/******************************************************************************
  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 baisc configuration
  History       :
  1.Date        : July 8, 2013
    Author      : Brighton Feng
    Modification: Created file
******************************************************************************/
#include <stdio.h>
#include "K2_Board_Init.h"

#define DDR_INIT_MAX_RETRY_NUM 	10

/*simple test to verify basic functions of DDR.
return fail count*/
int DDR_simple_test(unsigned int uiStartAddress,
	unsigned int uiByteCount)
{
	unsigned int uiFailCount= 0;
	
	uiFailCount += Memory_Fill_Test(uiStartAddress,uiByteCount, 0x00000000, 8, 0);
	uiFailCount += Memory_Fill_Test(uiStartAddress,uiByteCount, 0xFFFFFFFF, 8, 0);
	uiFailCount += Memory_Address_Test(uiStartAddress,uiByteCount, 8, 1024);
	uiFailCount += Memory_Bus_Bit_Walking(uiStartAddress);

	return uiFailCount;
}

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

	puts("DDR3A initialization");

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

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

	/*----------------DDR PLL configuration----------------*/
	/*DDR3 data rate will be confiugred as 
	ref_clock_MHz*PLL_multiplier/PLL_divisor*/
	DDR_cfg.ref_clock_MHz=  100; //reference clock speed in MHz
	DDR_cfg.PLL_multiplier= 40;
	DDR_cfg.PLL_divisor=    3;

	/*--------------SDRAM basic configuration--------------*/
	DDR_cfg.busWidth= DDR_BUS_WIDTH_32;
	DDR_cfg.num_bank= DDR_8_BANK;
	DDR_cfg.num_CE=   DDR_1_CE;
	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;

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

		//simple test, return if it pass, retry if it fail
		if(0==DDR_simple_test(0x80000000, 256))
			return;
			
		uiRetryCount++;
		printf("DDR3A reinitialization %d times\n", uiRetryCount);
	}
	puts("!DDR3A reinitialization failed!");
}

#if(2==CSL_DDR3_PER_CNT)
/*configure DDR3B on EVM*/
void K2_DDR3B_config(DDR3_Arbitration_Config * arbitration_cfg, 
	DDR3_ECC_Config * ecc_cfg)
{
	Uint32 uiRetryCount=0;
	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 *)&gBootCfgRegs->DDR3B_PLL_CTL0;
	DDR_cfg.ControlRegs= gDDR3ControlRegs[1];
	DDR_cfg.PHY_Regs= gDDR3_PHY_Regs[1];

	/*----------------DDR PLL configuration----------------*/
	/*DDR3 data rate will be confiugred as 
	ref_clock_MHz*PLL_multiplier/PLL_divisor*/
	DDR_cfg.ref_clock_MHz=  100; //reference clock speed in MHz
	DDR_cfg.PLL_multiplier= 16;
	DDR_cfg.PLL_divisor=    1;

	/*--------------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.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;

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

		//simple test, return if it pass, retry if it fail
		if(0==DDR_simple_test(0x60000000, 256))
			return;
			
		uiRetryCount++;
		printf("DDR3B reinitialization %d times\n", uiRetryCount);
	}
	puts("!DDR3B reinitialization failed!");
}
#endif /*(2==CSL_DDR3_PER_CNT)*/
#endif /*defined(K2K_EVM)*/

