//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  init.c
//
//  Samsung SMDKV210 board initialization code.
//
#include <bsp.h>
#include <clkinfo.h>



#define NOT_FIXEDUP (DWORD)-1

DWORD dwOEMDrWatsonSize = 128 * 1024;//NOT_FIXEDUP;

extern UINT32 g_oalIoCtlClockSpeed;
extern void OEMSupressDebug(BOOL supress);

void Port_Init(void);
static DWORD OEMEnumExtensionDRAM(PMEMORY_SECTION pMemSections, DWORD cMemSections);

static void InitSROMC_DM9000(void); //added 2010-08-06


//------------------------------------------------------------------------------
//
//  Global:  g_oalRtcResetTime
//
//  RTC init time after a RTC reset has occured.
//
SYSTEMTIME g_oalRtcResetTime =
{
    2009,     // wYear
    7,        // wMonth
    1,        // wDayofWeek
    20,        // wDay
    12,        // wHour
    0,        // wMinute
    0,        // wSecond
    0        // wMilliseconds
};

static void InitializeINFORMSFR(void);
static void InitializeGPIO(void);
static void InitializeCLKGating(void);
static void InitializeBlockPower(void);
static void InitializeCLKSource(void);
static void InitializeDebugLED(void);
static void InitializeCLAMPStable();

//------------------------------------------------------------------------------
//
//  OEMSetMemoryAttributes
//
//  OEM function to change memory attributes that isn't supported by kernel.
//  Current implementaion only supports PAGE_WRITECOMBINE.
//
//  This function first try to use PAT, and then try MTRR if PAT isn't available.
//
//------------------------------------------------------------------------------
BOOL OEMSetMemoryAttributes (
    LPVOID pVirtAddr,       // Virtual address of region
    LPVOID pPhysAddrShifted,// PhysicalAddress >> 8 (to support up to 40 bit address)
    DWORD  cbSize,          // Size of the region
    DWORD  dwAttributes     // attributes to be set
    )
{
    if (PAGE_WRITECOMBINE != dwAttributes) {
        DEBUGMSG (1, (L"OEMSetMemoryAttributes: Only PAGE_WRITECOMBINE is supported\r\n"));
        return FALSE;
    }

    return NKVirtualSetAttributes (pVirtAddr, cbSize,
                                  0x4,                  // not cacheable, but bufferable
                                  0xC,                  // Mask of all cache related bits
                                  &dwAttributes);
}


//------------------------------------------------------------------------------
//
//  Function:  OEMInit
//
//  This is Windows CE OAL initialization function. It is called from kernel
//  after basic initialization is made.
//
void OEMInit()
{
    BOOL *bCleanBootFlag;
    BOOL *bUseOALLog;    
    DWORD *dwOALLogMask;
    volatile CMU_CLK_REG *pCMUCLKReg;
    volatile SYSTEM_CLOCK *SystemClocks;
    BSP_ARGS *pBSPArgs;
   
    pCMUCLKReg = (volatile CMU_CLK_REG*)OALPAtoVA(BASE_REG_PA_CMU_CLK, FALSE);
    pBSPArgs =  (BSP_ARGS*)IMAGE_SHARE_ARGS_UA_START;   
	OALArgsInit(pBSPArgs);


	RETAILMSG(1, (L"[OAL] InitSROMC_DM9000\r\n\n"));
	InitSROMC_DM9000();



#ifdef RTC_TICK_ERROR_COMPENSATION
    pBSPArgs->bTickCountInit = TRUE;
#endif
	bCleanBootFlag = (BOOL*) OALArgsQuery(OAL_ARGS_QUERY_CLEANBOOT);
    bUseOALLog = (BOOL*) OALArgsQuery(OAL_ARGS_QUERY_LOGMASKENABLE);
    dwOALLogMask = (DWORD*)OALArgsQuery(OAL_ARGS_QUERY_LOGMASK);
    SystemClocks = (SYSTEM_CLOCK *)OALArgsQuery(OAL_ARGS_QUERY_SYSTEMCLOCKS);
    
	OALMSG(OAL_INFO,(L"OAL Log enable : %d \r\n",*bUseOALLog));
	OALMSG(OAL_INFO,(L"OAL Log mask : %x \r\n",*dwOALLogMask));
    
    g_pOemGlobal->pfnEnumExtensionDRAM = OEMEnumExtensionDRAM;

    // Store Clock Information to BSP args
#if (S5PV210_EVT==0)    
    SystemClocks->ARM_CLK=GET_ARMCLK(pCMUCLKReg->PLL_CON.APLL_CON, pCMUCLKReg->CLK_DIV.CLK_DIV0);
    SystemClocks->HCLKMSYS_CLK=GET_HCLKMSYS(pCMUCLKReg->PLL_CON.APLL_CON, pCMUCLKReg->CLK_DIV.CLK_DIV0);
    SystemClocks->PCLKMSYS_CLK=GET_PCLKMSYS(pCMUCLKReg->PLL_CON.APLL_CON, pCMUCLKReg->CLK_DIV.CLK_DIV0);
#else    
    SystemClocks->ARM_CLK=GET_ARMCLK(pCMUCLKReg->PLL_CON.APLL_CON0, pCMUCLKReg->CLK_DIV.CLK_DIV0);
    SystemClocks->HCLKMSYS_CLK=GET_HCLKMSYS(pCMUCLKReg->PLL_CON.APLL_CON0, pCMUCLKReg->CLK_DIV.CLK_DIV0);
    SystemClocks->PCLKMSYS_CLK=GET_PCLKMSYS(pCMUCLKReg->PLL_CON.APLL_CON0, pCMUCLKReg->CLK_DIV.CLK_DIV0);
#endif    
    SystemClocks->HCLKDSYS_CLK=GET_HCLKDSYS(pCMUCLKReg->PLL_CON.MPLL_CON, pCMUCLKReg->CLK_DIV.CLK_DIV0);
    SystemClocks->PCLKDSYS_CLK=GET_PCLKDSYS(pCMUCLKReg->PLL_CON.MPLL_CON, pCMUCLKReg->CLK_DIV.CLK_DIV0);
    SystemClocks->HCLKPSYS_CLK=GET_HCLKPSYS(pCMUCLKReg->PLL_CON.MPLL_CON, pCMUCLKReg->CLK_DIV.CLK_DIV0);
    SystemClocks->PCLKPSYS_CLK=GET_PCLKPSYS(pCMUCLKReg->PLL_CON.MPLL_CON, pCMUCLKReg->CLK_DIV.CLK_DIV0);
    

    OALMSG(OAL_FUNC, (L"[OAL] ++OEMInit()\r\n"));

    OALMSG(OAL_INFO, (TEXT("\n******** System Clock Info **********\r\n")));
#if (S5PV210_EVT==0)
    OALMSG(OAL_INFO, (TEXT("[OAL] APLL_CLK    : %10d Hz\r\n"),  GET_APLLCLK(pCMUCLKReg->PLL_CON.APLL_CON)));
#else
    OALMSG(OAL_INFO, (TEXT("[OAL] APLL_CLK    : %10d Hz\r\n"),  GET_APLLCLK(pCMUCLKReg->PLL_CON.APLL_CON0)));
#endif
    OALMSG(OAL_INFO, (TEXT("[OAL] MPLL_CLK    : %10d Hz\r\n"),  GET_MPLLCLK(pCMUCLKReg->PLL_CON.MPLL_CON)));
#if (S5PV210_EVT==0)
    OALMSG(OAL_INFO, (TEXT("[OAL] EPLL_CLK    : %10d Hz\r\n"),  GET_EPLLCLK(pCMUCLKReg->PLL_CON.EPLL_CON)));
#else
    OALMSG(OAL_INFO, (TEXT("[OAL] EPLL_CLK    : %10d Hz\r\n"),  GET_EPLLCLK(pCMUCLKReg->PLL_CON.EPLL_CON0)));
#endif
    OALMSG(OAL_INFO, (TEXT("[OAL] VPLL_CLK    : %10d Hz\r\n\n"),GET_VPLLCLK(pCMUCLKReg->PLL_CON.VPLL_CON)));

    OALMSG(OAL_INFO, (TEXT("[OAL] ARM_CLK     : %10d Hz\r\n"),  SystemClocks->ARM_CLK));
    OALMSG(OAL_INFO, (TEXT("[OAL] HCLK_MSYS   : %10d Hz\r\n"),  SystemClocks->HCLKMSYS_CLK));
    OALMSG(OAL_INFO, (TEXT("[OAL] PCLK_MSYS   : %10d Hz\r\n"),  SystemClocks->PCLKMSYS_CLK));
    OALMSG(OAL_INFO, (TEXT("[OAL] HCLK_DSYS   : %10d Hz\r\n"),  SystemClocks->HCLKDSYS_CLK));
    OALMSG(OAL_INFO, (TEXT("[OAL] PCLK_DSYS   : %10d Hz\r\n"),  SystemClocks->PCLKDSYS_CLK));
    OALMSG(OAL_INFO, (TEXT("[OAL] HCLK_PSYS   : %10d Hz\r\n"),  SystemClocks->HCLKPSYS_CLK));
    OALMSG(OAL_INFO, (TEXT("[OAL] PCLK_PSYS   : %10d Hz\r\n"),  SystemClocks->PCLKPSYS_CLK));    

    OALMSG(OAL_INFO, (L"******** System Clock Info **********\r\n\n"));


    
	// Check clean boot flag in BSP Args area
	if(*bCleanBootFlag)
	{
		BOOL *bCleanSysHiveFlag = (BOOL*) OALArgsQuery(OAL_ARGS_QUERY_SYS_HIVE_CLEAN);
		BOOL *bCleanUserHiveFlag = (BOOL*) OALArgsQuery(OAL_ARGS_QUERY_USER_HIVE_CLEAN);
		BOOL *bFormatStorageFlag = (BOOL*) OALArgsQuery(OAL_ARGS_QUERY_FORMATPART);

		// Tell filesys.exe that we want a clean boot.
		NKForceCleanBoot();

		OALMSG(OAL_INFO, (TEXT("OEM:-------------------------------------------\r\n")));
		OALMSG(OAL_INFO, (TEXT("OEM: Force clean boot.\r\n")));
		OALMSG(OAL_INFO, (TEXT("OEM:-------------------------------------------\r\n")));

		*bCleanSysHiveFlag = TRUE;		// Root partition Format
		*bCleanUserHiveFlag = TRUE;
		*bFormatStorageFlag = TRUE;
	}
	else
	{
		OALMSG(OAL_INFO, (TEXT("OEM:-------------------------------------------\r\n")));
		OALMSG(OAL_INFO, (TEXT("OEM: Normal Boot!!\r\n")));
		OALMSG(OAL_INFO, (TEXT("OEM:-------------------------------------------\r\n")));
	}

	if (pBSPArgs->bNoSerialMSG)
	{
		OALMSG(OAL_INFO, (TEXT("OEM: Cutting off Serial Message in OS Mode.\r\n")));
		OALMSG(OAL_INFO, (TEXT("OEM:-------------------------------------------\r\n")));
		OEMSupressDebug(TRUE);
	}
    else
    {
        OALLogSetZones(*dwOALLogMask);
    }

   
    g_oalIoCtlClockSpeed = SystemClocks->ARM_CLK;



    OALMSG(OAL_INFO,(TEXT("[OAL] CEProcessorType = 0x%x\r\n"),CEProcessorType));

    // Set memory size for DrWatson kernel support
     if (dwOEMDrWatsonSize != NOT_FIXEDUP)
     {
            dwNKDrWatsonSize = dwOEMDrWatsonSize;      // set size of reserved memory for Watson dump
     }
    
    // Intialize optional kernel functions. (Processor Extended Feature)
    g_pOemGlobal->pfnIsProcessorFeaturePresent = (PFN_IsProcessorFeaturePresent)OALIsProcessorFeaturePresent;

    // Set OEMSetMemoryAttributes function
    g_pOemGlobal->pfnSetMemoryAttributes = (PFN_SetMemoryAttributes)OEMSetMemoryAttributes;


    //InitializeDebugLED();

   // OEMWriteDebugLED(0, 0x0);

    // Initialize INFORM SFR
    // This function should be called for CPU Identification.
    InitializeINFORMSFR();

    // Initialize Clock Source
    //
    InitializeCLKSource();

    // Initialize Clock Gating
    //
    InitializeCLKGating();

    // Initialize Block Power
    //
    InitializeBlockPower();

    // Initialize Clamp Stable Counter for Deep Idle
    InitializeCLAMPStable();

    // Initilize cache globals
    OALCacheGlobalsInit();

    OALLogSerial(
        L"DCache: %d sets, %d ways, %d line size, %d size\r\n",
        g_oalCacheInfo.L1DSetsPerWay, g_oalCacheInfo.L1DNumWays,
        g_oalCacheInfo.L1DLineSize, g_oalCacheInfo.L1DSize
    );
    OALLogSerial(
        L"ICache: %d sets, %d ways, %d line size, %d size\r\n",
        g_oalCacheInfo.L1ISetsPerWay, g_oalCacheInfo.L1INumWays,
        g_oalCacheInfo.L1ILineSize, g_oalCacheInfo.L1ISize
    );

    // Initialize Interrupts
    if (!OALIntrInit())
    {
        OALMSG(OAL_ERROR, (L"[OAL:ERR] OEMInit() : failed to initialize interrupts\r\n"));
    }

    // Initialize system clock
    OALTimerInit(RESCHED_PERIOD, OEM_COUNT_1MS, 0);

    // Make high-res Monte Carlo profiling available to the kernel
    //
    g_pOemGlobal->pfnProfileTimerEnable = OEMProfileTimerEnable;
    g_pOemGlobal->pfnProfileTimerDisable = OEMProfileTimerDisable;

    // Initialize GPIO
    //
    InitializeGPIO();



	
    // Initialize the KITL connection if required
    //
    KITLIoctl(IOCTL_KITL_STARTUP, NULL, 0, NULL, 0, NULL);

    OALMSG(OAL_FUNC, (L"[OAL] --OEMInit\r\n"));

}

// ----------------------------------------------------
#define DM9000A_Tacs    (0x0)    // 0clk
#define DM9000A_Tcos    (0x0)    // 0clk
#define DM9000A_Tacc    (0x7)    // 14clk
#define DM9000A_Tcoh    (0x0)    // 0clk
#define DM9000A_Tah     (0x0)    // 0clk
#define DM9000A_Tacp    (0x0)    // 0clk
#define DM9000A_PMC     (0x0)    // normal(1data)
static void InitializeGPIO()
{
    volatile GPIO_REG *v_pGPIOregs = (GPIO_REG *)OALPAtoVA(BASE_REG_PA_GPIO, FALSE);
    volatile SROMCON_REG *x210_srom = (SROMCON_REG *)OALPAtoVA(BASE_REG_PA_SROM, FALSE);
    x210_srom = (SROMCON_REG *)OALPAtoVA(BASE_REG_PA_SROM, FALSE);
	
    OALMSG(OAL_FUNC, (L"[OAL] ++InitializeGPIO()\r\n"));

    // TODO: What port need initialization???

	x210_srom->SROM_BW = (x210_srom->SROM_BW & ~(0xF<<4)) |
							(1<<5) | // SMC ADDR Base for Memory Bank1
							// 0 = SMC_ADDR is Half-word base address  
							// 1 = SMC_ADDR is byte base address      
							(1<<4) ; // Data bus width control for Memory Bank1 (0=8-bit, 1=16-bit)
	x210_srom->SROM_BC1 = ((DM9000A_Tacs<<28)+(DM9000A_Tcos<<24)+(DM9000A_Tacc<<16)+(DM9000A_Tcoh<<12)+(DM9000A_Tah<<8)+(DM9000A_Tacp<<4)+(DM9000A_PMC));

	RETAILMSG(0, (TEXT("x210_srom=%x\r\n"),x210_srom));
	RETAILMSG(0, (TEXT("v_pGPIOregs->GPH1.GP_CON=%x\r\n"),v_pGPIOregs->GPH1.GP_CON));
	RETAILMSG(0, (TEXT("*x210_srom->SROM_BW=%x\r\n"),(&(x210_srom->SROM_BW))));
	RETAILMSG(0, (TEXT("x210_srom->SROM_BW=%x\r\n"),x210_srom->SROM_BW));
	RETAILMSG(0, (TEXT("x210_srom->SROM_BC1=%x\r\n"),x210_srom->SROM_BC1));
	RETAILMSG(0, (TEXT("*x210_srom->SROM_BC1=%x\r\n"),(&(x210_srom->SROM_BC1))));

    OALMSG(OAL_FUNC, (L"[OAL] --InitializeGPIO()\r\n"));
}

static void InitializeINFORMSFR(void)
{
    volatile PMU_MISC_REG *pPMUMISCReg = (PMU_MISC_REG *)OALPAtoVA(BASE_REG_PA_PMU_MISC, FALSE);

    OALMSG(OAL_FUNC, (L"[OAL] ++InitializeINFORMSFR()\r\n"));

    pPMUMISCReg->MISC_REG.INFORM0 = 0xC110E001;

    OALMSG(OAL_FUNC, (L"[OAL] --InitializeINFORMSFR()\r\n"));
}

static void InitializeCLKGating(void)
{
    volatile CMU_CLK_REG *pCMUCLKReg = (CMU_CLK_REG *)OALPAtoVA(BASE_REG_PA_CMU_CLK, FALSE);

    OALMSG(OAL_FUNC, (L"[OAL] ++InitializeCLKGating()\r\n"));

    // CLK_IP0
    pCMUCLKReg->CLK_GATE.CLK_GATE_IP0 = ((CLK_OFF<<BP_CLK_IP_CSIS)         |     // all clocks for CSIS
                                         (CLK_OFF<<BP_CLK_IP_IPC)          |     // all clocks for IPC
                                         (CLK_OFF<<BP_CLK_IP_ROTATOR)      |     // all clocks for ROTATOR
                                         (CLK_OFF<<BP_CLK_IP_JPEG)         |     // all clocks for JPEG
                                         (CLK_ON<<27)                      |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_FIMC2)        |     // all clocks for FIMC2
                                         (CLK_OFF<<BP_CLK_IP_FIMC1)        |     // all clocks for FIMC1
                                         (CLK_ON<<BP_CLK_IP_FIMC0)         |     // all clocks for FIMC0
                                         (0x7f<<17)                        |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_MFC)          |     // all clocks for MFC
#if (S5PV210_EVT==0)
                                         (0x7f<<9)                         |     // Reserved
#else                                         
                                         (0x7<<13)                         |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_G2D)          |     // all clocks for G2D
                                         (0x7<<9)                          |     // Reserved
#endif                                         
                                         (CLK_OFF<<BP_CLK_IP_G3D)          |     // all clocks for 3D
                                         (0x3<<6)                          |     // Reserved
                                         (CLK_ON<<BP_CLK_IP_IMEM)          |     // all clocks for IMEM
                                         (CLK_OFF<<BP_CLK_IP_PDMA1)        |     // all clocks for PDMA1
                                         (CLK_OFF<<BP_CLK_IP_PDMA0)        |     // all clocks for PDMA0
                                         (CLK_OFF<<BP_CLK_IP_MDMA)         |     // all clocks for MDMA
                                         (CLK_ON<<BP_CLK_IP_DMC1)          |     // all clocks for DMC1
                                         (CLK_ON<<BP_CLK_IP_DMC0));         // all clocks for DMC0

    // CLK_IP1
    pCMUCLKReg->CLK_GATE.CLK_GATE_IP1 = ((0x7<<29)                         |     // Reserved 
                                         (CLK_ON<<BP_CLK_IP_NFCON)        |     // all clocks for NFCON
                                         //(CLK_OFF<<BP_CLK_IP_SROMC)        |     // all clocks for SROMC
                                         // modify for dm9000 2010-08-17
                                         (CLK_ON<<BP_CLK_IP_SROMC)        |     // all clocks for SROMC
                                         (CLK_OFF<<BP_CLK_IP_CFCON)        |     // all clocks for CFCON
                                         (CLK_ON<<BP_CLK_IP_ONENANDXL)     |     // all clocks for ONENAND-XL
                                         (0x3f<<18)                        |     // Reserved
                                         //(CLK_OFF<<BP_CLK_IP_USBHOST)      |     // all clocks for USBHOST
                                         //(CLK_OFF<<BP_CLK_IP_USBOTG)       |     // all clocks for USBOTG
                                         (CLK_ON<<BP_CLK_IP_USBHOST)      |     // all clocks for USBHOST
                                         (CLK_ON<<BP_CLK_IP_USBOTG)       |     // all clocks for USBOTG
                                         (0xf<<12)                         |     // Reserved
	                                   (CLK_ON<<BP_CLK_IP_HDMI)         |     // all clocks for HDMI
                                         (CLK_ON<<BP_CLK_IP_TVENC)        |     // all clocks for TVENC
                                         (CLK_ON<<BP_CLK_IP_MIXER)        |     // all clocks for MIXER
                                         (CLK_ON<<BP_CLK_IP_VP)           |     // all clocks for VP
                                         (0x1f<<3)                         |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_DSIM)         |     // all clocks for DSIM
                                         (CLK_OFF<<BP_CLK_IP_MIE)          |     // all clocks for MIE
                                         (CLK_ON<<BP_CLK_IP_FIMD));         // all clocks for FIMD
                                         
    // CLK_IP2
    pCMUCLKReg->CLK_GATE.CLK_GATE_IP2 = ((CLK_OFF<<BP_CLK_IP_TZIC3)        |     // all clocks for TZIC3
                                         (CLK_OFF<<BP_CLK_IP_TZIC2)        |     // all clocks for TZIC2
                                         (CLK_OFF<<BP_CLK_IP_TZIC1)        |     // all clocks for TZIC1
                                         (CLK_OFF<<BP_CLK_IP_TZIC0)        |     // all clocks for TZIC0
                                         (CLK_ON<<BP_CLK_IP_VIC3)          |     // all clocks for VIC3
                                         (CLK_ON<<BP_CLK_IP_VIC2)          |     // all clocks for VIC2
                                         (CLK_ON<<BP_CLK_IP_VIC1)          |     // all clocks for VIC1
                                         (CLK_ON<<BP_CLK_IP_VIC0)          |     // all clocks for VIC0
                                         (0x7<<21)                         |     // Reserved 
                                         (CLK_OFF<<BP_CLK_IP_TSI)          |     // all clocks for TSI
                                         (CLK_OFF<<BP_CLK_IP_MMC3)         |     // all clocks for HSMMC3
                                         (CLK_OFF<<BP_CLK_IP_MMC2)         |     // all clocks for HSMMC2
                                         (CLK_OFF<<BP_CLK_IP_MMC1)         |     // all clocks for HSMMC1
                                         (CLK_OFF<<BP_CLK_IP_MMC0)         |     // all clocks for HSMMC0
                                         (0xf<<12)                         |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_SECJTAG)      |     // all clocks for SECJTAG
                                         (CLK_OFF<<BP_CLK_IP_HOSTIF)       |     // all clocks for HOSTIF
                                         (CLK_OFF<<BP_CLK_IP_MODEM)        |     // all clocks for MODEM I/F    
                                         (CLK_ON<<BP_CLK_IP_CORESIGHT)     |     // all clocks for CORESIGHT(CSSYS) For JTAG
                                         (0x3f<<2)                         |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_SDM)          |     // all clocks for SDM                                      
                                         (CLK_ON<<BP_CLK_IP_SECSS));         // all clocks for SECSS For JTAG

    // CLK_IP3
    pCMUCLKReg->CLK_GATE.CLK_GATE_IP3 = ((1<<31)                           |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_PCM2)         |     // all clocks for PCM2
                                         (CLK_OFF<<BP_CLK_IP_PCM1)         |     // all clocks for PCM1
                                         (CLK_OFF<<BP_CLK_IP_PCM0)         |     // all clocks for PCM0
                                         (CLK_ON<<BP_CLK_IP_SYSCON)        |     // all clocks for SYSCON
                                         (CLK_ON<<BP_CLK_IP_GPIO)          |     // all clocks for GPIO
                                         (1<<25)                           |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_TSADC)        |     // all clocks for TSADC
                                         (CLK_ON<<BP_CLK_IP_PWM)           |     // all clocks for PWM
                                         (CLK_ON<<BP_CLK_IP_WDT)           |     // all clocks for WDT
                                         (CLK_OFF<<BP_CLK_IP_KEYIF)        |     // all clocks for KEYIF
                                         #if (DEBUG_PORT == DEBUG_UART3)
                                         (CLK_ON<<BP_CLK_IP_UART3)         |     // all clocks for UART3
                                         (CLK_OFF<<BP_CLK_IP_UART2)        |     // all clocks for UART2
                                         (CLK_OFF<<BP_CLK_IP_UART1)        |     // all clocks for UART1
                                         (CLK_OFF<<BP_CLK_IP_UART0)        |     // all clocks for UART0
                                         #elif (DEBUG_PORT == DEBUG_UART2)
                                         (CLK_OFF<<BP_CLK_IP_UART3)        |     // all clocks for UART3
                                         (CLK_ON<<BP_CLK_IP_UART2)         |     // all clocks for UART2
                                         (CLK_OFF<<BP_CLK_IP_UART1)        |     // all clocks for UART1
                                         (CLK_OFF<<BP_CLK_IP_UART0)        |     // all clocks for UART0
                                         #elif (DEBUG_PORT == DEBUG_UART1)
                                         (CLK_OFF<<BP_CLK_IP_UART3)        |     // all clocks for UART3
                                         (CLK_OFF<<BP_CLK_IP_UART2)        |     // all clocks for UART2
                                         (CLK_ON<<BP_CLK_IP_UART1)         |     // all clocks for UART1
                                         (CLK_OFF<<BP_CLK_IP_UART0)        |     // all clocks for UART0
                                         #elif (DEBUG_PORT == DEBUG_UART0)
                                         (CLK_OFF<<BP_CLK_IP_UART3)        |     // all clocks for UART3
                                         (CLK_OFF<<BP_CLK_IP_UART2)        |     // all clocks for UART2
                                         (CLK_OFF<<BP_CLK_IP_UART1)        |     // all clocks for UART1
                                         (CLK_ON<<BP_CLK_IP_UART0)         |     // all clocks for UART0
                                         #endif                                                                                  
                                         (CLK_ON<<BP_CLK_IP_SYSTIMER)      |     // all clocks for SYSTIMER
                                         (CLK_ON<<BP_CLK_IP_RTC)           |     // all clocks for RTC
                                         (CLK_OFF<<BP_CLK_IP_SPI2)         |     // all clocks for SPI2    
                                         (CLK_OFF<<BP_CLK_IP_SPI1)         |     // all clocks for SPI1
                                         (CLK_OFF<<BP_CLK_IP_SPI0)         |     // all clocks for SPI0  
                                         
                                        // (CLK_OFF<<BP_CLK_IP_I2C_HDMI_PHY) |     // all clocks for I2C_HDMI_PHY                                      
                                        // (CLK_OFF<<BP_CLK_IP_I2C_HDMI_DDC) |     // all clocks for I2C_HDMI_DDC    
                                        //modified  2010-08-09
						(PWR_OFF<<BP_CLK_IP_I2C_HDMI_PHY) |     // all clocks for I2C_HDMI_PHY                                      
                                         (PWR_OFF<<BP_CLK_IP_I2C_HDMI_DDC) |     // all clocks for I2C_HDMI_DDC      
                                         
                                         (CLK_OFF<<BP_CLK_IP_I2C2)         |     // all clocks for I2C2                                      
                                         (CLK_OFF<<BP_CLK_IP_I2C1)         |     // all clocks for I2C1                                      
                                         (CLK_OFF<<BP_CLK_IP_I2C0)         |     // all clocks for I2C0                                      
                                         (CLK_OFF<<BP_CLK_IP_I2S2)         |     // all clocks for I2S2                                      
                                         (CLK_OFF<<BP_CLK_IP_I2S1)         |     // all clocks for I2S1  
                                         (CLK_OFF<<BP_CLK_IP_I2S0)         |     // all clocks for I2S0  
                                         (0x3<<2)                          |     // Reserved
                                         (CLK_OFF<<BP_CLK_IP_AC97)         |     // all clocks for AC97  
                                         (CLK_OFF<<BP_CLK_IP_SPDIF));         // all clocks for SPDIF
                                           
    // CLK_IP4
    pCMUCLKReg->CLK_GATE.CLK_GATE_IP4 = ((0x7fffff<<9) |  // Reserved
                                         (CLK_ON<<BP_CLK_IP_TZPC3)         |  // all clocks for TZPC3
                                         (CLK_ON<<BP_CLK_IP_TZPC2)         |  // all clocks for TZPC2
                                         (CLK_ON<<BP_CLK_IP_TZPC1)         |  // all clocks for TZPC1
                                         (CLK_ON<<BP_CLK_IP_TZPC0)         |  // all clocks for TZPC0
                                         (0x1<<4)                            |  // Reserved
                                         (CLK_OFF<<BP_CLK_IP_SECKEY)       |  // all clocks for SECKEY
                                         (CLK_ON<<BP_CLK_IP_IEM_APC)       |  // all clocks for IEM_APC
                                         (CLK_ON<<BP_CLK_IP_IEM_IEC)       |  // all clocks for IEM_IEC
                                         (CLK_ON<<BP_CLK_IP_CHIP_ID));         // all clocks for CHIPID
   OALMSG(OAL_FUNC, (L"[OAL] --InitializeCLKGating()\r\n"));                                      
}



static void InitializeBlockPower(void)
{

    volatile PMU_PM_REG *pPMUPMReg = (PMU_PM_REG *)OALPAtoVA(BASE_REG_PA_PMU_PM, FALSE);

    OALMSG(OAL_FUNC, (L"[OAL] ++InitializeBlockPower()\r\n"));

    pPMUPMReg->PWR_CONF.NORMAL_CFG = (0x7ff<<21)                      |   // Reserved
                                     (PWR_ON<<BP_IROM_POWER_GATE)     |   // IROM On
                                     (0xfff<<8)                       |   // Reserved 
                                     (PWR_OFF<<BP_AUDIOSS_POWER_GATE) |   // Audio sub-block Off
                                     (0x1<<6)                         |   // Reserved
                                     (PWR_OFF<<BP_CAM_POWER_GATE)     |   // CAM Off
                                     (PWR_OFF<<BP_TV_POWER_GATE)      |   // TV Off
                                     (PWR_ON<<BP_LCD_POWER_GATE)      |   // LCD On
                                     (PWR_OFF<<BP_G3D_POWER_GATE)     |   // 3D Off
                                     (PWR_OFF<<BW_MFC_POWER_GATE)     |   // MFC Off
                                     (PWR_ON<<0);         // Reserved
    OALMSG(OAL_FUNC, (L"[OAL] --InitializeBlockPower()\r\n"));                                  
}

static void InitializeCLKSource(void)
{
      //TO DO
}

//Adjusting Clamp for Deep Idle
static void InitializeCLAMPStable(void)
{

    volatile PMU_PM_REG *pPMUPMRegs = (PMU_PM_REG *)OALPAtoVA(BASE_REG_PA_PMU_PM, FALSE);

    OALMSG(OAL_FUNC, (L"[OAL]++ InitializeCLAMPStable()\r\n"));

    pPMUPMRegs->STABLE_REG.CLAMP_STABLE |= ((0x348<<16)      // Clamp Off Value=0x1ff*(1/24MHz(XUSBTI))= 35us)
                                             |(0x1<<0));     // Clamp On Value = 0x1 * (1/12MHz(XXTI))= 41.6ns)
    OALMSG(OAL_FUNC, (L"[OAL]-- InitializeCLAMPStable()\r\n"));                               
}

static void InitializeDebugLED(void)
{
    static volatile GPIO_REG *g_pGPIOReg;
    
    g_pGPIOReg = (GPIO_REG *)OALPAtoVA(BASE_REG_PA_GPIO, FALSE);

    OALMSG(OAL_FUNC, (L"[OAL] ++InitializeDebugLED()\r\n")); 
    //LED6, 7, 8, 9 for SMDKV210
  //  Set_PinFunction(g_pGPIOReg, LED6);
  //  Set_PinPullUD(g_pGPIOReg, LED6, sgip_PULL_DISABLE);
 
  //  Set_PinFunction(g_pGPIOReg, LED7);
  //  Set_PinPullUD(g_pGPIOReg, LED7, sgip_PULL_DISABLE);   

//    Set_PinFunction(g_pGPIOReg, LED8);
//    Set_PinPullUD(g_pGPIOReg, LED8, sgip_PULL_DISABLE);
 
//    Set_PinFunction(g_pGPIOReg, LED9);
//    Set_PinPullUD(g_pGPIOReg, LED9, sgip_PULL_DISABLE)
   
    OALMSG(OAL_FUNC, (L"[OAL] --InitializeDebugLED()\r\n")); 
}

static DWORD OEMEnumExtensionDRAM(
  PMEMORY_SECTION pMemSections,
  DWORD cMemSections)
{
    DWORD cSections = 0;
 
    OALMSG(OAL_INFO, (L"[OAL]++OEMEnumExtensionDRAM\r\n"));
    OALMSG(OAL_INFO, (L"    cMemSections = %d \r\n",cMemSections));

    if (cSections < cMemSections)
    {


		// DRAM0 Area
        pMemSections[cSections].dwFlags = 0;
        pMemSections[cSections].dwStart = DRAM0_BASE_CA_START;  //0x88000000

        pMemSections[cSections].dwLen =  ONEDRAM_EXTSIZE_FOR_AP;
        OALMSG(OAL_INFO, (L"    DRAM0_BASE_CA_START = 0x%x \r\n",DRAM0_BASE_CA_START));
        OALMSG(OAL_INFO, (L"    pMemSections[cSections].dwStart = 0x%x \r\n",pMemSections[cSections].dwStart));
        OALMSG(OAL_INFO, (L"    Extension Size = 0x%x \r\n",pMemSections[cSections].dwLen));  

		
        //RETAILMSG(1, (L"    DRAM0_BASE_CA_START = 0x%x \r\n",DRAM0_BASE_CA_START));
        //RETAILMSG(1, (L"    pMemSections[cSections].dwStart = 0x%x \r\n",pMemSections[cSections].dwStart));
        RETAILMSG(1, (L"    Extension Size = 0x%x \r\n",pMemSections[cSections].dwLen));
	    
		cSections++;



        // Extra DRAM1 Area 0x48000000, 106MB
        pMemSections[cSections].dwFlags = 0;
        pMemSections[cSections].dwStart = DRAM_EXTRA_BASE_CA_START;  //0x99500000
        pMemSections[cSections].dwLen =  DRAM_EXTRA_SIZE;
        OALMSG(OAL_INFO, (L"    DRAM1_EXTRA_BASE_CA_START = 0x%x \r\n",DRAM_EXTRA_BASE_CA_START));
        OALMSG(OAL_INFO, (L"    pMemSections[cSections].dwStart = 0x%x \r\n",pMemSections[cSections].dwStart));
        OALMSG(OAL_INFO, (L"    Extension Size = 0x%x \r\n",pMemSections[cSections].dwLen));   
		
        //RETAILMSG(1, (L"    DRAM1_EXTRA_BASE_CA_START = 0x%x \r\n",DRAM_EXTRA_BASE_CA_START));
        //RETAILMSG(1, (L"    pMemSections[cSections].dwStart = 0x%x \r\n",pMemSections[cSections].dwStart));
		RETAILMSG(1, (L" DRAM1   Extension Size = 0x%x \r\n",pMemSections[cSections].dwLen)); 		
        cSections++;   

		
    }

    OALMSG(OAL_INFO, (L"[OAL] --OEMEnumExtensionDRAM\r\n"));
    return cSections;
}

BOOL 
OEMGetExtensionDRAM( LPDWORD lpMemStart, LPDWORD lpMemLen ) 
{
    *lpMemStart = 0x88000000;
    *lpMemLen   = 0x08000000;

    return TRUE;    
}

#define CS8900_Tacs (0x0)   // 0clk
#define CS8900_Tcos (0x4)   // 4clk
#define CS8900_Tacc (0xd)   // 14clk
#define CS8900_Tcoh (0x1)   // 1clk
#define CS8900_Tah  (0x4)   // 4clk
#define CS8900_Tacp (0x6)   // 6clk
#define CS8900_PMC  (0x0)   // normal(1data)
static void InitSROMC_DM9000(void)
{
    //volatile S5PC100_SROMCON_REG *s5pC100SROM = (S5PC100_SROMCON_REG *)OALPAtoVA(S5PC100_BASE_REG_PA_SMC, FALSE);

    volatile SROMCON_REG *x210_srom = (SROMCON_REG *)OALPAtoVA(BASE_REG_PA_SROM, FALSE);
    x210_srom->SROM_BW = (x210_srom->SROM_BW & ~(0xF<<4)) |
                            (1<<7)| // nWBE/nBE(for UB/LB) control for Memory Bank1(0=Not using UB/LB, 1=Using UB/LB)
                            (1<<6)| // Wait enable control for Memory Bank1 (0=WAIT disable, 1=WAIT enable)
                            (1<<4); // Data bus width control for Memory Bank1 (0=8-bit, 1=16-bit)

    x210_srom->SROM_BC1 = ((CS8900_Tacs<<28)+(CS8900_Tcos<<24)+(CS8900_Tacc<<16)+(CS8900_Tcoh<<12)  \
                            +(CS8900_Tah<<8)+(CS8900_Tacp<<4)+(CS8900_PMC));


	RETAILMSG(0, (TEXT("x210_srom=%x\r\n"),x210_srom));

      RETAILMSG(0, (TEXT("*x210_srom->SROM_BW=%x\r\n"),(&(x210_srom->SROM_BW))));

       RETAILMSG(0, (TEXT("x210_srom->SROM_BW=%x\r\n"),x210_srom->SROM_BW));
       RETAILMSG(0, (TEXT("x210_srom->SROM_BC1=%x\r\n"),x210_srom->SROM_BC1));
	   RETAILMSG(0, (TEXT("*x210_srom->SROM_BC1=%x\r\n"),(&(x210_srom->SROM_BC1))));
}


