/******************************************************************************

  Copyright (C), 2014, Texas Instrument.

 ******************************************************************************
  File Name     : K2_common.c
  Version       : Initial Draft
  Author        : Brighton Feng
  Created       : June 11, 2014
  Description   : KeyStone 2 common miscellaneous functions and definitions

******************************************************************************/
#ifndef _KEYSTONE_COMMON_H_
#define _KEYSTONE_COMMON_H_

#include <tistdtypes.h>
#include <stdio.h>
#include <cslr_pllc.h>
#include <cslr_bootcfg.h>
#include <cslr_tpcc.h>
#include <cslr_tptc.h>
#include <cslr_device.h>
#include <cslr_cpintc.h>
#include <cslr_tmr.h>
#include <cslr_srio.h>
#include <cslr_vusr.h>
#include <csl_psc.h>
#include <csl_tmr.h>
#include <cslr_msmc.h>
#include <cslr_mpu.h>
#include <cslr_gpio.h>
#include <cslr_emif4f.h>
#include <cslr_gic400.h>
#include <csl_device_interrupt.h>
#include <cslr_tetris_vbusp.h>
#include "CP15.h"
#include "ARMv7_CPU.h"

typedef enum
{
	K2H_K2K = 0,
	K2E,
	K2L,
	UNKNOWN
}K2_Device_Type;

/*----------------parameters based on device type------------------*/
#if defined(DEVICE_K2L)
#define MSMC_RAM_SIZE_BYTES      (2*1024*1024) /*size of MSMC_RAM in bytes*/
#define NUMBER_ARM_CORES    2   /*number of ARM cores*/
#define NUMBER_DSP_CORES    4   /*number of DSP cores*/
#define NUM_EDMA_TC 	10
#define NUM_EDMA_CC 	3

//boot magic address of ARM cores
#define ARM_CORE0_BOOT_ADDRESS 0x0C1D2500
#define ARM_CORE1_BOOT_ADDRESS 0x0C1D2504

#elif defined(DEVICE_K2E)
#define MSMC_RAM_SIZE_BYTES      (2*1024*1024) /*size of MSMC_RAM in bytes*/
#define NUMBER_ARM_CORES    4   /*number of ARM cores*/
#define NUMBER_DSP_CORES    1   /*number of DSP cores*/
#define NUM_EDMA_TC 	14
#define NUM_EDMA_CC 	5

//boot magic address of ARM cores
#define ARM_CORE0_BOOT_ADDRESS 0x0C1D2500
#define ARM_CORE1_BOOT_ADDRESS 0x0C1D2504

#elif defined(DEVICE_K2H) || defined(DEVICE_K2K)
#define MSMC_RAM_SIZE_BYTES      (6*1024*1024) /*size of MSMC_RAM in bytes*/
#define NUMBER_ARM_CORES    4   /*number of ARM cores*/
#define NUMBER_DSP_CORES    8   /*number of DSP cores*/
#define NUM_EDMA_TC 	14
#define NUM_EDMA_CC 	5

//boot magic address of ARM cores
#define ARM_CORE0_BOOT_ADDRESS 0xc5ad000
#define ARM_CORE1_BOOT_ADDRESS 0xc5ad004
#define ARM_CORE2_BOOT_ADDRESS 0xc5ad008
#define ARM_CORE3_BOOT_ADDRESS 0xc5ad00c

#else
    #error Device type is NOT defined.
#endif

/*size of MSMC_RAM used by boot at the end of MSMC RAM*/
#define BOOT_USED_MSMC_RAM_SIZE_BYTES      (0x80000) 

/*----------------------PLL registers definition----------------*/
#define PLLCTL0_PLLD_SHIFT   (0)
#define PLLCTL0_PLLD_MASK    (0x3F<<PLLCTL0_PLLD_SHIFT)
#define PLLCTL0_PLLM_SHIFT   (6)
#define PLLCTL0_PLLM_MASK    (0x1FFF<<PLLCTL0_PLLM_SHIFT)
#define PLLCTL_OD_SHIFT      (19)
#define PLLCTL_OD_MASK       (0xF<<PLLCTL_OD_SHIFT)
#define PLLCTL_BYPASS_SHIFT  (23)
#define PLLCTL_BYPASS_MASK   (0x1<<PLLCTL_BYPASS_SHIFT)
#define PLLCTL0_BWADJ_SHIFT  (24)
#define PLLCTL0_BWADJ_MASK   (0xFF<<PLLCTL0_BWADJ_SHIFT)

#define PLLCTL1_BWADJ_SHIFT    (0)
#define PLLCTL1_BWADJ_MASK     (0xF<<PLLCTL1_BWADJ_SHIFT)
#define PLLCTL1_ENSAT_SHIFT    (6)
#define PLLCTL1_ENSAT_MASK     (0x1<<PLLCTL1_ENSAT_SHIFT)
#define PLLCTL1_PLLSEL_SHIFT    (13)
#define PLLCTL1_PLLSEL_MASK     (0x1<<PLLCTL1_PLLSEL_SHIFT)
#define PLLCTL1_PLLRESET_SHIFT (14)
#define PLLCTL1_PLLRESET_MASK  (0x1<<PLLCTL1_PLLRESET_SHIFT)

/*----------------------Boot Config registers definition----------------*/
#define DEVSPEED_1000_MHZ_MASK_L  (1<<0)
#define DEVSPEED_1200_MHZ_MASK_L  (1<<1)
#define DEVSPEED_1350_MHZ_MASK_L  (1<<2)
#define DEVSPEED_1400_MHZ_MASK_L  (1<<3)
#define DEVSPEED_1500_MHZ_MASK    (1<<4)
#define DEVSPEED_1400_MHZ_MASK_H  (1<<5)
#define DEVSPEED_1350_MHZ_MASK_H  (1<<6)
#define DEVSPEED_1200_MHZ_MASK_H  (1<<7)
#define DEVSPEED_1000_MHZ_MASK_H  (1<<8)
#define DEVSPEED_800_MHZ_MASK_H   (1<<9)

#define DEVSPEED_ARM_SPEED_MASK  (0xFFF<<0)
#define DEVSPEED_DSP_SPEED_MASK  (0xFFF<<16)
#define DEVSPEED_ARM_SPEED_SHIFT  (0)
#define DEVSPEED_DSP_SPEED_SHIFT  (16)

#define DEVSTAT_LENDIAN_SHIFT     (0)
#define DEVSTAT_BOOTMODE_SHIFT    (1)
#define DEVSTAT_SYSPLL_SHIFT      (5)
#define DEVSTAT_BOOTMASTER_SHIFT  (8)
#define DEVSTAT_ARMPLL_SHIFT      (9)

#define DEVSTAT_LENDIAN_MASK     (1<<0)
#define DEVSTAT_BOOTMODE_MASK    (7<<1)
#define DEVSTAT_SYSPLL_MASK      (7<<5)
#define DEVSTAT_BOOTMASTER_MASK  (1<<8)
#define DEVSTAT_ARMPLL_MASK      (7<<9)
/*----------------------Timer plus registers definition----------------*/
#define TMR_TCR_READRSTMODE_HI_SHIFT    (26)
#define TMR_TCR_CAPEVTMODE_LO_SHIFT     (12)
#define TMR_TCR_CAPMODE_LO_SHIFT        (11)
#define TMR_TCR_READRSTMODE_LO_SHIFT    (10)

#define TMR_TCR_READRSTMODE_HI_MASK    (1<<26)
#define TMR_TCR_CAPEVTMODE_LO_MASK     (3<<12)
#define TMR_TCR_CAPMODE_LO_MASK        (1<<11)
#define TMR_TCR_READRSTMODE_LO_MASK    (1<<10)

#define TMR_TGCR_PLUSEN_SHIFT 	       4
#define TMR_TGCR_PLUSEN_MASK 	       (1<<4)

#define TMR_INTCTLSTAT_EN_ALL_CLR_ALL   0x000F000F

#define CSL_TMR_WDTCR_WDKEY_CMD1         (0x0000A5C6u)
#define CSL_TMR_WDTCR_WDKEY_CMD2         (0x0000DA7Eu)

/*----------------------------------------------*
 * macros                                       *
 *----------------------------------------------*/
/*convert DSP core local address to global address for DMA on multi-core DSP*/
#define GLOBAL_ADDR(addr, DSP_core_num) ((Uint32)addr<0x1000000?\
						(Uint32)addr+(0x10000000+DSP_core_num*0x1000000):\
						(Uint32)addr)

/*according to default mapping, convert DDR3 logic address to 
32-bit physical address (36-bit physical address right shift by 4)*/
#define DDR_PHY_ADDR(addr) ((((Uint32)addr & 0x7FFFFFFF)>>4) | 0x80000000)

/*max number in two numbers*/
#define MAX(a, b) (a>b?a:b)
/*min number in two numbers*/
#define MIN(a, b) (a<b?a:b)

extern CSL_BootcfgRegs * gpBootCfgRegs;
extern CSL_PllcRegs * gpPLLC_regs;
extern CSL_PscRegs *  gpPSC_regs;
extern CSL_MsmcRegs * gpMSMC_regs;
extern CSL_GpioRegs * gpGPIO_regs;
#if defined(DEVICE_K2L)
extern CSL_GpioRegs * gpGPIO1_regs;
#endif

extern CSL_Tetris_vbuspRegs * gpARM_regs;

extern CSL_CPINTCRegs* gpCIC_regs; 	
extern CSL_Gic400Regs* gpGIC_regs; 

extern CSL_TpccRegs*  gpEDMA_CC0_regs;
extern CSL_TpccRegs*  gpEDMA_CC1_regs;
extern CSL_TpccRegs*  gpEDMA_CC2_regs;
#ifdef CSL_EDMACC_3_REGS
extern CSL_TpccRegs*  gpEDMA_CC3_regs;
#endif
#ifdef CSL_EDMACC_4_REGS
extern CSL_TpccRegs*  gpEDMA_CC4_regs;
#endif
extern CSL_TpccRegs*  gpEDMA_CC_regs[];
extern CSL_TptcRegs * gpEDMA_TC_0_0_regs;
extern CSL_TptcRegs * gpEDMA_TC_0_1_regs;
extern CSL_TptcRegs * gpEDMA_TC_1_0_regs;
extern CSL_TptcRegs * gpEDMA_TC_1_1_regs;
extern CSL_TptcRegs * gpEDMA_TC_1_2_regs;
extern CSL_TptcRegs * gpEDMA_TC_1_3_regs;
extern CSL_TptcRegs * gpEDMA_TC_2_0_regs;
extern CSL_TptcRegs * gpEDMA_TC_2_1_regs;
extern CSL_TptcRegs * gpEDMA_TC_2_2_regs;
extern CSL_TptcRegs * gpEDMA_TC_2_3_regs;
#ifdef CSL_EDMACC_3_REGS
extern CSL_TptcRegs * gpEDMA_TC_3_0_regs;
extern CSL_TptcRegs * gpEDMA_TC_3_1_regs;
#endif
#ifdef CSL_EDMACC_4_REGS
extern CSL_TptcRegs * gpEDMA_TC_4_0_regs;
extern CSL_TptcRegs * gpEDMA_TC_4_1_regs;
extern CSL_TptcRegs * gpEDMA_TC_regs[];
#endif
extern CSL_TmrRegs * gpTimerRegs[];

/*MPU for peripherals registers and data space*/
extern CSL_MpuRegs * gpMPU_regs[];

#if (2==CSL_DDR3_PER_CNT)
/*for Device has two DDR3 interfaces*/
extern CSL_Emif4fvRegs * gpDDR3ControlRegs[CSL_DDR3_PER_CNT];
#else
/*for Device has one DDR3 interface*/
extern CSL_Emif4fvRegs * gpDDR3ControlRegs;
#endif

extern unsigned int gMain_Core_Speed_Hz; //Main core clock speed in Hz
extern unsigned int gARM_Core_Speed_Hz; //ARM core clock speed in Hz

/*Main core PLL configuration
Main core will be configured to run at ref_clock_MHz*multiplier/divisor
 Input        : float ref_clock_MHz     
                unsigned int main_PLLM: 1~4096  
                unsigned int multiplier: 1~64  
*/
extern void KeyStone_main_PLL_init (float ref_clock_MHz,
	unsigned int multiplier, unsigned int divisor);


typedef struct  {
    volatile Uint32 PLL_CTL0;
    volatile Uint32 PLL_CTL1;
}PLL_ControlRegs;

 /*****************************************************************************
 Prototype    : KeyStone_PLL_init
 Description  : Config the PLL of ARM, PA and DDR
 	target clock speed will be ref_clock_MHz/inputDivisor*multiplier/outputDivisor
 Input        : unsigned int inputDivisor  
                unsigned int multiplier  
                unsigned int outputDivisor  
  Return Value : 0 for success, other value for error
 *****************************************************************************/
extern int KeyStone_PLL_init (PLL_ControlRegs * PLL_Regs, unsigned int inputDivisor, 
	unsigned int multiplier, unsigned int outputDivisor);
	
#ifndef DEVICE_K2E
/*****************************************************************************
 Prototype    : K2_ARM_PLL_init
 Description  : Config the ARM PLL
 	target clock speed will be ref_clock_MHz/divisor*multiplier
 Input        : float ref_clock_MHz
                unsigned int multiplier: 1~4096
                unsigned int divisor: 1~64
*****************************************************************************/
extern void K2_ARM_PLL_init (float ref_clock_MHz,
	unsigned int multiplier, unsigned int divisor);
#endif

/*****************************************************************************
 Prototype    : K2_PASS_PLL_init
 Description  : Config the PASS PLL
 	target clock speed will be ref_clock_MHz/divisor*multiplier
 Input        : float ref_clock_MHz
                unsigned int multiplier: 1~4096
                unsigned int divisor: 1~64
*****************************************************************************/
extern void K2_PASS_PLL_init (float ref_clock_MHz,
	unsigned int multiplier, unsigned int divisor);
/*****************************************************************************
 Prototype    : K2_DFE_PLL_init
 Description  : Config the DFE PLL
 	target clock speed will be ref_clock_MHz/divisor*multiplier
 Input        : float ref_clock_MHz
                unsigned int multiplier: 1~4096
                unsigned int divisor: 1~64
*****************************************************************************/
extern void K2_DFE_PLL_init (float ref_clock_MHz,
	unsigned int multiplier, unsigned int divisor);

/*===============================CCNT===================================*/
extern unsigned int cycle_measure_overhead;
/*get the delay between current and prvious CCNT.
The delay must be less than 32 bit.
enable the CCNT before use this macro*/
#define CCNT_getDelay(startCCNT) 	((unsigned int)((0xFFFFFFFFl+CP15_read_CCNT())- (unsigned long long)startCCNT)+ 1)
#define CCNT_count_cycle_from(startCCNT) 	(CCNT_getDelay(startCCNT)- cycle_measure_overhead)

#define dummy_wait(loopCnt) 	{int dummyLoopIndex;	for(dummyLoopIndex=0; dummyLoopIndex<loopCnt; dummyLoopIndex++) __asm__(" ISB");}

extern void PMU_CCNT_overflow_INT_setup();

/*get 64-bit cycle count*/
extern unsigned long long get_64_bit_cycle_count();

/*delay in millisecond*/
extern void delay_ms(Uint32 ms);

/*delay in microsecond*/
extern void delay_us(Uint32 us);

/*============================Chip level Timer==============================*/
typedef enum
{
	TIMER_ONE_SHOT_PULSE = 0, 	/*generate one shot pulse with timer*/
	TIMER_PERIODIC_PULSE, 	/*generate periodic pulse with timer*/
	TIMER_PERIODIC_CLOCK, 	/*generate periodic clock with timer*/
	/*generate periodic square wave with period reload feature, the difference 
	between wave and clock is the duty cycle of clock is always 50%*/
	TIMER_PERIODIC_WAVE, 	
	TIMER_WATCH_DOG 		/*configure timer as watch dog*/
}TTimerMode;

typedef struct  {
	int timer_num; 				/*select one timer*/
	TTimerMode timerMode; 		/*select function of the timer*/
	unsigned long long period; 	/*in the unit of Main core clock/6*/
	unsigned long long reload_period; 	/*the reload value of period*/
	int pulseWidth; 			/*pulse width between 0~3*/	
}Timer64_Config;

extern void	Reset_Timer(int timer_num);

/*Initailize a 64-bit timer*/
extern void Timer64_Init(Timer64_Config * tmrCfg);

typedef enum
{
	WD_OUT_NONE = 0,
	WD_RESET_DEVICE = 2,
#ifdef DEVICE_K2L
	WD_TRIGGER_GIC = 3,
#else
	WD_TRIGGER_GIC = 4,
#endif
	WD_RESET_DEVICE_AFTER_GIC = 5
}TWatchdogOutputMode_ARM;

/*write sequence of a A5C6h followed by a DA7Eh 
to services the watchdog timer.*/
extern void Service_Watchdog(int timer_num);

/*===============================PSC===================================*/
typedef struct  {
    volatile Uint32 PTCMD;
    volatile Uint32 PDSTAT;
    volatile Uint32 PDCTL;
}K2_ARM_LPSC_Regs;

extern Int32 KeyStone_enable_PSC_module (Uint32 pwrDmnNum, Uint32 moduleNum);
extern Int32 KeyStone_disable_PSC_module (Uint32 pwrDmnNum, Uint32 moduleNum);
extern Int32 KeyStone_disable_PSC_Power_Domain (Uint32 pwrDmnNum);

/*enable one ARM core through LPSC*/
extern void K2_ARM_LPSC_eanble(Uint32 uiCoreNum);

//declare the entry function implemented in assembly code
extern void Entry(void);
/*============================EDMA=====================================*/
//enum to indicate the EDMA CC number (higher 16-bit), and channel number(lower 16-bit)
typedef enum
{
	EDMA_CC0_CH0 = ((0<<16)|0 ),
	EDMA_CC0_CH1 = ((0<<16)|1 ),
	EDMA_CC0_CH2 = ((0<<16)|2 ),
	EDMA_CC0_CH3 = ((0<<16)|3 ),
	EDMA_CC0_CH4 = ((0<<16)|4 ),
	EDMA_CC0_CH5 = ((0<<16)|5 ),
	EDMA_CC0_CH6 = ((0<<16)|6 ),
	EDMA_CC0_CH7 = ((0<<16)|7 ),
	EDMA_CC0_CH8 = ((0<<16)|8 ),
	EDMA_CC0_CH9 = ((0<<16)|9 ),
	EDMA_CC0_CH10= ((0<<16)|10),
	EDMA_CC0_CH11= ((0<<16)|11),
	EDMA_CC0_CH12= ((0<<16)|12),
	EDMA_CC0_CH13= ((0<<16)|13),
	EDMA_CC0_CH14= ((0<<16)|14),
	EDMA_CC0_CH15= ((0<<16)|15),
	EDMA_CC0_CH16= ((0<<16)|16),
	EDMA_CC0_CH17= ((0<<16)|17),
	EDMA_CC0_CH18= ((0<<16)|18),
	EDMA_CC0_CH19= ((0<<16)|19),
	EDMA_CC0_CH20= ((0<<16)|20),
	EDMA_CC0_CH21= ((0<<16)|21),
	EDMA_CC0_CH22= ((0<<16)|22),
	EDMA_CC0_CH23= ((0<<16)|23),
	EDMA_CC0_CH24= ((0<<16)|24),
	EDMA_CC0_CH25= ((0<<16)|25),
	EDMA_CC0_CH26= ((0<<16)|26),
	EDMA_CC0_CH27= ((0<<16)|27),
	EDMA_CC0_CH28= ((0<<16)|28),
	EDMA_CC0_CH29= ((0<<16)|29),
	EDMA_CC0_CH30= ((0<<16)|30),
	EDMA_CC0_CH31= ((0<<16)|31),
	EDMA_CC0_CH32= ((0<<16)|32),
	EDMA_CC0_CH33= ((0<<16)|33),
	EDMA_CC0_CH34= ((0<<16)|34),
	EDMA_CC0_CH35= ((0<<16)|35),
	EDMA_CC0_CH36= ((0<<16)|36),
	EDMA_CC0_CH37= ((0<<16)|37),
	EDMA_CC0_CH38= ((0<<16)|38),
	EDMA_CC0_CH39= ((0<<16)|39),
	EDMA_CC0_CH40= ((0<<16)|40),
	EDMA_CC0_CH41= ((0<<16)|41),
	EDMA_CC0_CH42= ((0<<16)|42),
	EDMA_CC0_CH43= ((0<<16)|43),
	EDMA_CC0_CH44= ((0<<16)|44),
	EDMA_CC0_CH45= ((0<<16)|45),
	EDMA_CC0_CH46= ((0<<16)|46),
	EDMA_CC0_CH47= ((0<<16)|47),
	EDMA_CC0_CH48= ((0<<16)|48),
	EDMA_CC0_CH49= ((0<<16)|49),
	EDMA_CC0_CH50= ((0<<16)|50),
	EDMA_CC0_CH51= ((0<<16)|51),
	EDMA_CC0_CH52= ((0<<16)|52),
	EDMA_CC0_CH53= ((0<<16)|53),
	EDMA_CC0_CH54= ((0<<16)|54),
	EDMA_CC0_CH55= ((0<<16)|55),
	EDMA_CC0_CH56= ((0<<16)|56),
	EDMA_CC0_CH57= ((0<<16)|57),
	EDMA_CC0_CH58= ((0<<16)|58),
	EDMA_CC0_CH59= ((0<<16)|59),
	EDMA_CC0_CH60= ((0<<16)|60),
	EDMA_CC0_CH61= ((0<<16)|61),
	EDMA_CC0_CH62= ((0<<16)|62),
	EDMA_CC0_CH63= ((0<<16)|63),

	EDMA_CC1_CH0 = ((1<<16)|0 ),
	EDMA_CC1_CH1 = ((1<<16)|1 ),
	EDMA_CC1_CH2 = ((1<<16)|2 ),
	EDMA_CC1_CH3 = ((1<<16)|3 ),
	EDMA_CC1_CH4 = ((1<<16)|4 ),
	EDMA_CC1_CH5 = ((1<<16)|5 ),
	EDMA_CC1_CH6 = ((1<<16)|6 ),
	EDMA_CC1_CH7 = ((1<<16)|7 ),
	EDMA_CC1_CH8 = ((1<<16)|8 ),
	EDMA_CC1_CH9 = ((1<<16)|9 ),
	EDMA_CC1_CH10= ((1<<16)|10),
	EDMA_CC1_CH11= ((1<<16)|11),
	EDMA_CC1_CH12= ((1<<16)|12),
	EDMA_CC1_CH13= ((1<<16)|13),
	EDMA_CC1_CH14= ((1<<16)|14),
	EDMA_CC1_CH15= ((1<<16)|15),
	EDMA_CC1_CH16= ((1<<16)|16),
	EDMA_CC1_CH17= ((1<<16)|17),
	EDMA_CC1_CH18= ((1<<16)|18),
	EDMA_CC1_CH19= ((1<<16)|19),
	EDMA_CC1_CH20= ((1<<16)|20),
	EDMA_CC1_CH21= ((1<<16)|21),
	EDMA_CC1_CH22= ((1<<16)|22),
	EDMA_CC1_CH23= ((1<<16)|23),
	EDMA_CC1_CH24= ((1<<16)|24),
	EDMA_CC1_CH25= ((1<<16)|25),
	EDMA_CC1_CH26= ((1<<16)|26),
	EDMA_CC1_CH27= ((1<<16)|27),
	EDMA_CC1_CH28= ((1<<16)|28),
	EDMA_CC1_CH29= ((1<<16)|29),
	EDMA_CC1_CH30= ((1<<16)|30),
	EDMA_CC1_CH31= ((1<<16)|31),
	EDMA_CC1_CH32= ((1<<16)|32),
	EDMA_CC1_CH33= ((1<<16)|33),
	EDMA_CC1_CH34= ((1<<16)|34),
	EDMA_CC1_CH35= ((1<<16)|35),
	EDMA_CC1_CH36= ((1<<16)|36),
	EDMA_CC1_CH37= ((1<<16)|37),
	EDMA_CC1_CH38= ((1<<16)|38),
	EDMA_CC1_CH39= ((1<<16)|39),
	EDMA_CC1_CH40= ((1<<16)|40),
	EDMA_CC1_CH41= ((1<<16)|41),
	EDMA_CC1_CH42= ((1<<16)|42),
	EDMA_CC1_CH43= ((1<<16)|43),
	EDMA_CC1_CH44= ((1<<16)|44),
	EDMA_CC1_CH45= ((1<<16)|45),
	EDMA_CC1_CH46= ((1<<16)|46),
	EDMA_CC1_CH47= ((1<<16)|47),
	EDMA_CC1_CH48= ((1<<16)|48),
	EDMA_CC1_CH49= ((1<<16)|49),
	EDMA_CC1_CH50= ((1<<16)|50),
	EDMA_CC1_CH51= ((1<<16)|51),
	EDMA_CC1_CH52= ((1<<16)|52),
	EDMA_CC1_CH53= ((1<<16)|53),
	EDMA_CC1_CH54= ((1<<16)|54),
	EDMA_CC1_CH55= ((1<<16)|55),
	EDMA_CC1_CH56= ((1<<16)|56),
	EDMA_CC1_CH57= ((1<<16)|57),
	EDMA_CC1_CH58= ((1<<16)|58),
	EDMA_CC1_CH59= ((1<<16)|59),
	EDMA_CC1_CH60= ((1<<16)|60),
	EDMA_CC1_CH61= ((1<<16)|61),
	EDMA_CC1_CH62= ((1<<16)|62),
	EDMA_CC1_CH63= ((1<<16)|63),

	EDMA_CC2_CH0 = ((2<<16)|0 ),
	EDMA_CC2_CH1 = ((2<<16)|1 ),
	EDMA_CC2_CH2 = ((2<<16)|2 ),
	EDMA_CC2_CH3 = ((2<<16)|3 ),
	EDMA_CC2_CH4 = ((2<<16)|4 ),
	EDMA_CC2_CH5 = ((2<<16)|5 ),
	EDMA_CC2_CH6 = ((2<<16)|6 ),
	EDMA_CC2_CH7 = ((2<<16)|7 ),
	EDMA_CC2_CH8 = ((2<<16)|8 ),
	EDMA_CC2_CH9 = ((2<<16)|9 ),
	EDMA_CC2_CH10= ((2<<16)|10),
	EDMA_CC2_CH11= ((2<<16)|11),
	EDMA_CC2_CH12= ((2<<16)|12),
	EDMA_CC2_CH13= ((2<<16)|13),
	EDMA_CC2_CH14= ((2<<16)|14),
	EDMA_CC2_CH15= ((2<<16)|15),
	EDMA_CC2_CH16= ((2<<16)|16),
	EDMA_CC2_CH17= ((2<<16)|17),
	EDMA_CC2_CH18= ((2<<16)|18),
	EDMA_CC2_CH19= ((2<<16)|19),
	EDMA_CC2_CH20= ((2<<16)|20),
	EDMA_CC2_CH21= ((2<<16)|21),
	EDMA_CC2_CH22= ((2<<16)|22),
	EDMA_CC2_CH23= ((2<<16)|23),
	EDMA_CC2_CH24= ((2<<16)|24),
	EDMA_CC2_CH25= ((2<<16)|25),
	EDMA_CC2_CH26= ((2<<16)|26),
	EDMA_CC2_CH27= ((2<<16)|27),
	EDMA_CC2_CH28= ((2<<16)|28),
	EDMA_CC2_CH29= ((2<<16)|29),
	EDMA_CC2_CH30= ((2<<16)|30),
	EDMA_CC2_CH31= ((2<<16)|31),
	EDMA_CC2_CH32= ((2<<16)|32),
	EDMA_CC2_CH33= ((2<<16)|33),
	EDMA_CC2_CH34= ((2<<16)|34),
	EDMA_CC2_CH35= ((2<<16)|35),
	EDMA_CC2_CH36= ((2<<16)|36),
	EDMA_CC2_CH37= ((2<<16)|37),
	EDMA_CC2_CH38= ((2<<16)|38),
	EDMA_CC2_CH39= ((2<<16)|39),
	EDMA_CC2_CH40= ((2<<16)|40),
	EDMA_CC2_CH41= ((2<<16)|41),
	EDMA_CC2_CH42= ((2<<16)|42),
	EDMA_CC2_CH43= ((2<<16)|43),
	EDMA_CC2_CH44= ((2<<16)|44),
	EDMA_CC2_CH45= ((2<<16)|45),
	EDMA_CC2_CH46= ((2<<16)|46),
	EDMA_CC2_CH47= ((2<<16)|47),
	EDMA_CC2_CH48= ((2<<16)|48),
	EDMA_CC2_CH49= ((2<<16)|49),
	EDMA_CC2_CH50= ((2<<16)|50),
	EDMA_CC2_CH51= ((2<<16)|51),
	EDMA_CC2_CH52= ((2<<16)|52),
	EDMA_CC2_CH53= ((2<<16)|53),
	EDMA_CC2_CH54= ((2<<16)|54),
	EDMA_CC2_CH55= ((2<<16)|55),
	EDMA_CC2_CH56= ((2<<16)|56),
	EDMA_CC2_CH57= ((2<<16)|57),
	EDMA_CC2_CH58= ((2<<16)|58),
	EDMA_CC2_CH59= ((2<<16)|59),
	EDMA_CC2_CH60= ((2<<16)|60),
	EDMA_CC2_CH61= ((2<<16)|61),
	EDMA_CC2_CH62= ((2<<16)|62),
	EDMA_CC2_CH63= ((2<<16)|63),

	EDMA_CC3_CH0 = ((3<<16)|0 ),
	EDMA_CC3_CH1 = ((3<<16)|1 ),
	EDMA_CC3_CH2 = ((3<<16)|2 ),
	EDMA_CC3_CH3 = ((3<<16)|3 ),
	EDMA_CC3_CH4 = ((3<<16)|4 ),
	EDMA_CC3_CH5 = ((3<<16)|5 ),
	EDMA_CC3_CH6 = ((3<<16)|6 ),
	EDMA_CC3_CH7 = ((3<<16)|7 ),
	EDMA_CC3_CH8 = ((3<<16)|8 ),
	EDMA_CC3_CH9 = ((3<<16)|9 ),
	EDMA_CC3_CH10= ((3<<16)|10),
	EDMA_CC3_CH11= ((3<<16)|11),
	EDMA_CC3_CH12= ((3<<16)|12),
	EDMA_CC3_CH13= ((3<<16)|13),
	EDMA_CC3_CH14= ((3<<16)|14),
	EDMA_CC3_CH15= ((3<<16)|15),
	EDMA_CC3_CH16= ((3<<16)|16),
	EDMA_CC3_CH17= ((3<<16)|17),
	EDMA_CC3_CH18= ((3<<16)|18),
	EDMA_CC3_CH19= ((3<<16)|19),
	EDMA_CC3_CH20= ((3<<16)|20),
	EDMA_CC3_CH21= ((3<<16)|21),
	EDMA_CC3_CH22= ((3<<16)|22),
	EDMA_CC3_CH23= ((3<<16)|23),
	EDMA_CC3_CH24= ((3<<16)|24),
	EDMA_CC3_CH25= ((3<<16)|25),
	EDMA_CC3_CH26= ((3<<16)|26),
	EDMA_CC3_CH27= ((3<<16)|27),
	EDMA_CC3_CH28= ((3<<16)|28),
	EDMA_CC3_CH29= ((3<<16)|29),
	EDMA_CC3_CH30= ((3<<16)|30),
	EDMA_CC3_CH31= ((3<<16)|31),
	EDMA_CC3_CH32= ((3<<16)|32),
	EDMA_CC3_CH33= ((3<<16)|33),
	EDMA_CC3_CH34= ((3<<16)|34),
	EDMA_CC3_CH35= ((3<<16)|35),
	EDMA_CC3_CH36= ((3<<16)|36),
	EDMA_CC3_CH37= ((3<<16)|37),
	EDMA_CC3_CH38= ((3<<16)|38),
	EDMA_CC3_CH39= ((3<<16)|39),
	EDMA_CC3_CH40= ((3<<16)|40),
	EDMA_CC3_CH41= ((3<<16)|41),
	EDMA_CC3_CH42= ((3<<16)|42),
	EDMA_CC3_CH43= ((3<<16)|43),
	EDMA_CC3_CH44= ((3<<16)|44),
	EDMA_CC3_CH45= ((3<<16)|45),
	EDMA_CC3_CH46= ((3<<16)|46),
	EDMA_CC3_CH47= ((3<<16)|47),
	EDMA_CC3_CH48= ((3<<16)|48),
	EDMA_CC3_CH49= ((3<<16)|49),
	EDMA_CC3_CH50= ((3<<16)|50),
	EDMA_CC3_CH51= ((3<<16)|51),
	EDMA_CC3_CH52= ((3<<16)|52),
	EDMA_CC3_CH53= ((3<<16)|53),
	EDMA_CC3_CH54= ((3<<16)|54),
	EDMA_CC3_CH55= ((3<<16)|55),
	EDMA_CC3_CH56= ((3<<16)|56),
	EDMA_CC3_CH57= ((3<<16)|57),
	EDMA_CC3_CH58= ((3<<16)|58),
	EDMA_CC3_CH59= ((3<<16)|59),
	EDMA_CC3_CH60= ((3<<16)|60),
	EDMA_CC3_CH61= ((3<<16)|61),
	EDMA_CC3_CH62= ((3<<16)|62),
	EDMA_CC3_CH63= ((3<<16)|63),

	EDMA_CC4_CH0 = ((4<<16)|0 ),
	EDMA_CC4_CH1 = ((4<<16)|1 ),
	EDMA_CC4_CH2 = ((4<<16)|2 ),
	EDMA_CC4_CH3 = ((4<<16)|3 ),
	EDMA_CC4_CH4 = ((4<<16)|4 ),
	EDMA_CC4_CH5 = ((4<<16)|5 ),
	EDMA_CC4_CH6 = ((4<<16)|6 ),
	EDMA_CC4_CH7 = ((4<<16)|7 ),
	EDMA_CC4_CH8 = ((4<<16)|8 ),
	EDMA_CC4_CH9 = ((4<<16)|9 ),
	EDMA_CC4_CH10= ((4<<16)|10),
	EDMA_CC4_CH11= ((4<<16)|11),
	EDMA_CC4_CH12= ((4<<16)|12),
	EDMA_CC4_CH13= ((4<<16)|13),
	EDMA_CC4_CH14= ((4<<16)|14),
	EDMA_CC4_CH15= ((4<<16)|15),
	EDMA_CC4_CH16= ((4<<16)|16),
	EDMA_CC4_CH17= ((4<<16)|17),
	EDMA_CC4_CH18= ((4<<16)|18),
	EDMA_CC4_CH19= ((4<<16)|19),
	EDMA_CC4_CH20= ((4<<16)|20),
	EDMA_CC4_CH21= ((4<<16)|21),
	EDMA_CC4_CH22= ((4<<16)|22),
	EDMA_CC4_CH23= ((4<<16)|23),
	EDMA_CC4_CH24= ((4<<16)|24),
	EDMA_CC4_CH25= ((4<<16)|25),
	EDMA_CC4_CH26= ((4<<16)|26),
	EDMA_CC4_CH27= ((4<<16)|27),
	EDMA_CC4_CH28= ((4<<16)|28),
	EDMA_CC4_CH29= ((4<<16)|29),
	EDMA_CC4_CH30= ((4<<16)|30),
	EDMA_CC4_CH31= ((4<<16)|31),
	EDMA_CC4_CH32= ((4<<16)|32),
	EDMA_CC4_CH33= ((4<<16)|33),
	EDMA_CC4_CH34= ((4<<16)|34),
	EDMA_CC4_CH35= ((4<<16)|35),
	EDMA_CC4_CH36= ((4<<16)|36),
	EDMA_CC4_CH37= ((4<<16)|37),
	EDMA_CC4_CH38= ((4<<16)|38),
	EDMA_CC4_CH39= ((4<<16)|39),
	EDMA_CC4_CH40= ((4<<16)|40),
	EDMA_CC4_CH41= ((4<<16)|41),
	EDMA_CC4_CH42= ((4<<16)|42),
	EDMA_CC4_CH43= ((4<<16)|43),
	EDMA_CC4_CH44= ((4<<16)|44),
	EDMA_CC4_CH45= ((4<<16)|45),
	EDMA_CC4_CH46= ((4<<16)|46),
	EDMA_CC4_CH47= ((4<<16)|47),
	EDMA_CC4_CH48= ((4<<16)|48),
	EDMA_CC4_CH49= ((4<<16)|49),
	EDMA_CC4_CH50= ((4<<16)|50),
	EDMA_CC4_CH51= ((4<<16)|51),
	EDMA_CC4_CH52= ((4<<16)|52),
	EDMA_CC4_CH53= ((4<<16)|53),
	EDMA_CC4_CH54= ((4<<16)|54),
	EDMA_CC4_CH55= ((4<<16)|55),
	EDMA_CC4_CH56= ((4<<16)|56),
	EDMA_CC4_CH57= ((4<<16)|57),
	EDMA_CC4_CH58= ((4<<16)|58),
	EDMA_CC4_CH59= ((4<<16)|59),
	EDMA_CC4_CH60= ((4<<16)|60),
	EDMA_CC4_CH61= ((4<<16)|61),
	EDMA_CC4_CH62= ((4<<16)|62),
	EDMA_CC4_CH63= ((4<<16)|63)

}EDMA_CC_Channel_Num;

typedef enum
{
	DMA_NO_WAIT= 0,	/*do not wait DMA complete*/
	DMA_WAIT 			/*wait DMA complete*/
}DMA_Wait;

/*a structure to define a EDMA channel*/
typedef struct
{
	Uint8 CC_num; 		//number of the CC for the channel
	Uint8 channel_num;
	Uint8 TC_num; 		//number of the TC used for the channel
}EDMA_CC_Chanel_TC;

/*setup uiChannel of an EDMA to use uiTC*/
extern void EDMA_channel_TC_cfg (Uint32 uiCC, 
	Uint32 uiChannel, Uint32 uiTC);
extern void EDMA_TC_priority_cfg(Uint32 uiCC, 
	Uint32 uiPri, Uint32 uiTC);
extern void EDMA_init();

extern void EDMA_event_enable(Uint32 uiCC, Uint32 uiChannel);
extern void EDMA_event_disable(Uint32 uiCC, Uint32 uiChannel);
extern void EDMA_interrupt_enable(Uint32 uiCC, Uint32 uiIntNum);
extern void EDMA_interrupt_disable(Uint32 uiCC, Uint32 uiIntNum);

/*wait the pending EDMA complete*/
extern void EDMA_wait(EDMA_CC_Channel_Num CC_channel);
extern void EDMA_copy(unsigned int srcAddr, unsigned int dstAddr, 
	unsigned int byteCount, EDMA_CC_Channel_Num CC_channel, DMA_Wait wait);
extern void EDMA_fill(unsigned int address, unsigned long long data, 
	unsigned int byteCount, EDMA_CC_Channel_Num CC_channel);

/*============================ARM MMU with long format========================*/
/*Long format memory entry alignment mask*/
//mask to get the modulo of 1G
#define MOD_1G_MASK           0x3FFFFFFF
//mask to align to 1G boundary
#define ALIGN_1G_MASK         0xC0000000
#define ALIGN_1G_LONG_MASK  0xFFC0000000ULL
//mask to get the modulo of 2M
#define MOD_2M_MASK           0x001FFFFF
//mask to align to 2M boundary
#define ALIGN_2M_MASK         0xFFE00000
#define ALIGN_2M_LONG_MASK  0xFFFFE00000ULL
//mask to get the modulo of 4K
#define MOD_4K_MASK           0x00000FFF
//mask to align to 4K boundary
#define ALIGN_4K_MASK         0xFFFFF000
#define ALIGN_4K_LONG_MASK  0xFFFFFFF000ULL

/* Long descriptor L1 & L2 Block & L3 Page Upper Memory Attribute */
#define MMU_MEM_ATTR_EXE_NEVER_SHIFT             (54)
#define MMU_MEM_ATTR_PL1_EXE_NEVER_SHIFT         (53)
#define MMU_MEM_ATTR_CONTI_HINT_SHIFT            (52)

/* Long descriptor L1 & L2 Block & L3 Page Lower Memory Attribute */
#define MMU_MEM_ATTR_NOT_GLOBAL_SHIFT            (11)
#define MMU_MEM_ATTR_ACCESS_FLAG_SHIFT           (10)
#define MMU_MEM_ATTR_SHARE_SHIFT                 (8)
#define MMU_MEM_ATTR_ACCESS_PERM_SHIFT           (6)
#define MMU_MEM_ATTR_NON_SECURE_SHIFT            (5)
#define MMU_MEM_ATTR_INDEX_SHIFT                 (2)

/* Long descriptor L1 & L2 Table Attribute */
#define MMU_TAB_ATTR_NON_SECURE_SHIFT            (63)
#define MMU_TAB_ATTR_ACCESS_PERM_SHIFT           (61)
#define MMU_TAB_ATTR_EXE_NEVER_SHIFT             (60)
#define MMU_TAB_ATTR_PL1_EXE_NEVER_SHIFT         (59)

#define MMU_MEM_ATTR_CONTI_HINT_DIS            (0)
#define MMU_MEM_ATTR_CONTI_HINT_EN             (1)
#define MMU_MEM_ATTR_ACCESS_FLAG_CLR           (0)
#define MMU_MEM_ATTR_ACCESS_FLAG_SET           (1)

/*long descriptor type*/
#define MMU_LONG_DESC_TYPE_INVALID  0
#define MMU_LONG_DESC_TYPE_BLOCK    1
#define MMU_LONG_DESC_TYPE_TABLE    3
#define MMU_LONG_DESC_TYPE_PAGE     3
#define MMU_LONG_DESC_TYPE_MASK     3

/*Memory global attributes, if this region is available for all processes*/
typedef enum
{
	MMU_MEM_ATTR_GLOBAL     = 0,
	MMU_MEM_ATTR_NOT_GLOBAL = 1
}MMU_Memory_Global_Attr;

/*Memory secure attributes. For memory accesses from Secure state, 
specifies whether the output address is in Secure or Non-secure memory.
For memory accesses from Non-secure state, this bit is ignored.*/
typedef enum
{
	MMU_MEM_ATTR_SECURE     = 0,
	MMU_MEM_ATTR_NON_SECURE = 1
}MMU_Memory_Secure_Attr;

/*Memory share attributes*/
typedef enum
{
	MMU_MEM_ATTR_NON_SHARE   = 0,
	MMU_MEM_ATTR_OUTER_SHARE = 2,
	MMU_MEM_ATTR_INNER_SHARE = 3
}MMU_Memory_Share_Attr;
typedef MMU_Memory_Share_Attr MMU_Table_Share_Attr;

/*Memory access permission attributes*/
typedef enum
{
	MMU_MEM_ATTR_PL1_RW = 0, /*read/write at PL1 level*/
	MMU_MEM_ATTR_RW     = 1, /*read/write at any level*/
	MMU_MEM_ATTR_PL1_RO = 2, /*read only at PL1 level*/
	MMU_MEM_ATTR_RO     = 3  /*read only at any level*/
}MMU_Memory_Access_Permission;

/*Memory execute permission attributes*/
typedef enum
{
	MMU_MEM_ATTR_X   = 0, /*eXecute at any level*/
	MMU_MEM_ATTR_PXN = 1, /*eXecute never at PL1 level*/
	MMU_MEM_ATTR_XN  = 2  /*eXecute never*/
}MMU_Memory_Exectue_Permission;

/*Memory attributes defined for MAIR register.
Please note, outer cacheable is not availible on K2 devices*/
typedef enum
{
	MMU_MEM_ATTR_STRONG_ORDER           = 0,    /*strongly ordered*/
	MMU_MEM_ATTR_DEVICE                 = 0x4,  /*device*/
	MMU_MEM_ATTR_NORMAL_NON_CACHE       = 0x44, /*normal non-cache memory*/
	MMU_MEM_ATTR_NORMAL_CACHE_RA_WT_NWA = 0x4A, /*normal, read-allocate, write-through, non-write-allocate*/
	MMU_MEM_ATTR_NORMAL_CACHE_RA_WB_NWA = 0x4E, /*normal, read-allocate, write-back, non-write-allocate*/
	MMU_MEM_ATTR_NORMAL_CACHE_RA_WB_WA  = 0xFF  /*normal, read-allocate, write-back, write-allocate*/
}MMU_Memory_Attr;

typedef enum
{
	MMU_TAB_ATTR_NON_CACHE    = 0, /*non-cache memory*/                                 
	MMU_TAB_ATTR_CACHE_WB_WA  = 1, /*write-back, write-allocate*/       
	MMU_TAB_ATTR_CACHE_WT_NWA = 2, /*write-through, non-write-allocate*/
	MMU_TAB_ATTR_CACHE_WB_NWA = 3  /*write-back, non-write-allocate*/   
}MMU_Table_Cache_Attr;

/*a memory segment in virtual address space*/
typedef struct
{
    Uint32 uiStartAddress;
    Uint32 uiByteCnt;
}MMU_Memory_Segment;

/*a memory range need be setup in translation table*/
typedef struct
{
    Uint32                        uiVirtualAddress;
    unsigned long long            ullPhysicalAddress;
    Uint32                        uiByteCnt;
    MMU_Memory_Attr               attribute; //memory type and cache attribute
    MMU_Memory_Access_Permission  accessPermission; //read/write permission
    MMU_Memory_Exectue_Permission exectuePermission;
    MMU_Memory_Share_Attr         shareAttr;
    MMU_Memory_Global_Attr        isGlobal; //is global region?
    MMU_Memory_Secure_Attr        isSecure; //use secure memory in secure state?
}MMU_Memory_Map_Range;

typedef struct
{
	MMU_Memory_Map_Range *memory_map; //array of memory ranges need be setup in translation table
	Uint32               uiNumMemMapRanges; //number of the ranges of the memory map
	/*First and second level MMU translation tables are allocated statically in this driver.
	If the "memory_map[]" includes ranges less than 2MB, then third level table 
	entry will be saved into "ullpMMU3rdLevelTT", and linked to the second level table;
	if all ranges are multiple of 2MB, then, NULL can be assigned for "ullpMMU3rdLevelTT".
	Please note, "MMU3rdLevelTT" must be in phsycial sapce or flat mapped space.
	Each small range will need one or two 512-entry tables depends if the range 
	aligns to 2MB boundary. The "ullpMMU3rdLevelTT" will be used sequentially for 
	multple ranges, please make sure its size is large enough for all small ranges,
	and its address is 4KB aligned.*/
	unsigned long long   (*ullpMMU3rdLevelTT)[512]; //third level MMU translation table
	Bool                 bAlignCheck; //memory access alignment check
	MMU_Table_Cache_Attr tableCacheAttr;
	MMU_Table_Share_Attr tableShareAttr;	
}MMU_Long_Format_Config;

/*first and second level MMU translation tables are allocated statically in this driver,
third level translation table should be allocation in application level if needed*/
unsigned long long gullaMMU1stLevelTT[4]; 	  	//first level MMU translation table
unsigned long long gullaMMU2ndLevelTT[4][512]; 	//second level MMU translation tables

/*initialize long format MMU table according to "MMU_cfg".*/
extern void MMU_long_format_init(MMU_Long_Format_Config * MMU_cfg);

/*======================device level memory protection========================*/
/*Memory Protection access permision mask*/
#define MP_NONE 0
#define MP_UX 	(1<<0) 
#define MP_UW 	(1<<1) 
#define MP_UR 	(1<<2) 
#define MP_SX 	(1<<3) 
#define MP_SW 	(1<<4) 
#define MP_SR 	(1<<5) 

/*for peripheral MPU only*/
#define MP_NS   (1<<7)
#define MP_EMU  (1<<6)

/*Memory Protection mask for enabling AIDs*/
#define MP_LOCAL    (1<<8)
#define MP_AIDX     (1<<9)
#define MP_AID0     (1<<10)
#define MP_AID1     (1<<11)
#define MP_AID2     (1<<12)
#define MP_AID3     (1<<13)
#define MP_AID4     (1<<14)
#define MP_AID5     (1<<15)
#define MP_AID0_5   0xFC00

/*for peripheral MPU only*/
#define MP_AID6     (1<<16)
#define MP_AID7     (1<<17)
#define MP_AID8     (1<<18)
#define MP_AID9     (1<<19)
#define MP_AID10    (1<<20)
#define MP_AID11    (1<<21)
#define MP_AID12    (1<<22)
#define MP_AID13    (1<<23)
#define MP_AID14    (1<<24)
#define MP_AID15    (1<<25)
#define MP_AID0_15  0x03FFFC00
#define MP_AID0_7   0x0003FC00
#define MP_AID0_8   0x0007FC00
#define MP_AID8_15  0x03FC0000
#define MP_AID9_15  0x03F80000
#define MPU_DENY_ALL 	(MP_AID0_15|MP_NONE)

#define MAX_AID_NUM 	16

typedef enum
{
	PRIVID_C66_COREPAC0    = 0,
	PRIVID_C66_COREPAC1    = 1,
	PRIVID_C66_COREPAC2    = 2,
	PRIVID_C66_COREPAC3    = 3,
	PRIVID_C66_COREPAC4    = 4,
	PRIVID_C66_COREPAC5    = 5,
	PRIVID_C66_COREPAC6    = 6,
	PRIVID_C66_COREPAC7    = 7,
	PRIVID_ARM_COREPAC     = 8, 
	PRIVID_PKTDMA_SRIO_USB = 9,
	PRIVID_QM_SECOND       = 10,
	PRIVID_PCIE            = 11,	
	PRIVID_DEBUG           = 12,	
#ifdef DEVICE_K2E
	PRIVID_PCIE1 = 13,	
#else
	PRIVID_RAC_TAC_BCP_DIO = 13,	
#endif
#ifdef DEVICE_K2L
	PRIVID_PCIE1 = 14,	
#else
	PRIVID_HYPERLINK       = 14,	
#endif
#ifdef DEVICE_K2E
	PRIVID_TSIP = 15	
#else
	PRIVID_RESERVED        = 15	
#endif
}K2_PrivID;

#define MSMC_MPAXH_US_SHIFT 	7
#define MSMC_MPAXH_US_MASK 		(1<<7)

typedef enum
{
	MSMC_SHARE= 0,
	MSMC_UNSHARE= 1
}K2_MSMC_Share;   

/* Register Overlay Structure MPAX*/
typedef struct
{
    volatile Uint32 MPAXL;
    volatile Uint32 MPAXH;
}MPAX_Regs;

/*memory protection and address extension configuration*/
typedef struct
{
    Uint32 BADDR; 	/*32-bit virtual base address*/
    /*36-bit physical replace address, right shift by 4 to get the value here)*/
    Uint32 RADDR; 
    Uint32 SegementSize; 	/*Segment size in byte, must be power of 2*/
	K2_MSMC_Share share;		/*This memory page is not shared?*/
    Uint32 AccessPermisionMask; 	/*Access types allowed in this address range.*/
}MPAX_Config;

/*delete one MPAX segment*/
extern void KeyStone_SES_MPAX_seg_delete(Uint32 segNum, Uint32 PrivID);
extern void KeyStone_SMS_MPAX_seg_delete(Uint32 segNum, Uint32 PrivID);
/*configure one MPAX segment*/
extern void KeyStone_MPAX_seg_setup(MPAX_Regs * MPAX_regs, Uint32 BADDR, 
	Uint32 RADDR, Uint32 SegementSize, K2_MSMC_Share share, Uint32 AccessPermisionMask);

/*configure multiple MPAX segments in SMS of MSMC with a configuration table*/
extern void KeyStone_SMS_MPAX_setup(MPAX_Config MPAX_cfg[], 
	Uint32 firstSeg, Uint32 numSegs, Uint32 PrivID);
	
/*configure multiple MPAX segments in SES of MSMC with a configuration table*/
extern void KeyStone_SES_MPAX_setup(MPAX_Config MPAX_cfg[], 
	Uint32 firstSeg, Uint32 numSegs, Uint32 PrivID);
	
/*Enable MSMC Memory protection error interrupt for all PrivIDs*/
extern void KeyStone_MSMC_MP_interrupt_en();

/*Initialize SMS MPAX for SOC DMA access MSMC RAM*/
extern void K2_SMS_MPAX_init(K2_PrivID privID, K2_MSMC_Share share);

/*==========Peripherals registers and internal data buffer MPU=============*/
/*peripherals memory protection unit configuration*/
typedef struct
{
    Uint32 StartAddr; 	            /*32-bit start address*/
    Uint32 EndAddr;                 /*32-bit end address*/
    Uint32 AccessPermisionMask; 	/*Access types allowed in this address range.*/
}MPU_Range_Config;

typedef struct
{
    Uint32 StartAddr; 	            /*32-bit start address*/
    Uint32 EndAddr;                 /*32-bit end address*/
}MPU_Addr;

extern CSL_MpuRegs * gpMPU_regs[];

/*configure one range in peripheral MPU*/
extern void KeyStone_MPU_range_setup(CSL_MpuProg_regionRegs *MPPA_regs, 
	Uint32 uiStartAddress, Uint32 uiEndAddress, Uint32 AccessPermisionMask);

/*peripherals MPU ranges configuration*/
extern void KeyStone_MPU_setup(Uint32 uiMPU_num, 
	MPU_Range_Config MPU_cfg[], Uint32 numRangeCfg);

/*search the range which match a address and then modify
the access permission of that range.*/
extern void KeyStone_MPU_MPPA_modify(Uint32 uiMPU_num, 
	Uint32 uiAddress, Uint32 AccessPermisionMask);

/* enable the all MPU interrupts */
extern void KeyStone_MPU_interrupts_enable();

/*================internal shared memory EDC============================*/
/*Enable MSMC EDC and setup scrubbing cycle counter*/
extern void KeyStone_MSMC_RAM_EDC_enable(Uint32 scrubCnt);

/*Enable MSMC EDC error interrupt*/
extern void KeyStone_MSMC_RAM_EDC_interrupt_en();

/*MSMC_RAM EDC error handler*/
extern void KeyStone_MSMC_RAM_EDC_handler();

/*===============================Exception=============================*/
/*some exception events routed from CIC to GIC,
all these events are routed to one input of GIC*/
extern Uint32 gCIC_EXC_out_num; 	//CIC output event number for exceptions

/* Config the system error and exception.
If bGlobalExceptionMaster==TRUE, the global exception events 
from CIC will be routed to exception model of this CPU core.
Call this function as last step after all configuration/initialization complete*/
extern void KeyStone_Exception_cfg(Bool bGlobalExceptionMaster);

/*===================interrupt handling based on GIC-400=====================*/
#define MAX_GIC_SGIS               16
#define NUM_GIC_INTERRUPTS         512   // 32 PPIs + 480 SPIs

#define GIC400_PPI_LEGACY_IRQ                  31
#define GIC400_PPI_NON_SECURE_PHYSICAL_TIMER   30
#define GIC400_PPI_SECURE_PHYSICAL_TIMER       29
#define GIC400_PPI_LEGACY_FIQ_SIGNAL           28
#define GIC400_PPI_VIRTUAL_TIMER               27
#define GIC400_PPI_HYPERVISOR_TIMER            26
#define GIC400_PPI_VIRTUAL_MAINTENANCE         25

#define GIC_CTLR_FIQEN_SHIFT                (3)
#define GIC_CTLR_ENABLEGRP1_SHIFT           (1)
#define GIC_CTLR_ENABLEGRP0_SHIFT           (0)
#define GIC_CTLR_FIQEN_MASK                 (8)
#define GIC_CTLR_ENABLEGRP1_MASK            (2)
#define GIC_CTLR_ENABLEGRP0_MASK            (1)

/*convert SPI ID to GIC interrupt ID: GIC ID = SPI ID +32.
For example SPI 0 is GIC ID 32*/
#define GIC_CONVERT_SPI_ID(x)  ((x)+32)

//Get INT ID and source ID from IAR value
#define GIC_GET_INT_ID(x) (((x) & CSL_GIC400_GICC_IAR_ACKINTID_MASK) >>\
                                CSL_GIC400_GICC_IAR_ACKINTID_SHIFT)
#define GIC_GET_SRC_ID(x) (((x) & CSL_GIC400_GICC_IAR_CPUID_MASK) >>\
                                   CSL_GIC400_GICC_IAR_CPUID_SHIFT)

/*-------------------------------------------------------------------------*//**
 * @TYPE         INTH_Handler_t
 *
 * @BRIEF        function pointer to interrupt handlers
 *
 * @DESCRIPTION  A function pointer to interrupt handlers. The functions should
 *               be defined in the following format:
 *
 *               void INT_xxx_Handler(Uint32 uiIAR_value, Uint32 uiIntAddress);
 *               uiIAR_value: the value of IAR register
 *               uiIntAddress: the PC address when the interrupt happens
 *//*------------------------------------------------------------------------ */
typedef void (*INT_Handler_t)(Uint32, Uint32);

typedef enum GIC_SGI_Target_Mode
{
    TARGET_CPUS_LIST = 0x0,
    TARGET_ALL_EXCEPT_SELF,         // Excludes Self
    TARGET_ONLY_SELF,
    TARGET_KIND_MAX
}GIC_SGI_Target_Mode_t;

/*only 32 priority level is supported by GIC-400,
that is, only the highest 5 bit of prioiry value are used.
Please note, lowest priority value means highest priority*/
#define MAX_GIC400_PRIORITY_LEVELS    32
typedef enum
{
	GIC400_PRIORITY_0_OF_32  = (0 <<3),
	GIC400_PRIORITY_1_OF_32  = (1 <<3),
	GIC400_PRIORITY_2_OF_32  = (2 <<3),
	GIC400_PRIORITY_3_OF_32  = (3 <<3),
	GIC400_PRIORITY_4_OF_32  = (4 <<3),
	GIC400_PRIORITY_5_OF_32  = (5 <<3),
	GIC400_PRIORITY_6_OF_32  = (6 <<3),
	GIC400_PRIORITY_7_OF_32  = (7 <<3),
	GIC400_PRIORITY_8_OF_32  = (8 <<3),
	GIC400_PRIORITY_9_OF_32  = (9 <<3),
	GIC400_PRIORITY_10_OF_32 = (10<<3),
	GIC400_PRIORITY_11_OF_32 = (11<<3),
	GIC400_PRIORITY_12_OF_32 = (12<<3),
	GIC400_PRIORITY_13_OF_32 = (13<<3),
	GIC400_PRIORITY_14_OF_32 = (14<<3),
	GIC400_PRIORITY_15_OF_32 = (15<<3),
	GIC400_PRIORITY_16_OF_32 = (16<<3),
	GIC400_PRIORITY_17_OF_32 = (17<<3),
	GIC400_PRIORITY_18_OF_32 = (18<<3),
	GIC400_PRIORITY_19_OF_32 = (19<<3),
	GIC400_PRIORITY_20_OF_32 = (20<<3),
	GIC400_PRIORITY_21_OF_32 = (21<<3),
	GIC400_PRIORITY_22_OF_32 = (22<<3),
	GIC400_PRIORITY_23_OF_32 = (23<<3),
	GIC400_PRIORITY_24_OF_32 = (24<<3),
	GIC400_PRIORITY_25_OF_32 = (25<<3),
	GIC400_PRIORITY_26_OF_32 = (26<<3),
	GIC400_PRIORITY_27_OF_32 = (27<<3),
	GIC400_PRIORITY_28_OF_32 = (28<<3),
	GIC400_PRIORITY_29_OF_32 = (29<<3),
	GIC400_PRIORITY_30_OF_32 = (30<<3),
	GIC400_PRIORITY_31_OF_32 = (31<<3)
}GIC_Priority;

/*Please note, lowest priority vale means highest priority*/
#define GIC400_PRIORITY_HIGHEST GIC400_PRIORITY_0_OF_32
#define GIC400_PRIORITY_HIGHER  GIC400_PRIORITY_8_OF_32
#define GIC400_PRIORITY_MIDDLE  GIC400_PRIORITY_16_OF_32
#define GIC400_PRIORITY_LOWER   GIC400_PRIORITY_24_OF_32
#define GIC400_PRIORITY_LOWEST  GIC400_PRIORITY_30_OF_32
#define GIC400_PRIORITY_MASK  	GIC400_PRIORITY_31_OF_32

/*trigger type of GIC interrupt*/
typedef enum
{
	GIC_TRIGGER_TYPE_LEVEL = 0, 
	GIC_TRIGGER_TYPE_EDGE  = 2 
}GIC_Trigger_Type;

/*configuration parameters for GIC*/
typedef	struct{
	Bool bEnableGrp0;
	Bool bEnableGrp1;
	Bool bEnableFIQ; //Group 0 map to FIQ instead of IRQ?
} GIC_Config;

/*configuration parameters for one GIC interrupt*/
typedef	struct{
	Uint8 ucGroupNum; 	//group this interrupt belong to
	Uint8 ucPriority; 	//priority of this interrupt
	GIC_Trigger_Type trigger_type;
} GIC_INT_Config;

//array of interrupt handling function pointers
extern INT_Handler_t INT_Handlers[];

/*initialize GIC global parameters*/
extern void GIC_global_init(GIC_Config * gic_cfg);
/*initialize GIC CPU inteface parameters*/
extern void GIC_CPU_init(GIC_Config * gic_cfg);

/*configure an interrupt and hook handler for it*/
extern void GIC_interrupt_hook(Uint32 uiINT_num, 
	GIC_INT_Config * int_cfg, INT_Handler_t handler);

/*mask the interrupts with priority lower or equal than the mask_priority_level.
Please note, lower priority vale means higher priority*/
extern void GIC_priority_mask(GIC_Priority mask_priority_level);

extern void GIC_interupt_enable(Uint32 uiINT_num);
extern void GIC_interupt_disable(Uint32 uiINT_num);

/*generate a software interrupt*/
extern void GIC_SGI_generate(Uint32 uiSGI_ID, 
	GIC_SGI_Target_Mode_t target_mode, Uint8 ucTargetList);

/*poll interrupt status and execute interrupt handler accordingly*/
extern void ARM_poll_interrupts();
/*================Chip-level Interrupt Controller configure==================*/
static inline unsigned int SWAP_ENDIAN(unsigned int byte_index)
{
#ifdef _BIG_ENDIAN
	return ((byte_index&0xFFFFFFFC)+(3-byte_index&3));
#else
	return byte_index;
#endif
}

static inline void KeyStone_CIC_clear_system_event(CSL_CPINTCRegs* cpIntcRegs,
	int input_event_num)
{
	volatile Uint32 dummy_value;

	/*clear input interrupts events*/
	cpIntcRegs->STATUS_CLR_INDEX_REG= input_event_num;

	/*dummy read to make sure the previous write data land into the register*/
	dummy_value= cpIntcRegs->STATUS_CLR_INDEX_REG;
}

static inline void KeyStone_CIC_disable_host_int(CSL_CPINTCRegs* cpIntcRegs,
	int host_int_num)
{
	volatile Uint32 dummy_value;

	/* Disable the host interrupt */
	cpIntcRegs->HINT_ENABLE_CLR_INDEX_REG = host_int_num;

	/*dummy read to make sure the previous write data land into the register*/
	dummy_value= cpIntcRegs->HINT_ENABLE_CLR_INDEX_REG;
}

static inline void KeyStone_CIC_enable_host_int(CSL_CPINTCRegs* cpIntcRegs,
	int host_int_num)
{
	volatile Uint32 dummy_value;

	/* Enable the host interrupt */
	cpIntcRegs->HINT_ENABLE_SET_INDEX_REG = host_int_num;

	/*dummy read to make sure the previous write data land into the register*/
	dummy_value= cpIntcRegs->HINT_ENABLE_SET_INDEX_REG;
}

static inline void KeyStone_CIC_event_map(CSL_CPINTCRegs* cpIntcRegs,
	int input_event_num, int out_num)
{
	/*Map input event to output*/
	cpIntcRegs->CH_MAP[SWAP_ENDIAN(input_event_num)]= out_num;

	/*clear input interrupts events*/
	cpIntcRegs->STATUS_CLR_INDEX_REG= input_event_num; 

	/*enable input interrupts events*/
	cpIntcRegs->ENABLE_SET_INDEX_REG= input_event_num;

	/*enable output*/
	cpIntcRegs->HINT_ENABLE_SET_INDEX_REG= out_num;
}

/*=========================other utility functions==========================*/
static inline Uint32 K2_Get_device_number()
{
	return 0;
}
/*Get device information including device type, boot mode, endian information...*/
extern void K2_get_device_info();

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

/*=====implementation of C6000 intrinsics for ARM compiler.
may be used when migrate C6000 DSP code to ARM==========*/
static const Uint32 bitcount[256] = {
  0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,     
  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,   
  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,    
  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,  
  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 
  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
};
static inline Uint32 _bitc4(Uint32 src)
{
    Uint32 a,c;

    a = src;

    c = (bitcount[(a >> 24) & 0xff] << 24) |
        (bitcount[(a >> 16) & 0xff] << 16) |
        (bitcount[(a >> 8) & 0xff] << 8) |
        bitcount[a & 0xff];
	return c;
}

static inline Uint32 _lmbd(Uint32 src1, Uint32 src2)
{
    Int32 a;
    Int32 b;
    Int32 n;

    a = src2;
    b = src1 & 0x1;
    if (b == 0) {
      a = ~a;
    }
    for (n = 0; (n < 32) && (a >= 0); n++) {
      a <<= 1;
    }
	return n;
}

#define _hill(x) ((Int32)((x) >> 32))
#define _loll(x) ((Int32)((x) >> 0 ))

#if 0
static inline unsigned long long _itoll(unsigned int src1, unsigned int src2)
{
	unsigned long long register ullData= src1;

	ullData= (ullData<<32)|src2;
	
	return ullData;
}
#else
static inline unsigned long long _itoll(unsigned int hi_32_bit, unsigned int lo_32_bit)
{
	unsigned int reg[2];

    reg[1] = hi_32_bit;
    reg[0] = lo_32_bit;
	return *(unsigned long long *)reg;
}
#endif

static inline Uint32 _dotpu4(unsigned int src1, unsigned int src2)
{
    Uint32 a,b,c,i;

    a = src1;
    b = src2;
    c = 0;
    for (i = 0; i < 4; i++) {
      c += (a & 0xff) * (b & 0xff);
      a >>= 8;
      b >>= 8;
    }
	return c;
}

static inline Uint32 _swap4(Uint32 src)
{
    Uint32 a,c;

    a = src;
    c = ((a & 0xff00ff) << 8) | ((a >> 8) & 0xff00ff);
	return c;
}

static inline Uint32 _packlh2(Uint32 src1, Uint32 src2)
{
    Uint32 a,b,c;

    a = src1 << 16;
    b = src2 >> 16;
    c = (a & 0xffff0000) | (b & 0xffff);
	return c;
}

#endif
