/****************************************************************************\
 *        Copyright (C) 2012~2013 Texas Instruments Incorporated.           *
 *                           All Rights Reserved                            *
 *                                                                          *
 * GENERAL DISCLAIMER                                                       *
 * ------------------                                                       *
 * All software and related documentation is provided "AS IS" and without   *
 * warranty or support of any kind and Texas Instruments expressly disclaims*
 * all other warranties, express or implied, including, but not limited to, *
 * the implied warranties of merchantability and fitness for a particular   *
 * purpose.  Under no circumstances shall Texas Instruments be liable for   *
 * any incidental, special or consequential damages that result from the    *
 * use or inability to use the software or related documentation, even if   *
 * Texas Instruments has been advised of the liability.                     *
 ****************************************************************************
This example shows EMIF operations:
1. NAND FLASH test, Verified on NAND512R3A2DZA6E on Shannon EVM,
                               MT29F1G08ABBDAHC on Appleton EVM and K2 EVM
2. NOR FLASH test, Verified on JS28F256M29EW on a customer's board.
 ****************************************************************************
 * Created by :                                                             *
 *            Brighton Feng                                                 *
 *            Texas Instruments                                             * 
 *            Jan 5, 2012                                                   *
 *  July 26, 2013 Brighton Feng  Update for K2                              *
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include "K2_common.h"
#include "K2_Board_Init.h"
#include "KeyStone_EMIF16_init.h"
#include "EMIF_NOR_FLASH_test.h"
#include "EMIF_NAND_FLASH_test.h"

/*select between NAND FLASH or NOR FLASH test*/
#define NAND_FLASH_TEST 	1

#define FLASH_TEST_BUFFER_SIZE 	(512*1024)

//MMU memory ranges tables
MMU_Memory_Map_Range memory_ranges[]=
{
	{//MSMC RAM
    .uiVirtualAddress   = 0x0C000000,
    .ullPhysicalAddress = 0x0C000000,
    .uiByteCnt          = MSMC_RAM_SIZE_BYTES,
    .attribute          = MMU_MEM_ATTR_NORMAL_CACHE_RA_WB_WA,
    .accessPermission   = MMU_MEM_ATTR_RW,
    .exectuePermission  = MMU_MEM_ATTR_X,
    .shareAttr          = MMU_MEM_ATTR_OUTER_SHARE,
    .isGlobal           = MMU_MEM_ATTR_GLOBAL,
    .isSecure           = MMU_MEM_ATTR_SECURE,
	},                     
	{//EMIF16               
    .uiVirtualAddress   = CSL_AEMIF_SLV_AS1_EMIF16_CS_DATA,
    .ullPhysicalAddress = CSL_AEMIF_SLV_AS1_EMIF16_CS_DATA, 	
    .uiByteCnt          = 0x02000000, 	
    .attribute          = MMU_MEM_ATTR_STRONG_ORDER,/*can not be set as normal memory for NAND FLASH*/
    .accessPermission   = MMU_MEM_ATTR_RW,
    .exectuePermission  = MMU_MEM_ATTR_XN,
    .shareAttr          = MMU_MEM_ATTR_INNER_SHARE,
    .isGlobal           = MMU_MEM_ATTR_GLOBAL,
    .isSecure           = MMU_MEM_ATTR_SECURE,
	},
	{//DDR3A               
    .uiVirtualAddress   = 0x80000000,
    .ullPhysicalAddress = 0x800000000ULL, 	
#if (DDR3A_SIZE_BYTES>0x80000000ULL)
    .uiByteCnt          = 0x80000000, 	
#else
    .uiByteCnt          = DDR3A_SIZE_BYTES, 	
#endif
    .attribute          = MMU_MEM_ATTR_NORMAL_CACHE_RA_WB_WA,
    .accessPermission   = MMU_MEM_ATTR_RW,
    .exectuePermission  = MMU_MEM_ATTR_XN,
    .shareAttr          = MMU_MEM_ATTR_OUTER_SHARE,
    .isGlobal           = MMU_MEM_ATTR_GLOBAL,
    .isSecure           = MMU_MEM_ATTR_SECURE,
	}
};

MMU_Long_Format_Config mmu_cfg=
{
	.memory_map        = memory_ranges,
	.uiNumMemMapRanges = sizeof(memory_ranges)/sizeof(MMU_Memory_Map_Range),
	.ullpMMU3rdLevelTT = NULL, 	//No level 3 translation table
	.bAlignCheck       = TRUE,
	.tableCacheAttr    = MMU_TAB_ATTR_CACHE_WB_WA,
	.tableShareAttr	   = MMU_MEM_ATTR_INNER_SHARE,
};

Uint8	testBuf[FLASH_TEST_BUFFER_SIZE] __attribute__ ((section (".data.testBuf")));

EMIF16_CE_Config gNorCeCfg;	/*the configuration for the CE of NOR FLASH*/
EMIF16_CE_Config gNandCeCfg;/*the configuration for the CE of NAND FLASH*/
EMIF16_Config gEmif16Cfg;
void EMIF_init()
{
	memset(&gNorCeCfg, 0, sizeof(gNorCeCfg));
	memset(&gNandCeCfg, 0, sizeof(gNandCeCfg));
	memset(&gEmif16Cfg, 0, sizeof(gEmif16Cfg));
	
	/*configuraiton for the CE of NOR FLASH*/
	gNorCeCfg.busWidth= EMIF_BUS_16BIT;
	gNorCeCfg.opMode  = NOR_ASRAM_MODE;
	gNorCeCfg.strobeMode = SS_STROBE;  
	gNorCeCfg.waitMode = EMIF_WAIT_NONE;
	gNorCeCfg.wrSetup = CSL_EMIF16_A0CR_WSETUP_RESETVAL;          
	gNorCeCfg.wrStrobe = CSL_EMIF16_A0CR_WSTROBE_RESETVAL;         
	gNorCeCfg.wrHold= CSL_EMIF16_A0CR_WHOLD_RESETVAL;            
	gNorCeCfg.rdSetup= CSL_EMIF16_A0CR_RSETUP_RESETVAL;           
	gNorCeCfg.rdStrobe= CSL_EMIF16_A0CR_RSTROBE_RESETVAL;          
	gNorCeCfg.rdHold= CSL_EMIF16_A0CR_RHOLD_RESETVAL;            
	gNorCeCfg.turnAroundCycles= CSL_EMIF16_A0CR_TA_RESETVAL;  
	gNorCeCfg.nor_pg_Cfg= NULL;        

	/*configuraiton for the CE of NAND FLASH*/
	gNandCeCfg.busWidth= EMIF_BUS_8BIT;
	gNandCeCfg.opMode  = NAND_MODE;
	gNandCeCfg.strobeMode = SS_STROBE;  
	gNandCeCfg.waitMode = EMIF_WAIT_NONE;
	/*timing configuration for NAND512R3A2DZA6E*/
#if 1
	gNandCeCfg.wrSetup = 1;//CSL_EMIF16_A0CR_WSETUP_RESETVAL,          
	gNandCeCfg.wrStrobe = 4;//CSL_EMIF16_A0CR_WSTROBE_RESETVAL,         
	gNandCeCfg.wrHold= 5;//CSL_EMIF16_A0CR_WHOLD_RESETVAL,            
	gNandCeCfg.rdSetup= 1;//CSL_EMIF16_A0CR_RSETUP_RESETVAL           
	gNandCeCfg.rdStrobe= 7;//CSL_EMIF16_A0CR_RSTROBE_RESETVAL          
	gNandCeCfg.rdHold= 2;//CSL_EMIF16_A0CR_RHOLD_RESETVAL            
#else
	gNandCeCfg.wrSetup = CSL_EMIF16_A0CR_WSETUP_RESETVAL;          
	gNandCeCfg.wrStrobe = CSL_EMIF16_A0CR_WSTROBE_RESETVAL;         
	gNandCeCfg.wrHold= CSL_EMIF16_A0CR_WHOLD_RESETVAL;            
	gNandCeCfg.rdSetup= CSL_EMIF16_A0CR_RSETUP_RESETVAL;           
	gNandCeCfg.rdStrobe= CSL_EMIF16_A0CR_RSTROBE_RESETVAL;         
	gNandCeCfg.rdHold= CSL_EMIF16_A0CR_RHOLD_RESETVAL;            
#endif
	gNandCeCfg.turnAroundCycles= CSL_EMIF16_A0CR_TA_RESETVAL;  
	gNandCeCfg.nor_pg_Cfg= NULL;        

#if NAND_FLASH_TEST
	gEmif16Cfg.ceCfg[EMIF_NAND_FLASH_CS] = &gNandCeCfg;
#else
	gEmif16Cfg.ceCfg[EMIF_NOR_FLASH_CS] = &gNorCeCfg;
#endif

	gEmif16Cfg.wait0Polarity= EMIF_LOW_WAIT;
	gEmif16Cfg.wait1Polarity= EMIF_LOW_WAIT;
	gEmif16Cfg.maxWait = CSL_EMIF16_AWCCR_MAXEXTWAIT_RESETVAL;
	
	KeyStone_EMIF16_init(&gEmif16Cfg);

}

int main()
{
	/*common initialization for internal modules in K2 device 
	enable GIC, memory protection interrupts, EDC for MSMC RAM */
	K2_common_device_init();
	/*initialize GIC interface for CPU, enable IRQ, FIQ, PMU*/
	K2_common_CPU_init();
	KeyStone_Exception_cfg(TRUE);

	//Main core speed= MAIN_PLL_REF_CLK_MHZ*MAIN_PLL_MULTIPLIER/MAIN_PLL_DIVISOR
	KeyStone_main_PLL_init(MAIN_PLL_REF_CLK_MHZ, MAIN_PLL_MULTIPLIER, MAIN_PLL_DIVISOR);
	//KeyStone_main_PLL_init(MAIN_PLL_REF_CLK_MHZ, 36, 4);

#ifndef DEVICE_K2E 	//K2E only has main PLL for both ARM and DSP cores
	//ARM core speed= ARM_PLL_REF_CLK_MHZ*ARM_PLL_MULTIPLIER/ARM_PLL_DIVISOR
	K2_ARM_PLL_init(ARM_PLL_REF_CLK_MHZ, ARM_PLL_MULTIPLIER, ARM_PLL_DIVISOR);
	//K2_ARM_PLL_init(125, 8, 1);
#endif

	K2_DDR3A_config(NULL, NULL);

	/*MMU configure for ARM core*/
	MMU_long_format_init(&mmu_cfg);
	CP15_ICacheEnable();
	CP15_DCacheEnable();

	//On K2, EMIF belong to clock domain 3 which need be enabled
	KeyStone_enable_PSC_module(CSL_PSC_PD_ALWAYSON, CSL_PSC_LPSC_AEMIF_SPI);

	EMIF_init();

#if NAND_FLASH_TEST
	NAND_FLASH_test((Uint32)testBuf, FLASH_TEST_BUFFER_SIZE);
#else
	NOR_FLASH_test((Uint32)testBuf, FLASH_TEST_BUFFER_SIZE);
#endif

	puts("FLASH test complete.");

	return 0;
}

