summaryrefslogtreecommitdiff
path: root/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c')
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c787
1 files changed, 787 insertions, 0 deletions
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c
new file mode 100644
index 000000000..297dd6edf
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c
@@ -0,0 +1,787 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics Co. Ltd
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+void dmc_delay(UINT32);
+void mem_ctrl_init_done();
+
+#define Outp32(addr, data) (*(volatile UINT32 *)(addr) = (data))
+#define Inp32(addr) ((*(volatile UINT32 *)(addr)))
+
+#define CONFIG_DMC_CALIBRATION
+#define CONFIG_ODTOFF_GATELEVELINGON
+#define POP_TYPE 1
+#define PRO_PKGINFO 0
+
+void DMC_Delay(UINT32 x)
+{
+ dmc_delay(x);
+}
+
+void CMU_SetMemClk(UINT32 nMEMCLK)
+{
+ volatile UINT32 uBits;
+
+ // MEM Clock = 800 MHz
+
+ // MCLK_DPHY(0:8), MCLK_CDREX(0:4), BPLL(0:0)
+ uBits = (0 << 8) | (0 << 4) | (1 << 0);
+ Outp32(0x10030200, uBits); // rCLK_SRC_CDREX
+
+ // MCLK_DPHY = 800 / 1 = 800
+ // MCLK_CDREX = 800 / 1 = 800
+ // ACLK_CDREX = MCLK_CDREX / 2 = 400
+ // PCLK_CDREX = 800 / 1 / 6 = 133
+
+ // MCLK_CDREX2(1/1:28), ACLK_SFRTZASCP(1/2:24), MCLK_DPHY(1/1:20), MCLK_CDREX(1/1:16), PCLK_CDREX(1/6:4), ACLK_CDREX(1/2:0)
+ uBits = (0 << 28) | (1 << 24) | (0 << 20) | (0 << 16) | (5 << 4) | (1 << 0);
+ Outp32(0x10030500, uBits); // rCLK_DIV_CDREX
+
+ // MPLL(0:8)
+ uBits = (1 << 8);
+ Outp32(0x10014204, Inp32(0x10014204) & ~uBits); // rCLK_SRC_CORE1
+
+ // Setting MPLL [P,M,S]
+ //
+ uBits = (1 << 21) | (3 << 12) | (8 << 8);
+ Outp32(0x10014104, uBits); // rMPLL_CON1
+
+ // ENABLE(1), MDIV(200), PDIV(3), SDIV(0)
+ uBits = (1 << 31) | (200 << 16) | (3 << 8) | (0 << 0); // MPLL=1600MHz(3:200:0)
+ Outp32(0x10014100, uBits); // rMPLL_CON0
+
+ while ((Inp32(0x10014100) & (1 << 29)) == 0);
+
+ // MPLL(1:8)
+ uBits = (1 << 8);
+ Outp32(0x10014204, Inp32(0x10014204) | uBits); // rCLK_SRC_CORE1
+
+}
+
+void DMC_CaTraining(int ch)
+{
+ unsigned char code;
+ int find_vmw;
+ unsigned int phyBase;
+ unsigned int ioRdOffset;
+ unsigned int temp, mr41, mr48, vwml, vwmr, vwmc;
+ unsigned int lock;
+ unsigned int resp_mr41, resp_mr48;
+ UINT32 pkg_type = PRO_PKGINFO;
+
+
+ phyBase = 0x10c00000+(0x10000 * ch);
+ ioRdOffset = 0x150 + (0x4 * ch);
+
+ temp = Inp32( phyBase + 0x0000 );
+ temp |= (1 << 16);
+ Outp32( phyBase + 0x0000, temp );
+
+ temp = Inp32( phyBase + 0x0008 );
+ temp |= (1 << 23);
+ Outp32( phyBase + 0x0008, temp );
+
+ code = 0x8;
+ find_vmw = 0;
+ vwml = vwmr = vwmc = 0;
+
+ if (pkg_type == POP_TYPE) {
+ resp_mr41 = 0x5555;
+ resp_mr48 = 0x0101;
+ } else {
+ if ( ch == 0 ) {
+ resp_mr41 = 0x69C5;
+ resp_mr48 = 0x4040;
+ } else {
+ resp_mr41 = 0xD14E;
+ resp_mr48 = 0x8008;
+ }
+ }
+
+ while (1) {
+
+ //- code update
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFFFFFF00;
+ temp |= code;
+ Outp32( phyBase + 0x0028, temp );
+
+ //- resync
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFEFFFFFF;
+ Outp32( phyBase + 0x0028, temp );
+ temp |= 0x01000000;
+ Outp32( phyBase + 0x0028, temp );
+ temp &= 0xFEFFFFFF;
+ Outp32( phyBase + 0x0028, temp );
+
+ if(ch == 0) {
+ Outp32( 0x10DD0000+0x0010, 0x50690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x50690
+ //Outp32( 0x10DD0000+0x0010, 0x001050690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x50690
+ } else {
+ Outp32( 0x10DD0000+0x0010, 0x10050690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x10050690
+ //Outp32( 0x10DD0000+0x0010, 0x10150690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x10050690
+ }
+
+ Outp32( 0x10DD0000+0x0160, 0x3FF011 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=1
+ Outp32( 0x10DD0000+0x0164, 0x1 ); //- Set DMC.CACAL_CONFIG1.cacal_csn=1
+ DMC_Delay(0x100);
+
+ mr41 = Inp32( 0x10DD0000 + ioRdOffset );
+ mr41 &= 0xFFFF;
+
+ Outp32( 0x10DD0000+0x0160, 0x3FF010 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=0
+ DMC_Delay(0x100);
+
+ if( ch == 0 ) {
+ Outp32( 0x10DD0000+0x0010, 0x60300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x60300
+ //Outp32( 0x10DD0000+0x0010, 0x001060300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x60300
+ } else {
+ Outp32( 0x10DD0000+0x0010, 0x10060300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x10060300
+ //Outp32( 0x10DD0000+0x0010, 0x10160300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x10060300
+ }
+
+ Outp32( 0x10DD0000+0x0160, 0x3FF011 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=1
+ Outp32( 0x10DD0000+0x0164, 0x1 ); //- Set DMC.CACAL_CONFIG1.cacal_csn=1
+ DMC_Delay(0x100);
+
+ mr48 = Inp32( 0x10DD0000 + ioRdOffset );
+
+ if (pkg_type == POP_TYPE) {
+ mr48 &= 0x0303;
+ } else {
+ if ( ch == 0 ) {
+ mr48 &= 0xC060;
+ } else {
+ mr48 &= 0x8418;
+ }
+ }
+
+ Outp32( 0x10DD0000+0x0160, 0x3FF010 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=0
+ DMC_Delay(0x100);
+
+ if( (find_vmw == 0) && (mr41 == resp_mr41 ) && ( mr48 == resp_mr48 ) ) {
+ find_vmw = 0x1;
+ vwml = code;
+ }
+
+ if( (find_vmw == 1) && ( (mr41 != resp_mr41 ) || ( mr48 != resp_mr48 ) ) ) {
+ find_vmw = 0x3;
+ vwmr = code - 1;
+
+ if( ch == 0 ) {
+ Outp32( 0x10DD0000+0x0010, 0x50AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0
+ //Outp32( 0x10DD0000+0x0010, 0x001050AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0
+ } else {
+ Outp32( 0x10DD0000+0x0010, 0x10050AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0
+ //Outp32( 0x10DD0000+0x0010, 0x10150AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0
+ }
+ //DMC_Delay(0x10000);
+ break;
+ }
+
+ code++;
+
+ if(code == 255) {
+ while(1);
+ }
+ }
+
+ vwmc = (vwml + vwmr) / 2;
+
+#if 1
+ {
+ UINT32 lock_force;
+ UINT32 temp = 0;
+
+ lock_force = (Inp32( phyBase + 0x30 ) >> 8) & 0x7F;
+
+ temp = ((vwml & 0xFF) << 16) |
+ ((vwmr & 0xFF) << 8) |
+ ((vwmc & 0xFF));
+
+ if(ch == 0) {
+ Outp32(0x10040818, temp);
+ }
+ else {
+ Outp32(0x1004081C, temp);
+ }
+ }
+#endif
+
+ //- code update
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFFFFFF00;
+ temp |= vwmc;
+ Outp32( phyBase + 0x0028, temp );
+
+ //- resync
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFEFFFFFF;
+ Outp32( phyBase + 0x0028, temp );
+ temp |= 0x01000000;
+ Outp32( phyBase + 0x0028, temp );
+ temp &= 0xFEFFFFFF;
+ Outp32( phyBase + 0x0028, temp );
+
+ temp = Inp32( phyBase+0x0000 );
+ temp &= 0xFFFEFFFF;
+ Outp32( phyBase + 0x0000, temp );
+
+#if 1
+
+ //- vmwc convert to offsetd value.
+
+ lock = Inp32( phyBase + 0x0034 );
+ lock &= 0x1FF00;
+ lock >>= 8;
+
+ if( (lock & 0x3) == 0x3 ) {
+ lock++;
+ }
+
+ code = vwmc - (lock >> 2);
+
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFFFFFF00;
+ temp |= code;
+ Outp32( phyBase + 0x0028, temp );
+
+ temp = Inp32( phyBase + 0x0008 );
+ temp &= 0xFF7FFFFF;
+ Outp32( phyBase + 0x0008, temp );
+#endif
+}
+
+static void DMC_ZqInit(UINT8 dq, UINT8 ck, UINT8 cke, UINT8 cs, UINT8 ca)
+{
+ UINT32 temp;
+ UINT32 zqBase;
+ int ch;
+
+ for( ch = 0; ch < 2; ch++ ) {
+
+ zqBase = 0x10c00000 + ( 0x10000 * ch );
+
+ temp = Inp32( zqBase + 0x40 );
+ temp &= 0xF8FBFFF1;
+ temp |= ( ( dq & 0x7 ) << 24 );
+ temp |= ( ( 1 << 18 ) | ( 1 << 2 ) );
+
+ Outp32( zqBase + 0x40, temp );
+
+ temp |= (1 << 1);
+
+ Outp32( zqBase + 0x40, temp );
+
+ while( ( Inp32( zqBase + 0x48 ) & 0x5 ) != 0x1 );
+
+ temp = Inp32( zqBase + 0x40 );
+
+ temp &= ~( 1 << 18 );
+
+ Outp32( zqBase + 0x40, temp );
+
+ temp = ( ( ck & 0x7 ) << 9 ) | ( ( cke & 0x7 ) << 6 ) |
+ ( ( cs & 0x7 ) << 3 ) | ( ca & 0x7 );
+
+ Outp32( zqBase + 0xA0, temp );
+ }
+}
+
+void mem_ctrl_init_lpddr3(UINT32 nMEMCLK)
+{
+ UINT32 lock, temp;
+ UINT32 pkg_type = PRO_PKGINFO;
+
+ //-
+ //-PHASE 1 : PHY DLL Initialization
+ //-
+ //-2) Set the right value to PHY_CON0.ctrl_ddr_mode
+ Outp32( 0x10C00000+0x0000, 0x17021A40 ); //- PHY0.CON0[12:11].ctrl_ddr_mode=LPDDR3
+ Outp32( 0x10C10000+0x0000, 0x17021A40 ); //- PHY1.CON0[12:11].ctrl_ddr_mode=LPDDR3
+ //-3) Enable CA swap when POP is used
+ Outp32( 0x10C00000+0x0000, 0x17021A00 ); //- PHY0.CON0.ctrl_atgate=0x0
+ Outp32( 0x10C10000+0x0000, 0x17021A00 ); //- PHY1.CON0.ctrl_atgate=0x0
+
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10030A20, 0x80000000 ); //- LPDDR3PHY_CON3[31]=1.
+ Outp32( 0x10C00000+0x0064, 0x1 ); //- PHY0.CON24[0]=1
+ Outp32( 0x10C10000+0x0064, 0x1 ); //- PHY0.CON24[0]=1
+ } else {
+ Outp32( 0x10030A20, 0x00000000 ); //- LPDDR3PHY_CON3[31]=0.
+ Outp32( 0x10C00000+0x0064, 0x0 ); //- PHY0.CON24[0]=0
+ Outp32( 0x10C10000+0x0064, 0x0 ); //- PHY0.CON24[0]=0
+ }
+ //-4) Set PHY for DQS pull-down mode
+ Outp32( 0x10C00000+0x0038, 0x0F ); //- PHY0.CON14.ctrl_pulld_dq=0x0, ctrl_pulld_dqs=0x0F
+ Outp32( 0x10C10000+0x0038, 0x0F ); //- PHY1.CON14.ctrl_pulld_dq=0x0, ctrl_pulld_dqs=0x0F
+ //-5) Set PHY_CON42.ctrl_bstlen and PHY_CON42.ctrl_rdlat
+ Outp32( 0x10C00000+0x00ac, 0x80C ); //- PHY0.CON42.ctrl_bstlen[12:8]=0x8, ctrl_rdlat[4:0]=0x0C
+ Outp32( 0x10C10000+0x00ac, 0x80C ); //- PHY1.CON42.ctrl_bstlen[12:8]=0x8, ctrl_rdlat[4:0]=0x0C
+ Outp32( 0x10C00000+0x006C, 0x7107F ); //- PHY0.CON26.T_wrdata_en[20:16]=0x7
+ Outp32( 0x10C10000+0x006C, 0x7107F ); //- PHY1.CON26.T_wrdata_en[20:16]=0x7
+ Outp32( 0x10C00000+0x0000, 0x17021A00 ); //- Set PHY0.PHY_CON0.ctrl_read_disable=0x0
+ Outp32( 0x10C00000+0x0040, 0x8080304 ); //- Set PHY0.PHY_CON16.zq_term.
+ Outp32( 0x10C10000+0x0000, 0x17021A00 ); //- Set PHY1.PHY_CON0.ctrl_read_disable=0x0
+ Outp32( 0x10C10000+0x0040, 0x8080304 ); //- Set PHY1.PHY_CON16.zq_term.
+ Outp32( 0x10030B00, 0x1 ); //- Set 0x1003_0B00[0]=0x1
+ //-6) ZQ calibration
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10C00000+0x0040, 0xE0C0304 ); //- Set PHY0.CON16.zq_mode_dds=0x6000000
+ Outp32( 0x10C00000+0x0040, 0xE0C0304 ); //- Set PHY0.CON16.zq_manual_mode=1
+ Outp32( 0x10C00000+0x0040, 0xE0C0306 ); //- Set PHY0.CON16.zq_manual_str
+ while( ( Inp32( 0x10C00000+0x0048 ) & 0x1 ) != 0x1 ); //- Wait for PHY0.CON17.zq_done
+ Outp32( 0x10C00000+0x0040, 0xE080304 ); //- Set PHY0.CON16.zq_clk_en=0
+ Outp32( 0x10C10000+0x0040, 0xE0C0304 ); //- Set PHY1.CON16.zq_mode_dds=0x6000000
+ Outp32( 0x10C10000+0x0040, 0xE0C0304 ); //- Set PHY1.CON16.zq_manual_mode=1
+ Outp32( 0x10C10000+0x0040, 0xE0C0306 ); //- Set PHY1.CON16.zq_manual_str
+ while( ( Inp32( 0x10C10000+0x0048 ) & 0x1 ) != 0x1 ); //- Wait for PHY1.CON17.zq_done
+ Outp32( 0x10C10000+0x0040, 0xE080304 ); //- Set PHY1.CON16.zq_clk_en=0
+ Outp32( 0x10C00000+0x00A0, 0xDB6 ); //- PHY0.CON39[11:0]=0xDB6
+ Outp32( 0x10C10000+0x00A0, 0xDB6 ); //- PHY1.CON39[11:0]=0xDB6
+ } else {
+ DMC_ZqInit(0x4, 0x4, 0x4, 0x4, 0x4);
+ }
+
+ //-7) Set CONCONTROL. At this moment, assert the dfi_init_start field to high.
+ Outp32( 0x10DD0000+0x0000, 0xFFF2100 ); //- rdfetch=0x2
+ Outp32( 0x10DD0000+0x0000, 0x1FFF2100 ); //- assert dfi_init_start
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0000, 0xFFF2100 ); //- deassert dfi_init_start
+ //-
+ //-PHASE 2 : Setting Controller Register
+ //-
+ //-8) Set MEMCONTROL. At this moment, switch OFF all low power feature.
+ Outp32( 0x10DD0000+0x0004, 0x312700 ); //- memcontrol
+ //-9) Set the MEMBASECONFIG0 register.
+ //- If there are two external memory chips set the MEMBASECONFIG1 register.
+ Outp32( 0x10DD0000+0x010C, 0x4007C0 ); //- chipbase0=0x40, mask=0x7C0
+ Outp32( 0x10DD0000+0x0110, 0x8007C0 ); //- chipbase1=0x80, mask=0x7C0
+ Outp32( 0x10DD0000+0x0008, 0x1323 ); //- memconfig0
+ Outp32( 0x10DD0000+0x000C, 0x1323 ); //- memconfig1
+ //-10) Set the PRECHCONFIG register
+ Outp32( 0x10DD0000+0x0014, 0xFF000000 ); //- DMC.PRECHCONFIG[15:0]=(0x0|0x0)
+ //-11) Set the TIMINGAREF, TIMINGROW, TIMINGDATA, and TIMINGPOWER registers
+ //- according to memory AC parameters.
+ Outp32( 0x10DD0000+0x00F0, 0x7 ); //- iv_size=0x7
+ Outp32( 0x10DD0000+0x0030, 0x5D ); //- tREFI=0x5D
+ Outp32( 0x10DD0000+0x0034, 0x34498692 ); //- DMC.TIMINGROW=0x34498692
+ Outp32( 0x10DD0000+0x0038, 0x3630560C ); //- DMC.TIMINGDATA=0x3630560C
+ Outp32( 0x10DD0000+0x003C, 0x50380336 ); //- DMC.TIMINGPOWER=0x50380336
+ Outp32( 0x10DD0000+0x0004, 0x312700 ); //-
+ //-12) Set the QOSCONTROL0~15 and BRBQOSCONFIG register if Qos Scheme is required.
+ Outp32( 0x10DD0000+0x60, 0xFFF ); //- QOS#0.=0xFFF
+ Outp32( 0x10DD0000+0x68, 0xFFF ); //- QOS#1.=0xFFF
+ Outp32( 0x10DD0000+0x70, 0xFFF ); //- QOS#2.=0xFFF
+ Outp32( 0x10DD0000+0x78, 0xFFF ); //- QOS#3.=0xFFF
+ Outp32( 0x10DD0000+0x80, 0xFFF ); //- QOS#4.=0xFFF
+ Outp32( 0x10DD0000+0x88, 0xFFF ); //- QOS#5.=0xFFF
+ Outp32( 0x10DD0000+0x90, 0xFFF ); //- QOS#6.=0xFFF
+ Outp32( 0x10DD0000+0x98, 0xFFF ); //- QOS#7.=0xFFF
+ Outp32( 0x10DD0000+0xA0, 0xFFF ); //- QOS#8.=0xFFF
+ Outp32( 0x10DD0000+0xA8, 0xFFF ); //- QOS#9.=0xFFF
+ Outp32( 0x10DD0000+0xB0, 0xFFF ); //- QOS#10.=0xFFF
+ Outp32( 0x10DD0000+0xB8, 0xFFF ); //- QOS#11.=0xFFF
+ Outp32( 0x10DD0000+0xC0, 0xFFF ); //- QOS#12.=0xFFF
+ Outp32( 0x10DD0000+0xC8, 0xFFF ); //- QOS#13.=0xFFF
+ Outp32( 0x10DD0000+0xD0, 0xFFF ); //- QOS#14.=0xFFF
+ Outp32( 0x10DD0000+0xD8, 0x0 ); //- QOS#15.=0xFFF
+ //-13) Set the PHY_CON4.ctrl_offsetr0~3 and PHY_CON6.ctrl_offsetw0~3 to 0x7F.
+ Outp32( 0x10C00000+0x0010, 0x7F7F7F7F ); //- offsetr=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F
+ Outp32( 0x10C10000+0x0010, 0x7F7F7F7F ); //- offsetr=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F
+ Outp32( 0x10C00000+0x0018, 0x7F7F7F7F ); //- offsetw=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F
+ Outp32( 0x10C10000+0x0018, 0x7F7F7F7F ); //- offsetw=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F
+ //-14) Set the PHY_CON4.ctrl_offsetd value to 0x7F.
+ Outp32( 0x10C00000+0x0028, 0x7F ); //- offsetd=0x7F
+ Outp32( 0x10C10000+0x0028, 0x7F ); //- offsetd=0x7F
+ //-15)
+ //-16)
+ Outp32( 0x10C00000+0x0030, 0x10107F70 ); //- lock forcing=0x7F
+ Outp32( 0x10C10000+0x0030, 0x10107F70 ); //- lock forcing=0x7F
+ Outp32( 0x10C00000+0x0030, 0x10107F50 ); //- disable ctrl_dll_on
+ Outp32( 0x10C10000+0x0030, 0x10107F50 ); //- disable ctrl_dll_on
+ DMC_Delay(0x100); //- wait 1ms
+ //-18) Update the DLL information.
+ Outp32( 0x10DD0000+0x0018, 0x8 ); //- fp_resync=1
+ Outp32( 0x10DD0000+0x0018, 0x0 ); //- fp_resync=0
+ //-
+ //-PHASE 3 : Memory Initialization
+ //-
+ //-18)~26)
+ Outp32( 0x10DD0000+0x0010, 0x7000000 ); //- port:0x0, cs:0x0 nop command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x71C00 ); //- port:0x0, cs:0x0 mr63 command
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0010, 0x10BFC ); //- port:0x0, cs:0x0 mr10 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x50C ); //- port:0x0, cs:0x0 mr1 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x868 ); //- port:0x0, cs:0x0 mr2 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0xC04 ); //- port:0x0, cs:0x0 mr3 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x7100000 ); //- port:0x0, cs:0x1 nop command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x171C00 ); //- port:0x0, cs:0x1 mr63 command
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0010, 0x110BFC ); //- port:0x0, cs:0x1 mr10 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10050C ); //- port:0x0, cs:0x1 mr1 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x100868 ); //- port:0x0, cs:0x1 mr2 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x100C04 ); //- port:0x0, cs:0x1 mr3 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x17000000 ); //- port:0x1, cs:0x0 nop command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10071C00 ); //- port:0x1, cs:0x0 mr63 command
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0010, 0x10010BFC ); //- port:0x1, cs:0x0 mr10 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x1000050C ); //- port:0x1, cs:0x0 mr1 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10000868 ); //- port:0x1, cs:0x0 mr2 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10000C04 ); //- port:0x1, cs:0x0 mr3 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x17100000 ); //- port:0x1, cs:0x1 nop command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10171C00 ); //- port:0x1, cs:0x1 mr63 command
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0010, 0x10110BFC ); //- port:0x1, cs:0x1 mr10 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x1010050C ); //- port:0x1, cs:0x1 mr1 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10100868 ); //- port:0x1, cs:0x1 mr2 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10100C04 ); //- port:0x1, cs:0x1 mr3 command
+ DMC_Delay(0x100); //- wait 1ms
+ //-27) Return to the memory operating frequency.
+ CMU_SetMemClk(800);
+
+ //-28) Set the PHY_CON4.ctrl_offsetr0~3 and PHY_CON6.ctrl_offsetw0~3 to 0x8.
+ Outp32( 0x10C00000+0x0010, 0x8080808 ); //- offsetr=0:0x08, 1:0x08, 2:0x08, 3:0x08
+ Outp32( 0x10C10000+0x0010, 0x8080808 ); //- offsetr=0:0x08, 1:0x08, 2:0x08, 3:0x08
+ Outp32( 0x10C00000+0x0018, 0x8080808 ); //- offsetw=0:0x08, 1:0x08, 2:0x08, 3:0x08
+ Outp32( 0x10C10000+0x0018, 0x8080808 ); //- offsetw=0:0x08, 1:0x08, 2:0x08, 3:0x08
+ //-29) Set the PHY_CON4.ctrl_offsetd value to 0x8.
+ Outp32( 0x10C00000+0x0028, 0x8 ); //- offsetd=0x08
+ Outp32( 0x10C10000+0x0028, 0x8 ); //- offsetd=0x08
+ //-30)~34)
+ Outp32( 0x10C00000+0x0030, 0x10107F70 ); //- ctrl_dll_on[5] = 1
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10C00000+0x0030, 0x10107F30 ); //- ctrl_start[6] = 0
+ Outp32( 0x10C00000+0x0030, 0x10107F70 ); //- ctrl_start[6] = 1
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10C10000+0x0030, 0x10107F70 ); //- ctrl_dll_on[5] = 1
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10C10000+0x0030, 0x10107F30 ); //- ctrl_start[6] = 0
+ Outp32( 0x10C10000+0x0030, 0x10107F70 ); //- ctrl_start[6] = 1
+ DMC_Delay(0x100); //- wait 1ms
+ //-35)~36)
+ Outp32( 0x10DD0000+0x0000, 0x1FFF2100 ); //- assert dfi_init_start
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC ) != 0xC ); //- Wait for DMC.dfi_init_complete_ch0/1
+ Outp32( 0x10DD0000+0x0000, 0xFFF2100 ); //- deassert dfi_init_start
+ //-37) Update the DLL information.
+ Outp32( 0x10DD0000+0x0018, 0x8 ); //- fp_resync=1
+ Outp32( 0x10DD0000+0x0018, 0x0 ); //- fp_resync=0
+
+#if defined(CONFIG_DMC_CALIBRATION)
+ //-38) Do leveing and calibration
+ //-39) Perform these steps
+ //- - a. Update PHYCON12.ctrl_force with by using PHY_CON13.ctrl_lock_value[9:2]
+ lock = (Inp32(0x10c00034) >> 8) & 0xFF;
+ if((lock & 0x3) == 0x3) {
+ lock++;
+ }
+
+ temp = Inp32(0x10c00030) & 0xFFFF80FF;
+ temp |= ((lock >> 2) << 8);
+ Outp32( 0x10c00000 + 0x0030, temp);
+
+ lock = (Inp32(0x10c10034) >> 8) & 0xFF;
+ if((lock & 0x3) == 0x3) {
+ lock++;
+ }
+
+ temp = Inp32(0x10c10030) & 0xFFFF80FF;
+ temp |= ((lock >> 2) << 8);
+ Outp32( 0x10c10000 + 0x0030, temp);
+
+ //- - b. Enable PHY_CON0.ctrl_atgate
+ Outp32( 0x10C00000+0x0000, 0x17021A40 ); //- PHY0.CON0.ctrl_atgate=1.
+ Outp32( 0x10C10000+0x0000, 0x17021A40 ); //- PHY1.CON0.ctrl_atgate=1.
+ //- - d. Enable PHY_CON0.p0_cmd_en
+ Outp32( 0x10C00000+0x0000, 0x17025A40 ); //- PHY0.CON0.p0_cmd_en=1.
+ Outp32( 0x10C10000+0x0000, 0x17025A40 ); //- PHY1.CON0.p0_cmd_en=1.
+ //- - e. Enable PHY_CON2.InitDeskewEn
+ Outp32( 0x10C00000+0x0008, 0x10044 ); //- PHY0.CON2.InitDeskewEn=1.
+ Outp32( 0x10C10000+0x0008, 0x10044 ); //- PHY1.CON2.InitDeskewEn=1.
+ //- - f. Enable PHY_CON0.byte_rdlvl_en
+ Outp32( 0x10C00000+0x0000, 0x17027A40 ); //-
+ Outp32( 0x10C10000+0x0000, 0x17027A40 ); //-
+
+ //- - c. Disable PHY_CON12.ctrl_dll_on
+ temp = Inp32(0x10c00030) & 0xFFFFFFDF;
+ Outp32( 0x10c00030, temp );
+ temp = Inp32(0x10c10030) & 0xFFFFFFDF;
+ Outp32( 0x10c10030, temp );
+ DMC_Delay(0x100); //- wait 1ms
+
+ //-CA Training.
+ DMC_CaTraining(0);
+ DMC_CaTraining(1);
+
+ if (pkg_type == POP_TYPE) {
+ //-Read DQ Calibration.
+ Outp32( 0x10C00000+0x0004, 0x92F0001 ); //- Set PHY0.CON1.rdlvl_rddata_adj
+ Outp32( 0x10C10000+0x0004, 0x92F0001 ); //- Set PHY1.CON1.rdlvl_rddata_adj
+ Outp32( 0x10C00000+0x005C, 0x00000041 ); //- PHY0.CON22.lpddr2_addr=0x041
+ Outp32( 0x10C10000+0x005C, 0x00000041 ); //- PHY1.CON22.lpddr2_addr=0x041
+ Outp32( 0x10C00000+0x0008, 0x2010044 ); //- Set PHY0.CON2.rdlvl_en
+ Outp32( 0x10C10000+0x0008, 0x2010044 ); //- Set PHY1.CON2.rdlvl_en
+ Outp32( 0x10DD0000+0x00F8, 0x2 ); //- DMC.RDLVLCONFIG.ctrl_rdlvl_data_en=1
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC000 ) != 0xC000 ); //- Wait DMC.rdlvl_complete_ch0/1
+ Outp32( 0x10DD0000+0x00F8, 0x0 ); //- Set DMC.RDLVLCONFIG.ctrl_rdlvl_data_en=0
+
+ Outp32(0x10C00000 + 0x0014, 0xC);
+ while( Inp32(0x10C00000 + 0x0058) != 0);
+
+ Outp32(0x10C10000 + 0x0014, 0xC);
+ while( Inp32(0x10C00000 + 0x0058) != 0);
+
+ Outp32(0x10C00000 + 0x0014, 0x0);
+ Outp32(0x10C10000 + 0x0014, 0x0);
+
+ //-Write DQ Calibration.
+ while( ( Inp32( 0x10DD0000+0x0048 ) & 0x3 ) != 0x0 ); //- Wait for DMC.chip_busy_state CH0
+ while( ( Inp32( 0x10DD0000+0x004C ) & 0x3 ) != 0x0 ); //- Wait for DMC.chip_busy_state CH1
+ Outp32( 0x10DD0000+0x00F4, 0x1 ); //- DMC.WRTRACONFIG
+ Outp32( 0x10C00000+0x005C, 0x204 ); //-
+ Outp32( 0x10C10000+0x005C, 0x204 ); //-
+ Outp32( 0x10C00000+0x0004, 0x92F00FF ); //-Set "rdlvl_rddata_adj" to 0x0001 or 0x0100 in PHY_CON1[15:0]
+ Outp32( 0x10C10000+0x0004, 0x92F00FF ); //-Set "rdlvl_rddata_adj" to 0x0001 or 0x0100 in PHY_CON1[15:0]
+ Outp32( 0x10C00000+0x0008, 0x6010044 ); //-
+ Outp32( 0x10C10000+0x0008, 0x6010044 ); //-
+ Outp32( 0x10C00000+0x0008, 0xE010044 ); //-
+ Outp32( 0x10C10000+0x0008, 0xE010044 ); //-
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC000 ) != 0xC000 ); //- Wait DMC.rdlvl_complete_ch0/1
+ Outp32( 0x10C00000+0x0008, 0x6010044 ); //-
+ Outp32( 0x10C10000+0x0008, 0x6010044 ); //-
+
+ Outp32(0x10C00000 + 0x0014, 0xC);
+ while( Inp32(0x10C00000 + 0x0058) != 0);
+
+ Outp32(0x10C10000 + 0x0014, 0xC);
+ while( Inp32(0x10C10000 + 0x0058) != 0);
+
+ Outp32(0x10C00000 + 0x0014, 0x0);
+ Outp32(0x10C10000 + 0x0014, 0x0);
+ }
+
+ //-43) Enable PHY_CON12.ctrl_dll_on
+ temp = Inp32( 0x10c00030) | 0x20;
+ Outp32( 0x10c00030, temp );
+ //while( ( Inp32(0x10c00030) & 0x1 ) != 0x1 );
+
+ temp = Inp32( 0x10c10030) | 0x20;
+ Outp32( 0x10c10030, temp );
+ //while( ( Inp32(0x10c10030) & 0x1 ) != 0x1 );
+
+ //-44) Disable PHY_CON.ctrl_atgate when POP is used
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10C00000+0x0000, 0x17027A00 ); //- PHY0.CON0.ctrl_atgate=0x0
+ Outp32( 0x10C10000+0x0000, 0x17027A00 ); //- PHY1.CON0.ctrl_atgate=0x0
+ }
+ Outp32( 0x10C00000+0x0000, 0x17127A00 ); //- Set PHY0.CON0.ctrl_upd_range=0x1
+ Outp32( 0x10C10000+0x0000, 0x17127A00 ); //- Set PHY1.CON0.ctrl_upd_range=0x1
+
+ //-45) Enable PHY_CON2.DLLDeSkewEn
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10C00000+0x0008, 0x6011044 ); //- PHY0.CON2.DllDeskewEn=1.
+ Outp32( 0x10C10000+0x0008, 0x6011044 ); //- PHY1.CON2.DllDeskewEn=1.
+ } else {
+ Outp32( 0x10C00000+0x0008, 0x11044 ); //- PHY0.CON2.DllDeskewEn=1.
+ Outp32( 0x10C10000+0x0008, 0x11044 ); //- PHY1.CON2.DllDeskewEn=1.
+ }
+ //-46) Update the DLL information
+ Outp32( 0x10DD0000+0x0018, 0x8 ); //- fp_resync=1
+ Outp32( 0x10DD0000+0x0018, 0x0 ); //- fp_resync=0
+#endif
+
+ //-47) ODT is not supported in LPDDR2/LPDDR3
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10C00000+0x0000, 0x17127A00 ); //- Set PHY0.PHY_CON0.ctrl_read_disable=0x0
+ Outp32( 0x10C00000+0x0040, 0xE080304 ); //- Set PHY0.PHY_CON16.zq_term.
+ Outp32( 0x10C10000+0x0000, 0x17127A00 ); //- Set PHY1.PHY_CON0.ctrl_read_disable=0x0
+ Outp32( 0x10C10000+0x0040, 0xE080304 ); //- Set PHY1.PHY_CON16.zq_term.
+ }
+
+ //-48) Issue the PALL command to memory
+ Outp32( 0x10DD0000+0x0010, 0x1000000 ); //- send PALL to port=0x0, cs=0x0
+ Outp32( 0x10DD0000+0x0010, 0x1100000 ); //- send PALL to port=0x0, cs=0x1
+ Outp32( 0x10DD0000+0x0010, 0x11000000 ); //- send PALL to port=0x1, cs=0x0
+ Outp32( 0x10DD0000+0x0010, 0x11100000 ); //- send PALL to port=0x1, cs=0x1
+ //-49) Set the MEMCONTROL if power-down modes are required.
+ Outp32( 0x10DD0000+0x0004, 0x312700 ); //- DMC.MEMCONTROL.tp_en=0x0.
+ Outp32( 0x10DD0000+0x0014, 0xFF000000 ); //- DMC.PRECHCONFIG.tp_cnt=0xFF
+ Outp32( 0x10DD0000+0x0028, 0xFFFF00FF ); //- DMC.PWRDNCONFIG.dsref_cyc=0xFFFF0000
+ Outp32( 0x10DD0000+0x0004, 0x312720 ); //- Set DMC.MEMCONTROL.dsref_en=0x20.
+ Outp32( 0x10DD0000+0x0028, 0xFFFF00FF ); //- Set DMC.PWRDNCONFIG.dpwrdn_cyc=0xFF
+ Outp32( 0x10DD0000+0x0004, 0x312722 ); //- Set DMC.MEMCONTROL.dpwrdn_en=0x2., dpwrdn_type=0x0
+ Outp32( 0x10DD0000+0x0004, 0x312723 ); //- DMC.MEMCONTROL.clk_stop_en=0x1.
+ Outp32( 0x10DD0000+0x0000, 0xFFF2108 ); //- Set DMC.PHYCONTROL.io_pd_con=0x1.
+ //-50) Set the CONCONTROL to turn on an auto refresh counter.
+ Outp32( 0x10DD0000+0x0000, 0xFFF2128 ); //- aref enabled
+
+ mem_ctrl_init_done();
+
+}
+
+void mem_ctrl_init_ddr3(UINT32 nMEMCLK)
+{
+ UINT32 ap_odt, dram_odt;
+
+#if defined(CONFIG_ODTOFF_GATELEVELINGON)
+ ap_odt = 0xE2C0000;
+ dram_odt = 0x2;
+#else // ODT On and Gate Leveling Off
+ ap_odt = 0xE240000;
+ dram_odt = 0x42;
+#endif
+
+ CMU_SetMemClk(nMEMCLK);
+
+ DMC_Delay(0x10000); // wait 300ms
+ Outp32( 0x10030A10, 0x00000000 ); //- PHY_RESET[0]=0
+ DMC_Delay(100);
+ Outp32( 0x10030A10, 0x00000001 ); //- PHY_RESET[0]=1
+ DMC_Delay(100);
+ Outp32( 0x10C00000+0x00a0, 0x000006db ); //- dds of CA = 0x3
+ Outp32( 0x10C10000+0x00a0, 0x000006db ); //- dds of CA = 0x3
+ Outp32( 0x10C00000+0x00ac, 0x0000080b ); //- ctrl_bstlen[12:8]=8, ctrl_rdlat[4:0]=11
+ Outp32( 0x10C10000+0x00ac, 0x0000080b ); //- ctrl_bstlen[12:8]=8, ctrl_rdlat[4:0]=11
+ Outp32( 0x10C00000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_clk_div_en[18]=1
+ Outp32( 0x10C10000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_clk_div_en[18]=1
+ Outp32( 0x10C00000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_mode_noterm[19]=0
+ Outp32( 0x10C10000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_mode_noterm[19]=0
+ Outp32( 0x10C00000+0x0040, ap_odt|0x0306 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=1
+ Outp32( 0x10C10000+0x0040, ap_odt|0x0306 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=1
+ while( ( Inp32( 0x10C00000+0x0048 ) & 0x1 ) != 0x1 ); //- PHY0: wait for zq_done
+ while( ( Inp32( 0x10C10000+0x0048 ) & 0x1 ) != 0x1 ); //- PHY1: wait for zq_done
+ Outp32( 0x10C00000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0
+ Outp32( 0x10C10000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0
+ Outp32( 0x10C00000+0x0038, 0x0000000f ); //- ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf
+ Outp32( 0x10C10000+0x0038, 0x0000000f ); //- ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf
+ Outp32( 0x10DD0000+0x0000, 0x1FFF0000|(0x3<<12) ); //- dfi_init_start[28]=1, rd_fetch[14:12]=3
+ Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ Outp32( 0x10C00000+0x0010, 0x8080808 ); //- ctrl_offsetr
+ Outp32( 0x10C10000+0x0010, 0x8080808 ); //- ctrl_offsetr
+ Outp32( 0x10C00000+0x0018, 0x8080808 ); //- ctrl_offsetw
+ Outp32( 0x10C10000+0x0018, 0x8080808 ); //- ctrl_offsetw
+ Outp32( 0x10C00000+0x0028, 0x8 ); //- ctrl_offsetd[7:0]=0x8
+ Outp32( 0x10C10000+0x0028, 0x8 ); //- ctrl_offsetd[7:0]=0x8
+ Outp32( 0x10C00000+0x0030, 0x10100030 ); //- ctrl_force[14:8]=0x0, ctrl_start[6]=0, ctrl_dll_on[5]=1
+ Outp32( 0x10C10000+0x0030, 0x10100030 ); //- ctrl_force[14:8]=0x0, ctrl_start[6]=0, ctrl_dll_on[5]=1
+ DMC_Delay(100);
+ Outp32( 0x10C00000+0x0030, 0x10100070 ); //- ctrl_dll_start[6]=1
+ Outp32( 0x10C10000+0x0030, 0x10100070 ); //- ctrl_dll_start[6]=1
+ DMC_Delay(100);
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC ) != 0xC ); //- wait dfi_init_complete
+ Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ Outp32( 0x10DD0000+0x0000, 0x0FFF0000|(0x3<<12) ); //- dfi_init_start[28]=0, rd_fetch[14:12]=3
+ Outp32( 0x10DD0000+0x00F0, 0x7 ); //- channel interleaving
+ Outp32( 0x10DD0000+0x0008, 0x00001333 ); //- bank interleaving
+ Outp32( 0x10DD0000+0x000C, 0x00001333 ); //- bank interleaving
+ Outp32( 0x10DD0000+0x010C, 0x00400780 ); //- chip_base[26:16]=40, chip_mask[10:0]=780
+ Outp32( 0x10DD0000+0x0110, 0x00800780 ); //- chip_base[26:16]=80, chip_mask[10:0]=780
+ Outp32( 0x10DD0000+0x0014, 0xFF000000 ); //- precharge policy counter
+ Outp32( 0x10DD0000+0x0028, 0xFFFF00FF ); //- low power counter
+ Outp32( 0x10DD0000+0x0030, 0x000000bb ); //- refresh counter
+ Outp32( 0x10DD0000+0x0034, 0x8C36650E ); //- timing row
+ Outp32( 0x10DD0000+0x0038, 0x3630580B ); //- timing data
+ Outp32( 0x10DD0000+0x003C, 0x41000A44 ); //- timing power
+ // Set the QOSCONTROL0~15 and BRBQOSCONFIG register if Qos Scheme is required.
+ Outp32( 0x10DD0000+0x60, 0xFFF ); //- QOS#0.=0xFFF
+ Outp32( 0x10DD0000+0x68, 0xFFF ); //- QOS#1.=0xFFF
+ Outp32( 0x10DD0000+0x70, 0xFFF ); //- QOS#2.=0xFFF
+ Outp32( 0x10DD0000+0x78, 0xFFF ); //- QOS#3.=0xFFF
+ Outp32( 0x10DD0000+0x80, 0xFFF ); //- QOS#4.=0xFFF
+ Outp32( 0x10DD0000+0x88, 0xFFF ); //- QOS#5.=0xFFF
+ Outp32( 0x10DD0000+0x90, 0xFFF ); //- QOS#6.=0xFFF
+ Outp32( 0x10DD0000+0x98, 0xFFF ); //- QOS#7.=0xFFF
+ Outp32( 0x10DD0000+0xA0, 0xFFF ); //- QOS#8.=0xFFF
+ Outp32( 0x10DD0000+0xA8, 0xFFF ); //- QOS#9.=0xFFF
+ Outp32( 0x10DD0000+0xB0, 0xFFF ); //- QOS#10.=0xFFF
+ Outp32( 0x10DD0000+0xB8, 0xFFF ); //- QOS#11.=0xFFF
+ Outp32( 0x10DD0000+0xC0, 0xFFF ); //- QOS#12.=0xFFF
+ Outp32( 0x10DD0000+0xC8, 0xFFF ); //- QOS#13.=0xFFF
+ Outp32( 0x10DD0000+0xD0, 0xFFF ); //- QOS#14.=0xFFF
+ Outp32( 0x10DD0000+0xD8, 0x0 ); //- QOS#15.=0xFFF
+ Outp32( 0x10DD0000+0x0010, 0x01000000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x01100000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x11000000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x11100000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x07000000 );
+ Outp32( 0x10DD0000+0x0010, 0x00020000|0x18 );
+ Outp32( 0x10DD0000+0x0010, 0x00030000 );
+ Outp32( 0x10DD0000+0x0010, 0x00010000|dram_odt );
+ Outp32( 0x10DD0000+0x0010, 0x00000000|0xD70 );
+ Outp32( 0x10DD0000+0x0010, 0x0a000000 ); //- ZQInit
+ Outp32( 0x10DD0000+0x0010, 0x17000000 );
+ Outp32( 0x10DD0000+0x0010, 0x10020000|0x18 );
+ Outp32( 0x10DD0000+0x0010, 0x10030000 );
+ Outp32( 0x10DD0000+0x0010, 0x10010000|dram_odt );
+ Outp32( 0x10DD0000+0x0010, 0x10000000|0xD70 );
+ Outp32( 0x10DD0000+0x0010, 0x1a000000 ); //- ZQInit
+
+#if defined(CONFIG_ODTOFF_GATELEVELINGON)
+ Outp32( 0x10C00000+0x0000, 386009664 ); // ctrl_atgate=1
+ Outp32( 0x10C10000+0x0000, 386009664 ); // ctrl_atgate=1
+ Outp32( 0x10C00000+0x0000, 386026048 ); // p0_cmd_en=1
+ Outp32( 0x10C10000+0x0000, 386026048 ); // p0_cmd_en=1
+ Outp32( 0x10C00000+0x0008, 65604 ); // InitDeskewEn=1
+ Outp32( 0x10C10000+0x0008, 65604 ); // InitDeskewEn=1
+ Outp32( 0x10C00000+0x0000, 386034240 ); // byte_rdlvl_en=1
+ Outp32( 0x10C10000+0x0000, 386034240 ); // byte_rdlvl_en=1
+ Outp32( 0x10C00000+0x0030, 0x10100050+0x1900 ); //- ctrl_force[14:8], ctrl_dll_on[5]=0
+ Outp32( 0x10C10000+0x0030, 0x10100050+0x1900 ); //- ctrl_force[14:8], ctrl_dll_on[5]=0
+ Outp32( 0x10C00000+0x0008, 16842820 ); // rdlvl_gate_en=1
+ Outp32( 0x10C10000+0x0008, 16842820 ); // rdlvl_gate_en=1
+ Outp32( 0x10C00000+0x0000, 386034496 ); // ctrl_shgate=1
+ Outp32( 0x10C10000+0x0000, 386034496 ); // ctrl_shgate=1
+ Outp32( 0x10C00000+0x0004, 0x9010100 ); // ctrl_gateduradj=0
+ Outp32( 0x10C10000+0x0004, 0x9010100 ); // ctrl_gateduradj=0
+ Outp32( 0x10DD0000+0x00f8, 0x00000001 ); //- ctrl_rdlvl_data_en[1]=1
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC000 ) != 0xC000 ); //- Rdlvl_complete_ch1[15]=1, Rdlvl_complete_ch0[14]=1
+ Outp32( 0x10DD0000+0x00f8, 0x00000000 ); //- ctrl_rdlvl_data_en[1]=0
+ Outp32( 0x10C00000+0x0038, 0x00000000 ); //- ctrl_pulld_dq[11:8]=0x0, ctrl_pulld_dqs[3:0]=0x0
+ Outp32( 0x10C10000+0x0038, 0x00000000 ); //- ctrl_pulld_dq[11:8]=0x0, ctrl_pulld_dqs[3:0]=0x0
+ Outp32( 0x10C00000+0x0030, 0x10100070+0x1900 ); //- ctrl_force[14:8], ctrl_start[6]=1, ctrl_dll_on[5]=1
+ Outp32( 0x10C10000+0x0030, 0x10100070+0x1900 ); //- ctrl_force[14:8], ctrl_start[6]=1, ctrl_dll_on[5]=1
+ DMC_Delay(100);
+ Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- ctrl_shgate[29]=1, fp_resync[3]=1
+ Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- ctrl_shgate[29]=1, fp_resync[3]=0
+ Outp32( 0x10DD0000+0x0010, 0x01000000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x01100000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x11000000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x11100000 ); //- Issue PALL
+#endif
+ Outp32( 0x10DD0000+0x0004, 0x00302620 ); //- bl[22:20]=8, mem_type[11:8]=7, dsref_en[5]=1, dpwrdn_en[1]=1, clk_stop_en[0]=1
+ Outp32( 0x10DD0000+0x0000, 0x0FFF0020|(0x3<<12) ); //- dfi_init_start[28]=1, rd_fetch[14:12]=3, aref_en[5]=1
+
+ mem_ctrl_init_done();
+}