[processor-sdk/performance-audio-sr.git] / pdk_k2g_1_0_1 / packages / ti / platform / evmk2g / platform_lib / src / evm66x_sodimm.c
diff --git a/pdk_k2g_1_0_1/packages/ti/platform/evmk2g/platform_lib/src/evm66x_sodimm.c b/pdk_k2g_1_0_1/packages/ti/platform/evmk2g/platform_lib/src/evm66x_sodimm.c
--- /dev/null
@@ -0,0 +1,564 @@
+/******************************************************************************
+ * Copyright (c) 2013-2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * File Name: evm66x_sodimm.c
+ *
+ * Description: This contains functions for read spd value from spd eeprom and
+ * Configure ddr3 register.
+ *
+ *
+ ******************************************************************************/
+
+#include "platform_internal.h"
+
+ddr3_phy_config phyA_cfg;
+ddr3_emif_config emifA_cfg;
+void init_ddrphy(uint32_t base, ddr3_phy_config *phy_cfg, uint8_t eccEnable);
+void init_ddremif(uint32_t base, ddr3_emif_config *emif_cfg);
+
+enum EBANK
+{
+ DCE0,
+ DCE0_DEC1
+};
+enum NM
+{
+ DDR3busWidth_64,
+ DDR3busWidth_32,
+ DDR3busWidth_16
+};
+enum SRT
+{
+ NORMAL_TEMP,
+ EXTENDED_TEMP
+};
+
+enum Out_Impedance
+{
+ RZQ_6_IMP=0,
+ RZQ_7_IMP
+};
+enum Die_Term
+{
+ ODT_DISABLE=0,
+ RZQ_4_TERM,
+ RZQ_2_TERM,
+ RZQ_6_TERM,
+ RZQ_12_TERM,
+ RZQ_8_TERM
+};
+#define TEMP NORMAL_TEMP
+struct ddr3_sodiim
+{
+ float tCK;
+ uint32_t FREQSEL;
+ uint32_t tXP;
+ uint32_t tCKE;
+ uint32_t tPLLPD;
+ uint32_t tPLLGS;
+ uint32_t tPHYRST;
+ uint32_t tPLLLOCK;
+ uint32_t tPLLRST;
+ uint32_t tRFC;
+ uint32_t tXS;
+ uint32_t tDINIT0;
+ uint32_t tDINIT1;
+ uint32_t tDINIT2;
+ uint32_t tDINIT3;
+ uint32_t tRTP;
+ uint32_t tWTR;
+ uint32_t tRP;
+ uint32_t tRCD;
+ uint32_t tRAS;
+ uint32_t tRRD;
+ uint32_t tRC;
+ uint32_t tFAW;
+ uint32_t tMRD;
+ uint32_t tMOD;
+ uint32_t tWLO;
+ uint32_t tWLMRD;
+ uint32_t tXSDLL;
+ uint32_t tXPDLL;
+ uint32_t tCKESR;
+ uint32_t tDLLK;
+ uint32_t tWR;
+ uint32_t tWR_bin;
+ uint32_t CAS;
+ uint32_t CWL;
+ uint32_t ASR;
+ uint32_t PASR;
+ float tREFPRD;
+ uint8_t SDRAM_TYPE;
+ uint8_t IBANK;
+ uint8_t PAGESIZE;
+ uint8_t T_RRD;
+ uint8_t T_RAS_MAX;
+ uint8_t tZQCS;
+ uint32_t REFRESH_RATE;
+ uint8_t T_CSTA;
+}SPD;
+
+/******************************************************************************
+ *
+ * Function: cas_latancy
+ *
+ * Description: Find cas latency
+ *
+ * Parameters: uint16_t temp - SPD value(byte 15 and byte 14)
+ *
+ *
+ *
+ * Return Value: cas_bin
+ *
+ ******************************************************************************/
+unsigned char cas_latancy(uint16_t temp)
+{
+
+ uint8_t loop = 0;
+ uint8_t latancybitpos=0;
+ uint8_t CAS=0,cas_bin;
+
+ for(loop=0;loop<16;loop++)
+ {
+
+ if(temp & 0x0001)
+ {
+ latancybitpos=loop;
+ if((loop*2) > 15 )
+ {
+ cas_bin=(loop*2) - 15;
+ }
+ else
+ cas_bin=loop*2;
+ }
+ temp = temp >> 1;
+
+ }
+ CAS=latancybitpos+4;
+ printf("%d\n",CAS);
+
+ return cas_bin;
+}
+/******************************************************************************
+ *
+ * Function: ddrTimingCalculation
+ *
+ * Description: ddr timing calculation
+ *
+ * Parameters: uint8_t buf[] - Have SPD value
+ *
+ *
+ *
+ ******************************************************************************/
+void ddrTimingCalculation(uint8_t buf[])
+{
+
+ uint8_t Dividend,Divisor;
+ uint16_t ddrClock;
+ float vbus_clkPeriod,MTB,CLOCK_FREQ;
+
+ vbus_clkPeriod = 1.88;
+ Dividend = buf[10];
+ Divisor = buf[11];
+ MTB = (float)Dividend/Divisor;
+
+ SPD.tCK = buf[12]*MTB;
+ ddrClock = ((1/SPD.tCK)*1000)*2;
+ CLOCK_FREQ = ddrClock/2;
+ SPD.tPLLGS = (4/vbus_clkPeriod)*1000;
+ SPD.tPLLPD = (1/vbus_clkPeriod)*1000;
+ SPD.tPHYRST = 0xF;
+ if(buf[2] == 0x0b)
+ {
+ SPD.SDRAM_TYPE=0x03;
+ }
+ if(((buf[4] & 0x70) >>4) == 0x00)
+ {
+ SPD.IBANK=0x03; //Eight bank SDRAM devices
+ }
+
+ if(((buf[5] & 0x07)+9) == 0x08)
+ {
+ SPD.PAGESIZE = 0x00; //256 words (requires 8 column address bits)
+
+ }
+ else if(((buf[5] & 0x07)+9) == 0x09)
+ {
+ SPD.PAGESIZE = 0x01; //512 words (requires 9 column address bits)
+
+ }
+ else if(((buf[5] & 0x07)+9) == 0x0A)
+ {
+ SPD.PAGESIZE = 0x02; //1024 words (requires 10 column address bits)
+
+ }
+ else if(((buf[5] & 0x07)+9) == 0x0B)
+ {
+ SPD.PAGESIZE = 0x03; //2048 words (requires 11 column address bits)
+
+ }
+ if(((int)CLOCK_FREQ/2) >=166 && ((int)CLOCK_FREQ/2 < 275))
+ SPD.FREQSEL=0x03;
+ else if(((int)CLOCK_FREQ/2) >225 && ((int)CLOCK_FREQ/2 < 385))
+ SPD.FREQSEL=0x01;
+ else if(((int)CLOCK_FREQ/2) >335 && ((int)CLOCK_FREQ/2 < 534))
+ SPD.FREQSEL=0x00;
+
+
+ if(ddrClock == 800)
+ {
+
+
+ SPD.tZQCS=0x40;
+
+ if((int)(3*SPD.tCK) > (int)7.5)
+ SPD.tXP=(3*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tXP=(7.5/SPD.tCK)+0.5;
+
+ if((int)(3*SPD.tCK) > (int)7.5)
+ SPD.tCKE=(3*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tCKE=(7.5/SPD.tCK)+0.5;
+
+ }
+ else if (ddrClock == 1066)
+ {
+ SPD.tZQCS=0x40;
+
+ if((int)(3*SPD.tCK) > (int)7.5)
+ SPD.tXP=(3*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tXP=(7.5/SPD.tCK)+0.5;
+
+ if((int)(3*SPD.tCK) > (int)5.625)
+ SPD.tCKE=(3*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tCKE=(5.625/SPD.tCK)+0.5;
+
+ }
+ else if(ddrClock == 1333)
+ {
+ SPD.tZQCS=0x40;
+
+ if((int)(3*SPD.tCK) > 6)
+ SPD.tXP=(3*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tXP=6/SPD.tCK;
+
+ if((int)(3*SPD.tCK) > (int)5.625)
+ SPD.tCKE=(3*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tCKE=(5.625/SPD.tCK)+0.5;
+
+ }
+ else if (ddrClock == 1600)
+ {
+ SPD.tZQCS=0x40;
+
+ if((int)(3*SPD.tCK) > 6)
+ SPD.tXP=(3*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tXP=6/SPD.tCK;
+
+ if((int)(3*SPD.tCK) > 5)
+ SPD.tCKE=(3*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tCKE=(5/SPD.tCK)+0.5;
+
+ }
+ SPD.tPLLLOCK = (100/vbus_clkPeriod)*1000;
+ SPD.tPLLRST = (9/vbus_clkPeriod)*1000;
+ SPD.tRFC = (buf[24] | (buf[25] << 8))/Divisor;
+ SPD.tXS = ((SPD.tRFC+10)/SPD.tCK)+0.5;
+ SPD.tRFC = (SPD.tRFC/SPD.tCK) + 0.5;
+ SPD.tDINIT0 = (500/SPD.tCK)*1000;
+ SPD.tDINIT1 = SPD.tXS;
+ SPD.tDINIT2 = (200/SPD.tCK)*1000;
+ SPD.tDINIT3 = (1/SPD.tCK)*1000;
+ SPD.tRTP = ((float)buf[27]/Divisor)/SPD.tCK;
+ SPD.tWTR = ((float)buf[26]/Divisor)/SPD.tCK;
+ SPD.tRP = (((float)buf[20]/Divisor)/SPD.tCK)+0.5;
+ SPD.tRCD = (((float)buf[18]/Divisor)/SPD.tCK)+0.5;
+ SPD.tRAS = (buf[21] & 0x0f) << 8;
+ SPD.tRAS |= buf[22];
+ SPD.tRAS = ((float)SPD.tRAS/Divisor)/SPD.tCK;
+ SPD.tRRD = ((float)buf[19]/Divisor)/SPD.tCK;
+ SPD.tRC = (buf[21] & 0xf0) << 4;
+ SPD.tRC |= buf[23];
+ SPD.tRC = ((float)SPD.tRC/Divisor)/SPD.tCK;
+ SPD.tFAW = (((buf[28] << 8) | buf[29])/Divisor)/SPD.tCK;
+
+ SPD.T_RRD = ((((buf[28] << 8) | buf[29])/Divisor)/(4*SPD.tCK))-1;
+ SPD.tMRD=0x00;
+ SPD.tMOD=0x00;
+ SPD.tWLO=0x04;
+ SPD.tWLMRD=0x28;
+ SPD.tXSDLL=0x200;
+ SPD.T_RAS_MAX=0x0F;
+ SPD.T_CSTA=0x05;
+
+ if((int)(10*SPD.tCK) > 24)
+ SPD.tXPDLL=(10*SPD.tCK)/SPD.tCK;
+ else
+ SPD.tXPDLL=24/SPD.tCK;
+
+ SPD.tCKESR = SPD.tCKE + 1;
+ SPD.tDLLK=0x200;
+
+ SPD.CAS = cas_latancy(((buf[15] << 8) | buf[14]));
+ SPD.tWR = (buf[17]/Divisor)/SPD.tCK;
+ SPD.tWR_bin = (SPD.tWR/2) & 0x07;
+
+ if((SPD.tCK*10) >= (2.5*10))
+ SPD.CWL=0;
+ else if (((SPD.tCK*10) < (2.5*10)) && ((SPD.tCK*10) >= (1.875*10)))
+ SPD.CWL=1;
+ else if (((SPD.tCK*10) < (1.875*10)) && ((SPD.tCK*10) >= (1.5*10)))
+ SPD.CWL=2;
+ else if (((SPD.tCK*10) < (1.5*10)) && ((SPD.tCK*10) >= (1.25*10)))
+ SPD.CWL=3;
+ else if (((SPD.tCK*10) < (1.25*10)) && ((SPD.tCK*10) >= (1.071*10)))
+ SPD.CWL=4;
+ else if (((SPD.tCK*10) < (1.071*10)) && ((SPD.tCK*10) >= (0.938*10)))
+ SPD.CWL=5;
+ SPD.ASR = (buf[31] & 0x04) >> 2;
+ SPD.PASR = (buf[31] & 0x80) >> 7;
+ if(TEMP == NORMAL_TEMP)
+ {
+ SPD.tREFPRD = 64000.00/8192 ;
+ SPD.tREFPRD = (SPD.tREFPRD *1000)/SPD.tCK;
+ SPD.REFRESH_RATE = SPD.tREFPRD;
+ SPD.tREFPRD = SPD.tREFPRD * 5;
+ }
+ else if (TEMP == EXTENDED_TEMP)
+ {
+ SPD.tREFPRD = 32000.00/8192;
+ SPD.tREFPRD = (SPD.tREFPRD *1000)/SPD.tCK;
+ SPD.REFRESH_RATE = SPD.tREFPRD;
+ SPD.tREFPRD = SPD.tREFPRD * 5;
+ }
+}
+
+/******************************************************************************
+ *
+ * Function: crc16
+ *
+ * Description: crc16 algorithm for ddr
+ *
+ * Parameters: uint8_t *ptr - Point to base address of SPD array
+ * int count - Offset
+ *
+ *
+ * Return Value: crc
+ *
+ ******************************************************************************/
+static int crc16(uint8_t *ptr, int count)
+{
+ int crc, i;
+
+ crc = 0;
+ while (--count >= 0) {
+ crc = crc ^ (int)*ptr++ << 8;
+ for (i = 0; i < 8; ++i)
+ if (crc & 0x8000)
+ crc = crc << 1 ^ 0x1021;
+ else
+ crc = crc << 1;
+ }
+ return crc & 0xffff;
+}
+
+/******************************************************************************
+ *
+ * Function: ddr3_spd_check
+ *
+ * Description: Check CRC
+ *
+ * Parameters: uint8_t spd[] - have SPD value
+ *
+ *
+ * Return Value: Platform_EOK - status
+ *
+ ******************************************************************************/
+int32_t ddr3_spd_check(uint8_t spd[])
+{
+
+ int csum16;
+ int len;
+ unsigned char crc_lsb; /* byte 126 */
+ unsigned char crc_msb; /* byte 127 */
+
+ /*
+ * SPD byte0[7] - CRC coverage
+ * 0 = CRC covers bytes 0~125
+ * 1 = CRC covers bytes 0~116
+ */
+
+ len = !(spd[0] & 0x80) ? 126 : 117;
+ csum16 = crc16(spd, len);
+
+ crc_lsb = (unsigned char)(csum16 & 0x00ff);
+ crc_msb = (unsigned char)(csum16 >> 8);
+ if ((spd[126] == crc_lsb) && (spd[127] == crc_msb))
+ {
+ printf("SPD checksum verified.. Ok\n");
+ return Platform_EOK;
+ }
+ else
+ {
+ printf("SPD checksum unexpected.\n"
+ "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
+ "Checksum msb in SPD = %02X, computed SPD = %02X\n",
+ spd[126], crc_lsb, spd[127], crc_msb);
+ return ( (Platform_STATUS) Platform_EFAIL);
+ }
+}
+
+/******************************************************************************
+ *
+ * Function: readSPD
+ *
+ * Description: Read fixed number of bytes from SPD EEPROM
+ *
+ * Parameters: uint8_t uchEepromI2cAddress - i2c address of SPD EEPROM
+ * uint8_t buf[] - base address of buf,store data into buf
+ * uint8_t i2cportnumber - The i2c port number
+ *
+ *
+ * Return Value: Platform_EOK - status
+ *
+ ******************************************************************************/
+int32_t readSPD(uint8_t uchEepromI2cAddress,uint8_t buf[],uint8_t i2cportnumber)
+{
+
+ evmI2CInit(i2cportnumber);
+ if (i2cEepromRead (0x00, 256, (uint8_t *)buf,uchEepromI2cAddress,i2cportnumber) != I2C_RET_OK) {
+ platform_write("platform_spd_eeprom_read: EEPROM read failed\n");
+ return ( (Platform_STATUS) Platform_EFAIL);
+ }
+ if (ddr3_spd_check(buf) != Platform_EOK) {
+ printf("DIMM failed checksum:");
+ return ( (Platform_STATUS) Platform_EFAIL);
+ }
+ return ( (Platform_STATUS) Platform_EOK);
+}
+/******************************************************************************
+ *
+ * Function: init_ddr3param
+ *
+ * Description: Calculate ddr3 timing and configure ddr register
+ *
+ * Parameters: uint8_t buf[] - have spd value
+ *
+ *
+ * Return Value: Platform_EOK - status
+ *
+ ******************************************************************************/
+int32_t init_ddr3param(uint8_t buf[])
+{
+ int32_t status = CSL_SOK;
+ char dimm_name[32]={0};
+ strncpy(dimm_name, (char *)&buf[0x80], 18);
+ dimm_name[18] = '\0';
+ printf("dimm_name=%s\n",dimm_name);
+ ddrTimingCalculation(buf);
+
+ phyA_cfg.pllcr = CSL_FMKR(19,18,SPD.FREQSEL) | CSL_FMKR(16,13,0xE);
+ phyA_cfg.pgcr1_mask = (IODDRM_MASK | ZCKSEL_MASK | ZCKSEL_MASK);
+ phyA_cfg.pgcr1_val = ((1 << 2) | (1 << 7) | (1 << 23));
+ phyA_cfg.ptr0 = CSL_FMKR(31,21,SPD.tPLLPD) | CSL_FMKR(20,6,SPD.tPLLGS)| CSL_FMKR(5,0,SPD.tPHYRST);
+ phyA_cfg.ptr1 = CSL_FMKR(31,16,SPD.tPLLLOCK) | CSL_FMKR(12,0,SPD.tPLLRST);
+ phyA_cfg.ptr2 = CSL_FMKR(31,16,0) | CSL_FMKR(15,0,0);
+ phyA_cfg.ptr3 = CSL_FMKR(28,20,SPD.tDINIT1) | CSL_FMKR(19,0,SPD.tDINIT0);
+ phyA_cfg.ptr4 = CSL_FMKR(27,18,SPD.tDINIT3) | CSL_FMKR(17,0,SPD.tDINIT2);
+ phyA_cfg.dcr_mask = (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK);
+ phyA_cfg.dcr_val = ((1 << 10) | (1 << 27));
+ phyA_cfg.dtpr0 = CSL_FMKR(31,26,SPD.tRFC) | CSL_FMKR(25,22,SPD.tRRD) | CSL_FMKR(21,16,SPD.tRAS) | CSL_FMKR(15,12,SPD.tRCD) | CSL_FMKR(11,8,SPD.tRP) | CSL_FMKR(7,4,SPD.tWTR) | CSL_FMKR(3,0,SPD.tRTP);
+ phyA_cfg.dtpr1 = CSL_FMKR(29,26,SPD.tWLO) | CSL_FMKR(25,20,SPD.tWLMRD) | CSL_FMKR(19,11,SPD.tRFC) | CSL_FMKR(10,5,SPD.tFAW) | CSL_FMKR(4,2,SPD.tMOD) | CSL_FMKR(1,0,SPD.tMRD);
+ if((SPD.tXS > SPD.tXSDLL) && (SPD.tXP > SPD.tXPDLL))
+ {
+ phyA_cfg.dtpr2 = CSL_FMKR(31,31,0) | CSL_FMKR(30,30,1) | CSL_FMKR(29,29,0) |CSL_FMKR(28,19,SPD.tDLLK) | CSL_FMKR(18,15,SPD.tCKESR) | CSL_FMKR(14,10,SPD.tXP) | CSL_FMKR(9,0,SPD.tXS);
+ }
+ else
+ {
+
+ phyA_cfg.dtpr2 = CSL_FMKR(31,31,0) | CSL_FMKR(30,30,1) | CSL_FMKR(29,29,0) | CSL_FMKR(28,19,SPD.tDLLK) | CSL_FMKR(18,15,SPD.tCKESR) | CSL_FMKR(14,10,SPD.tXPDLL) | CSL_FMKR(9,0,SPD.tXSDLL);
+ }
+
+ phyA_cfg.mr0 = CSL_FMKR(12,12,1) | CSL_FMKR(11,9,SPD.tWR_bin) | CSL_FMKR(8,8,0) | CSL_FMKR(7,7,0) | CSL_FMKR(6,4,((SPD.CAS & 0x0E) >> 1)) | CSL_FMKR(3,3,0) | CSL_FMKR(2,2,(SPD.CAS &0x01)) ;
+
+ phyA_cfg.mr1 = CSL_FMKR(12,12,0) | CSL_FMKR(11,11,0) | CSL_FMKR(7,7,0) | CSL_FMKR(4,3,0) | CSL_FMKR(9,9,(RZQ_4_TERM & 0x04)) | CSL_FMKR(6,6,(RZQ_4_TERM & 0x02))
+ | CSL_FMKR(2,2,(RZQ_4_TERM & 0x01)) | CSL_FMKR(5,5,(RZQ_7_IMP & 0x02)) | CSL_FMKR(1,1,(RZQ_7_IMP & 0x01))
+ | CSL_FMKR(0,0,0);
+ phyA_cfg.mr2 = CSL_FMKR(10,9,ODT_DISABLE) | CSL_FMKR(7,7,NORMAL_TEMP) | CSL_FMKR(6,6,SPD.ASR) | CSL_FMKR(5,3,SPD.CWL)| CSL_FMKR(2,0,SPD.PASR);
+
+ phyA_cfg.dtcr = 0x710035C7;
+ phyA_cfg.pgcr2 = CSL_FMKR(27,20,0xF) | CSL_FMKR(19,18,0) | CSL_FMKR(17,0,(int)SPD.tREFPRD);
+
+ phyA_cfg.zq0cr1 = 0x0000007B;
+ phyA_cfg.zq1cr1 = 0x0000007B;
+ phyA_cfg.zq2cr1 = 0x0000007B;
+
+ phyA_cfg.pir_v1 = 0x00000033;
+ phyA_cfg.pir_v2 = 0x0000FF81;
+
+ //
+ // EMIF register configuration
+ //
+ emifA_cfg.sdcfg = CSL_FMKR(31,29,SPD.SDRAM_TYPE) | CSL_FMKR(27,25,RZQ_4_TERM) | CSL_FMKR(23,22,ODT_DISABLE)
+ | CSL_FMKR(16,14,SPD.CWL)| CSL_FMKR(13,12,DDR3busWidth_32) | CSL_FMKR(11,8,SPD.CAS)
+ | CSL_FMKR(6,5,SPD.IBANK) | CSL_FMKR(3,3,DCE0) | CSL_FMKR(1,0,SPD.PAGESIZE);
+ emifA_cfg.sdtim1 = CSL_FMKR(29,25,SPD.tWR-1) | CSL_FMKR(24,18,SPD.tRAS-1) | CSL_FMKR(17,10,SPD.tRC-1)
+ | CSL_FMKR(9,4,SPD.T_RRD) | CSL_FMKR(3,0,SPD.tWTR-1);
+ emifA_cfg.sdtim2 = CSL_FMKR(12,10,0x07) | CSL_FMKR(9,5,SPD.tRP-1) | CSL_FMKR(4,0,SPD.tRCD-1);
+ emifA_cfg.sdtim3 = CSL_FMKR(31,28,SPD.tXP-1) | CSL_FMKR(27,18,SPD.tXS-1) | CSL_FMKR(17,8,SPD.tXSDLL-1)
+ | CSL_FMKR(7,4,SPD.tRTP-1) | CSL_FMKR(3,0,SPD.tCKE-1);
+ emifA_cfg.sdtim4 = CSL_FMKR(31,28,SPD.T_CSTA) | CSL_FMKR(27,24,SPD.tCKESR-1) | CSL_FMKR(23,16,SPD.tZQCS-1) | CSL_FMKR(13,4,SPD.tRFC-1)
+ | CSL_FMKR(3,0,SPD.T_RAS_MAX);
+ emifA_cfg.sdrfc = CSL_FMKR(31,31,0) | CSL_FMKR(15,0,SPD.REFRESH_RATE-1);
+
+ emifA_cfg.zqcfg = CSL_FMKR(31,31,DCE0) | 70073200;
+
+ CSL_BootCfgUnlockKicker();
+
+ init_ddrphy(DDR3A_DDRPHYC, &phyA_cfg, 0);
+ init_ddremif(DDR3A_EMIF_CTRL_BASE,&emifA_cfg);
+
+
+ return (status);;
+}
+
+