/******************************************************************************
  Copyright (C), 2013, Texas Instrument.
 ******************************************************************************
  File Name     : K2_Board_Init.c
  Version       : Initial Draft
  Author        : Brighton Feng
  Created       : July 8, 2013
  Last Modified :
  Description   : KeyStone 2 Board basic configuration
  History       :
  1.Date        : July 8, 2013
    Author      : Brighton Feng
    Modification: Created file
  2.Date        : March 3, 2014
    Author      : Brighton Feng
    Modification: update for K2E/K2L, support 1600MTS x 64 bits.
                  add DDR3 ECC rleated functions.
******************************************************************************/
#include <stdio.h>
#include <csl_edma3.h>
#include "common_test.h"
#include "K2_Board_Init.h"

#define DDR_INIT_MAX_RETRY_NUM 	10

#pragma DATA_SECTION(DDR3A_REGS_MPAX_cfg_table,".far:Core_MPAX")
MPAX_Config DDR3A_REGS_MPAX_cfg_table[]=
{
    /*BADDR         RADDR           SegementSize      AccessPermisionMask
    32-bit virtual  36-bit physical in byte, must     Access types allowed
    base address    address right   be power of 2     in this address range
                    shift by 4                                            */
    {0x21010000,    0x121010000>>4,  4*1024,         MP_SR|MP_SW|MP_UR|MP_UW}/*map DDR3A configuration registers at physical address 0x1:00000000 to logical address 0x21010000*/
};

//check the if the DDR3 registers are mapped. If not, map it
void DDR3A_registers_adress_map()
{
	int i=0;
	for(i=0; i<16; i++)
	{
		if(0x12101000==(gpXMC_regs->XMPAX[i].XMPAXL&CSL_XMC_XMPAXL_RADDR_MASK))
		{//DDR3 registers at 0x1:21010000 is mapped in the XMPAX
			break;
		}
	}
	if(i==16) //not mapped, map it to last segement
	{
		KeyStone_XMC_MPAX_setup(DDR3A_REGS_MPAX_cfg_table, 15,
			sizeof(DDR3A_REGS_MPAX_cfg_table)/sizeof(MPAX_Config));
	}		
}

/*Copy data from MSMC_RAM to DDR ECC range by EDMA CC0 TC0 to intialize the ECC parity values.
MSMC_RAM->DDR is the fastest data path, EDMA CC0 TC0 is the fastest engine.
The data content be copied is not care because we only need to generate valide ECC parity values.
Since the DDR ECC range is multiple of 128KB, the low 17 bit of "uiStartAddr" and "uiByteCnt" shoudl be 0.
This function should be called right after DDR initialization and before other EDMA operations*/
void Fill_DDR_ECC_range_by_EDMA(Uint32 uiStartAddr, Uint32 uiByteCnt)
{
	int i;
	Uint32 uiCCNT;

	if(0==uiByteCnt)
		return;
		
	/*clear error/status flags*/
	gpEDMA_CC0_regs->TPCC_EMCR= 0xFFFF;
	gpEDMA_CC0_regs->TPCC_SECR= 0xFFFF;
	gpEDMA_CC0_regs->TPCC_ICR=  0xFFFF;
	gpEDMA_CC0_regs->TPCC_ECR=  0xFFFF;
    gpEDMA_CC0_regs->TPCC_CCERRCLR= 0xFFFF;

	/*Assign PaRAM for different channels*/
	for(i=0; i<64; i++) 	
		gpEDMA_CC0_regs->TPCC_DCHMAP[i] = i<< CSL_TPCC_TPCC_DCHMAP0_PAENTRY_SHIFT;

	uiCCNT= uiByteCnt>>14;
	while(uiCCNT)
	{
		//intermediate chaining is uesed to achieve ABC SYNC.
		gpEDMA_CC_regs[0]->PARAMSET[0].OPT= 
			CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_EN,
				CSL_EDMA3_TCCH_DIS, 
				CSL_EDMA3_ITCINT_DIS, 
				CSL_EDMA3_TCINT_EN,
				0,
				CSL_EDMA3_TCC_NORMAL,
				CSL_EDMA3_FIFOWIDTH_NONE, 
				CSL_EDMA3_STATIC_DIS, 
				CSL_EDMA3_SYNC_AB, 
				CSL_EDMA3_ADDRMODE_INCR, 
				CSL_EDMA3_ADDRMODE_INCR);
		gpEDMA_CC_regs[0]->PARAMSET[0].SRC= 0xC000000;  	//address of MSMC_RAM
		gpEDMA_CC_regs[0]->PARAMSET[0].A_B_CNT= CSL_EDMA3_CNT_MAKE(0x4000, 1);
		gpEDMA_CC_regs[0]->PARAMSET[0].DST= uiStartAddr;
		gpEDMA_CC_regs[0]->PARAMSET[0].SRC_DST_BIDX= CSL_EDMA3_BIDX_MAKE(0, 0x4000);
		gpEDMA_CC_regs[0]->PARAMSET[0].LINK_BCNTRLD= CSL_EDMA3_LINKBCNTRLD_MAKE(0xFFFF, 1);
		gpEDMA_CC_regs[0]->PARAMSET[0].SRC_DST_CIDX= CSL_EDMA3_CIDX_MAKE(0, 0x4000);
		if(uiCCNT>32768)
		{
			gpEDMA_CC_regs[0]->PARAMSET[0].CCNT= 32768;
			uiCCNT -= 32768;
		}
		else
		{
			gpEDMA_CC_regs[0]->PARAMSET[0].CCNT= uiCCNT;
			uiCCNT = 0;
		}
		
		/*Manually trigger the EDMA*/
		gpEDMA_CC_regs[0]->TPCC_ESR= 1;
	 
		/*wait for completion*/
		while(0==(gpEDMA_CC_regs[0]->TPCC_IPR&1));

		/*clear completion flag*/
		gpEDMA_CC_regs[0]->TPCC_ICR= 1;
	}
}

/*quick test to verify basic functions of memory from "uiStartAddress".
"uiTotalByteCount" determines number of address bits for address bus test.
this function returns fail count*/
int DDR_quick_test(unsigned int uiStartAddress,
	unsigned int uiTotalByteCount, Bool bECC_enabled)
{
	unsigned int uiFailCount= 0;
	
	uiFailCount += Memory_Fill_Test(uiStartAddress,256, 0x00000000, 8, 8);
	uiFailCount += Memory_Fill_Test(uiStartAddress,256, 0xFFFFFFFF, 8, 8);
	uiFailCount += Memory_Address_Test(uiStartAddress,256, 8, 8);

	if(FALSE==bECC_enabled)
	{//only continuous filling test can be done when ECC is enabled.
		uiFailCount += Memory_Data_Bus_Test(uiStartAddress, 64);
		uiFailCount += Memory_Address_Bus_Test(uiStartAddress, uiTotalByteCount, 1);
	}
	
	return uiFailCount;
}

/*initialize and quick test to verify basic functions of memory from "uiStartAddress".
"uiTotalByteCount" determines number of address bits for address bus test.
this function returns fail count*/
void DDR_init_and_quick_test(DDR3_Config * DDR_cfg,
	unsigned int uiStartAddress, unsigned int uiTotalByteCount)
{
	int i;
	Uint32 uiRetryCount=0;
	Uint32 uiEccRangeCnt=0;
	DDR3_ECC_Addr_Range addressRanges[3];
	DDR3_ECC_Config * ecc_cfg= DDR_cfg->ecc_cfg;

	if(ecc_cfg) 	//fill the ECC range to generate inital parity values
	{
		uiEccRangeCnt= get_DDR_ECC_ranges(ecc_cfg, addressRanges, (unsigned long long)uiTotalByteCount);
		if(uiEccRangeCnt)
		{
			puts(" DDR ECC is enabled.");
		}
	}		

	while(DDR_INIT_MAX_RETRY_NUM>uiRetryCount)
	{
		K2_DDR_Init(DDR_cfg);

		//DDR_cfg->ControlRegs->ECC_CTRL &= ~CSL_EMIF4FV_ECC_CTRL_REG_ECC_VERIFY_EN_MASK;

		/*Note: 36-bit DDR3 internal address need be translated into 32-bit EDMA virtul address.
		if the ECC range is larger than 2GB, SES MPAX need be reconfigured.*/
		for(i=0; i<uiEccRangeCnt; i++)
			Fill_DDR_ECC_range_by_EDMA(
				(Uint32)addressRanges[i].startAddr+uiStartAddress, /*covert to EDMA virtual address*/
				(Uint32)addressRanges[i].byteCnt);

		//DDR_cfg->ControlRegs->ECC_CTRL |= CSL_EMIF4FV_ECC_CTRL_REG_ECC_VERIFY_EN_MASK;

		//simple test to verify the basic function, return if it pass, retry if it fail
		if(0==DDR_quick_test(uiStartAddress, uiTotalByteCount, (Bool)uiEccRangeCnt))
			return;
			
		uiRetryCount++;
		printf("DDR3A reinitialization %d times\n", uiRetryCount);
	}
	puts("!DDR3A reinitialization failed!");
}

#if defined(K2K_EVM) || defined(K2H_EVM) || defined(K2K_EVM_REV2) || defined(K2H_EVM_REV2)
/*configure DDR3A on EVM*/
void K2_DDR3A_config(DDR3_Arbitration_Config * arbitration_cfg, 
	DDR3_ECC_Config * ecc_cfg)
{
	DDR3_Config DDR_cfg;

	puts("DDR3A initialization");

	//check the if the DDR3A registers are mapped. If not, map it
	DDR3A_registers_adress_map();

	DDR_cfg.arbitration_cfg= arbitration_cfg;
	DDR_cfg.ecc_cfg= ecc_cfg;

	/*------------------register pointers------------------*/
	DDR_cfg.PLL_Regs= (PLL_ControlRegs *)&gpBootCfgRegs->DDR3A_PLL_CTL0;
	DDR_cfg.ControlRegs= gpDDR3ControlRegs[0];
	DDR_cfg.PHY_Regs= gDDR3_PHY_Regs[0];

	/*----------------DDR PLL configuration----------------*/
	/*DDR_data_rate = ref_clock_MHz/PLL_input_divisor*PLL_multiplier/PLL_output_divisor*4
	Please make, 1.5625GHz < ref_clock_MHz/PLL_input_divisor*PLL_multiplier < 3.125GHz.
	Here: 100/1*20/6*4=1333.33MTS*/
#ifndef K2KH_DDR3A_1600
	DDR_cfg.ref_clock_MHz     = 100; //reference clock speed in MHz
	DDR_cfg.PLL_input_divisor = 1;
	DDR_cfg.PLL_multiplier    = 20;
	DDR_cfg.PLL_output_divisor= 6;
#else
	/*100/1*16/4*4=1600MTS*/
	DDR_cfg.ref_clock_MHz     = 100; //reference clock speed in MHz
	DDR_cfg.PLL_input_divisor = 1;
	DDR_cfg.PLL_multiplier    = 16;
	DDR_cfg.PLL_output_divisor= 4;
#endif
	/*--------------SDRAM basic configuration--------------*/
	if(0==(gpBootCfgRegs->JTAG_ID_REG0&0xF0000000))
	{/*on first revision of K2H/K2K, the DDR3A only support 32-bit width,
	refer to errata of the device for more details*/
		DDR_cfg.busWidth= DDR_BUS_WIDTH_32;
	}
	else
		DDR_cfg.busWidth= DDR_BUS_WIDTH_64;
	DDR_cfg.num_bank= DDR_8_BANK;
	DDR_cfg.num_CE=   DDR_1_CE;
	DDR_cfg.bUDIMM_address_mirror= FALSE;
	DDR_cfg.pageSize= DDR_PAGE_SIZE_10_BIT_1024_WORD;
	DDR_cfg.CL=       DDR_CL_9; //CAS_latency
	DDR_cfg.CWL=      DDR_CWL_7; //CAS_write_latency
	DDR_cfg.drive=    DDR_DRIVE_RZQ_OVER_7;
	DDR_cfg.DDR_TERM= DDR_TERM_RZQ_OVER_4;
	DDR_cfg.DYN_ODT=  DDR_DYN_ODT_DISABLED;
	
	/*-----------board layout timing parameter-------------*/
	DDR_cfg.round_trip_delay_ns= 2; //round trip delay in nanosecond
	DDR_cfg.temperature= DDR_TEMP_OVER_85C;

	/*-----DDR Timing values from DDR memory data sheet----*/
	/*the unit of following parameters is ns (nanosecond)*/
	DDR_cfg.tRCD  = 13.5;
	DDR_cfg.tRP   = 13.5;
	DDR_cfg.tRAS  = 36;
	DDR_cfg.tRC   = 49.5;
	DDR_cfg.tWR   = 15;
	DDR_cfg.tFAW  = 30;
	DDR_cfg.tRFC  = 160;
	DDR_cfg.tWLO  = 9;
	/*the unit of following parameters is clock number*/
	DDR_cfg.tCCD  =  4;
	DDR_cfg.tMRD  =  4;
	DDR_cfg.tDLLK =  512;
	DDR_cfg.tZQOPER= 256;
	DDR_cfg.tZQCS =  64;
	DDR_cfg.tWLMRD=  40;
	/*DDR3 timing parameters specified as maximum of nanosecond and number of clock*/
	DDR_cfg.tWTR.nCK=   4;
	DDR_cfg.tWTR.ns =   7.5;
	DDR_cfg.tRTP.nCK=   4;
	DDR_cfg.tRTP.ns =   7.5;
	DDR_cfg.tXP.nCK=    3;
	DDR_cfg.tXP.ns =    6;
	DDR_cfg.tXPDLL.nCK= 10;
	DDR_cfg.tXPDLL.ns = 24;
	DDR_cfg.tXS.nCK=    5;
	DDR_cfg.tXS.ns =    DDR_cfg.tRFC+10;
	DDR_cfg.tCKE.nCK=   3;
	DDR_cfg.tCKE.ns =   5.625;
	DDR_cfg.tMOD.nCK=   12;
	DDR_cfg.tMOD.ns =   15;
	DDR_cfg.tRRD.nCK=   4;
	DDR_cfg.tRRD.ns =   6;

#if (DDR3A_SIZE_BYTES<0x80000000ULL)
	DDR_init_and_quick_test(&DDR_cfg, 0x80000000, (Uint32)DDR3A_SIZE_BYTES);
#else 	//simple test only done for less than 2GB
	DDR_init_and_quick_test(&DDR_cfg, 0x80000000, 0x80000000);
#endif
}

#if (2==CSL_DDR3_PER_CNT)
/*configure DDR3B on EVM*/
void K2_DDR3B_config(DDR3_Arbitration_Config * arbitration_cfg, 
	DDR3_ECC_Config * ecc_cfg)
{
	DDR3_Config DDR_cfg;

	puts("DDR3B initialization");

	DDR_cfg.arbitration_cfg= arbitration_cfg;
	DDR_cfg.ecc_cfg= ecc_cfg;

	/*------------------register pointers------------------*/
	DDR_cfg.PLL_Regs= (PLL_ControlRegs *)&gpBootCfgRegs->DDR3B_PLL_CTL0;
	DDR_cfg.ControlRegs= gpDDR3ControlRegs[1];
	DDR_cfg.PHY_Regs= gDDR3_PHY_Regs[1];

	/*----------------DDR PLL configuration----------------*/
	/*DDR_data_rate = ref_clock_MHz/PLL_input_divisor*PLL_multiplier/PLL_output_divisor*4
	Please make, 1.5625GHz < ref_clock_MHz/PLL_input_divisor*PLL_multiplier < 3.125GHz.
	Here: 100/1*16/4*4=1600MTS*/
	DDR_cfg.ref_clock_MHz     = 100; //reference clock speed in MHz
	DDR_cfg.PLL_input_divisor = 1;
	DDR_cfg.PLL_multiplier    = 16;
	DDR_cfg.PLL_output_divisor= 4;

	/*--------------SDRAM basic configuration--------------*/
	DDR_cfg.busWidth= DDR_BUS_WIDTH_64;
	DDR_cfg.num_bank= DDR_8_BANK;
	DDR_cfg.num_CE=   DDR_1_CE;
	DDR_cfg.bUDIMM_address_mirror= FALSE;
	DDR_cfg.pageSize= DDR_PAGE_SIZE_10_BIT_1024_WORD;
	DDR_cfg.CL=       DDR_CL_11; //CAS_latency
	DDR_cfg.CWL=      DDR_CWL_8; //CAS_write_latency
	DDR_cfg.drive=    DDR_DRIVE_RZQ_OVER_7;
	DDR_cfg.DDR_TERM= DDR_TERM_RZQ_OVER_4;
	DDR_cfg.DYN_ODT=  DDR_DYN_ODT_DISABLED;
	
	/*-----------board layout timing parameter-------------*/
	DDR_cfg.round_trip_delay_ns= 2; //round trip delay in nanosecond
	DDR_cfg.temperature= DDR_TEMP_OVER_85C;

	/*-----DDR Timing values from DDR memory data sheet----*/
	/*the unit of following parameters is ns (nanosecond)*/
	DDR_cfg.tRCD  = 13.75;
	DDR_cfg.tRP   = 13.75;
	DDR_cfg.tRAS  = 35;
	DDR_cfg.tRC   = 48.75;
	DDR_cfg.tWR   = 15;
	DDR_cfg.tFAW  = 40;
#if 0 //defined(K2K_EVM) || defined(K2H_EVM)
	//the DDR3 memory on EVM rev 1.0 is K4B2G1646E
	DDR_cfg.tRFC  = 160;
#else
	//the DDR3 memory on EVM rev 2.0 is K4B4G1646B
	DDR_cfg.tRFC  = 260;
#endif
	DDR_cfg.tWLO  = 7.5;
	/*the unit of following parameters is clock number*/
	DDR_cfg.tCCD  =  4;
	DDR_cfg.tMRD  =  4;
	DDR_cfg.tDLLK =  512;
	DDR_cfg.tZQOPER= 256;
	DDR_cfg.tZQCS =  64;
	DDR_cfg.tWLMRD=  40;
	/*DDR3 timing parameters specified as maximum of nanosecond and number of clock*/
	DDR_cfg.tWTR.nCK=   4;
	DDR_cfg.tWTR.ns =   7.5;
	DDR_cfg.tRTP.nCK=   4;
	DDR_cfg.tRTP.ns =   7.5;
	DDR_cfg.tXP.nCK=    3;
	DDR_cfg.tXP.ns =    6;
	DDR_cfg.tXPDLL.nCK= 10;
	DDR_cfg.tXPDLL.ns = 24;
	DDR_cfg.tXS.nCK=    5;
	DDR_cfg.tXS.ns =    DDR_cfg.tRFC+10;
	DDR_cfg.tCKE.nCK=   3;
	DDR_cfg.tCKE.ns =   5;
	DDR_cfg.tMOD.nCK=   12;
	DDR_cfg.tMOD.ns =   15;
	DDR_cfg.tRRD.nCK=   4;
	DDR_cfg.tRRD.ns =   6;

#if (DDR3B_SIZE_BYTES<0x20000000ULL)
	DDR_init_and_quick_test(&DDR_cfg, 0x60000000, (Uint32)DDR3B_SIZE_BYTES);
#else 	//simple test only done for less than 512MB
	DDR_init_and_quick_test(&DDR_cfg, 0x60000000, 0x20000000);
#endif

}
#endif /*(2==CSL_DDR3_PER_CNT)*/
#endif /*defined(K2K_EVM)*/

#if defined(K2L_EVM)  
/*configure DDR3A on EVM*/
void K2_DDR3A_config(DDR3_Arbitration_Config * arbitration_cfg, 
	DDR3_ECC_Config * ecc_cfg)
{
	DDR3_Config DDR_cfg;

	puts("DDR3A initialization");

	//check the if the DDR3A registers are mapped. If not, map it
	DDR3A_registers_adress_map();

	DDR_cfg.arbitration_cfg= arbitration_cfg;
	DDR_cfg.ecc_cfg= ecc_cfg;

	/*------------------register pointers------------------*/
#ifdef DDR3A_PLL_CTL0
	DDR_cfg.PLL_Regs= (PLL_ControlRegs *)&gpBootCfgRegs->DDR3A_PLL_CTL0;
#else
	DDR_cfg.PLL_Regs= (PLL_ControlRegs *)&gpBootCfgRegs->DDRA_PLL_CTL0;
#endif
	DDR_cfg.ControlRegs= gpDDR3ControlRegs;
	DDR_cfg.PHY_Regs= gDDR3_PHY_Regs;

	/*----------------DDR PLL configuration----------------*/
	/*DDR_data_rate = ref_clock_MHz/PLL_input_divisor*PLL_multiplier/PLL_output_divisor*4
	Please make, 1.5625GHz < ref_clock_MHz/PLL_input_divisor*PLL_multiplier < 3.125GHz.
	Here: 100/1*16/4*4=1600MTS*/
	DDR_cfg.ref_clock_MHz     = 100; //reference clock speed in MHz
	DDR_cfg.PLL_input_divisor = 1;
	DDR_cfg.PLL_multiplier    = 16;
	DDR_cfg.PLL_output_divisor= 4;

	/*--------------SDRAM basic configuration--------------*/
	DDR_cfg.busWidth= DDR_BUS_WIDTH_64;
 	DDR_cfg.num_bank= DDR_8_BANK;
	DDR_cfg.num_CE=   DDR_1_CE;
	DDR_cfg.bUDIMM_address_mirror= FALSE;
	DDR_cfg.pageSize= DDR_PAGE_SIZE_10_BIT_1024_WORD;
	DDR_cfg.CL=       DDR_CL_11; //CAS_latency
	DDR_cfg.CWL=      DDR_CWL_8; //CAS_write_latency
	DDR_cfg.drive=    DDR_DRIVE_RZQ_OVER_7;
	DDR_cfg.DDR_TERM= DDR_TERM_RZQ_OVER_4;
	DDR_cfg.DYN_ODT=  DDR_DYN_ODT_DISABLED;
	
	/*-----------board layout timing parameter-------------*/
	DDR_cfg.round_trip_delay_ns= 2; //round trip delay in nanosecond
	DDR_cfg.temperature= DDR_TEMP_OVER_85C;

	/*-----DDR Timing values from DDR memory data sheet----*/
	/*the unit of following parameters is ns (nanosecond)*/
	DDR_cfg.tRCD  = 13.75;
	DDR_cfg.tRP   = 13.75;
	DDR_cfg.tRAS  = 35;
	DDR_cfg.tRC   = 48.75;
	DDR_cfg.tWR   = 15;
	DDR_cfg.tFAW  = 40;
	DDR_cfg.tRFC  = 260;
	DDR_cfg.tWLO  = 7.5;
	/*the unit of following parameters is clock number*/
	DDR_cfg.tCCD  =  4;
	DDR_cfg.tMRD  =  4;
	DDR_cfg.tDLLK =  512;
	DDR_cfg.tZQOPER= 256;
	DDR_cfg.tZQCS =  64;
	DDR_cfg.tWLMRD=  40;
	/*DDR3 timing parameters specified as maximum of nanosecond and number of clock*/
	DDR_cfg.tWTR.nCK=   4;
	DDR_cfg.tWTR.ns =   7.5;
	DDR_cfg.tRTP.nCK=   4;
	DDR_cfg.tRTP.ns =   7.5;
	DDR_cfg.tXP.nCK=    3;
	DDR_cfg.tXP.ns =    6;
	DDR_cfg.tXPDLL.nCK= 10;
	DDR_cfg.tXPDLL.ns = 24;
	DDR_cfg.tXS.nCK=    5;
	DDR_cfg.tXS.ns =    DDR_cfg.tRFC+10;
	DDR_cfg.tCKE.nCK=   3;
	DDR_cfg.tCKE.ns =   5;
	DDR_cfg.tMOD.nCK=   12;
	DDR_cfg.tMOD.ns =   15;
	DDR_cfg.tRRD.nCK=   4;
	DDR_cfg.tRRD.ns =   6;

#if (DDR3A_SIZE_BYTES<0x80000000ULL)
	DDR_init_and_quick_test(&DDR_cfg, 0x80000000, (Uint32)DDR3A_SIZE_BYTES);
#else 	//simple test only done for less than 2GB
	DDR_init_and_quick_test(&DDR_cfg, 0x80000000, 0x80000000);
#endif
}

#endif /*defined(K2L_EVM)*/

#if defined(K2E_EVM)  
/*configure DDR3A on EVM*/
void K2_DDR3A_config(DDR3_Arbitration_Config * arbitration_cfg, 
	DDR3_ECC_Config * ecc_cfg)
{
	DDR3_Config DDR_cfg;

	puts("DDR3A initialization");

	//check the if the DDR3A registers are mapped. If not, map it
	DDR3A_registers_adress_map();

	DDR_cfg.arbitration_cfg= arbitration_cfg;
	DDR_cfg.ecc_cfg= ecc_cfg;

	/*------------------register pointers------------------*/
	DDR_cfg.PLL_Regs= (PLL_ControlRegs *)&gpBootCfgRegs->DDR3A_PLL_CTL0;
	DDR_cfg.ControlRegs= gpDDR3ControlRegs;
	DDR_cfg.PHY_Regs= gDDR3_PHY_Regs;

	/*----------------DDR PLL configuration----------------*/
	/*DDR_data_rate = ref_clock_MHz/PLL_input_divisor*PLL_multiplier/PLL_output_divisor*4
	Please make, 1.5625GHz < ref_clock_MHz/PLL_input_divisor*PLL_multiplier < 3.125GHz.
	Here: 100/1*16/4*4=1600MTS*/
	DDR_cfg.ref_clock_MHz     = 100; //reference clock speed in MHz
	DDR_cfg.PLL_input_divisor = 1;
	DDR_cfg.PLL_multiplier    = 16;
	DDR_cfg.PLL_output_divisor= 4;

	/*--------------SDRAM basic configuration--------------*/
	DDR_cfg.busWidth= DDR_BUS_WIDTH_64;
 	DDR_cfg.num_bank= DDR_8_BANK;
	DDR_cfg.num_CE=   DDR_2_CE;
	DDR_cfg.bUDIMM_address_mirror= FALSE;
	DDR_cfg.pageSize= DDR_PAGE_SIZE_10_BIT_1024_WORD;
	DDR_cfg.CL=       DDR_CL_11; //CAS_latency
	DDR_cfg.CWL=      DDR_CWL_8; //CAS_write_latency
	DDR_cfg.drive=    DDR_DRIVE_RZQ_OVER_7;
	DDR_cfg.DDR_TERM= DDR_TERM_RZQ_OVER_4;
	DDR_cfg.DYN_ODT=  DDR_DYN_ODT_DISABLED;
	
	/*-----------board layout timing parameter-------------*/
	DDR_cfg.round_trip_delay_ns= 2; //round trip delay in nanosecond
	DDR_cfg.temperature= DDR_TEMP_OVER_85C;

	/*-----DDR Timing values from DDR memory data sheet----*/
	/*the unit of following parameters is ns (nanosecond)*/
	DDR_cfg.tRCD  = 13.75;
	DDR_cfg.tRP   = 13.75;
	DDR_cfg.tRAS  = 35;
	DDR_cfg.tRC   = 48.75;
	DDR_cfg.tWR   = 15;
	DDR_cfg.tFAW  = 40;
	DDR_cfg.tRFC  = 160;
	DDR_cfg.tWLO  = 7.5;
	/*the unit of following parameters is clock number*/
	DDR_cfg.tCCD  =  4;
	DDR_cfg.tMRD  =  4;
	DDR_cfg.tDLLK =  512;
	DDR_cfg.tZQOPER= 256;
	DDR_cfg.tZQCS =  64;
	DDR_cfg.tWLMRD=  40;
	/*DDR3 timing parameters specified as maximum of nanosecond and number of clock*/
	DDR_cfg.tWTR.nCK=   4;
	DDR_cfg.tWTR.ns =   7.5;
	DDR_cfg.tRTP.nCK=   4;
	DDR_cfg.tRTP.ns =   7.5;
	DDR_cfg.tXP.nCK=    3;
	DDR_cfg.tXP.ns =    6;
	DDR_cfg.tXPDLL.nCK= 10;
	DDR_cfg.tXPDLL.ns = 24;
	DDR_cfg.tXS.nCK=    5;
	DDR_cfg.tXS.ns =    DDR_cfg.tRFC+10;
	DDR_cfg.tCKE.nCK=   3;
	DDR_cfg.tCKE.ns =   5;
	DDR_cfg.tMOD.nCK=   12;
	DDR_cfg.tMOD.ns =   15;
	DDR_cfg.tRRD.nCK=   4;
	DDR_cfg.tRRD.ns =   6;

#if (DDR3A_SIZE_BYTES<0x80000000ULL)
	DDR_init_and_quick_test(&DDR_cfg, 0x80000000, (Uint32)DDR3A_SIZE_BYTES);
#else 	//simple test only done for less than 2GB
	DDR_init_and_quick_test(&DDR_cfg, 0x80000000, 0x80000000);
#endif
}

#endif /*defined(K2E_EVM)*/

/*Initialize SES MPAX for SOC DMA access DDR3A*/
void K2_SES_MPAX_init(K2_PrivID privID, K2_MSMC_Share share)
{
	MSMC_MPAX_Config MPAX_cfg;

	/*memory address extension/mapping and memory protection for EDMA started by ARM core*/
	MPAX_cfg.AccessPermisionMask= MP_SR|MP_SW|MP_UR|MP_UW;
	MPAX_cfg.share = share; //share (coherent) between DMA and ARM core
	MPAX_cfg.BADDR =  0x80000000;
	MPAX_cfg.RADDR = 0x800000000>>4;
#if (DDR3A_SIZE_BYTES>0x80000000)
	MPAX_cfg.SegementSize= 0x80000000;
#else
	MPAX_cfg.SegementSize= DDR3A_SIZE_BYTES;
#endif
	KeyStone_SES_MPAX_setup(&MPAX_cfg, 0, 1, privID);
}

