/******************************************************************************
 *
 * System On Chip(SOC)
 *
 * Copyright (c) 2002 Software Center, Samsung Electronics, Inc.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of Samsung 
 * Electronics, Inc("Confidential Information"). You Shall not disclose such 
 * Confidential Information and shall use it only in accordance with the terms 
 * of the license agreement you entered into Samsung.
 *
 *-----------------------------------------------------------------------------
 *
 *	S3C2440 BSP 
 *
 * power.c   :  S3C2440 Power Management(OEMPowerOff()) Routines
 *
 *      
 ******************************************************************************
 */

#include "windows.h"
#include "nkintr.h"
#include "oalintr.h"
#include "s2440.h"
#include "drv_glob.h"

#define PRIVATE     static
#define PUBLIC      

extern void   CPUPowerOff(void);
//extern void   EmergencyCPUPowerOff(void);
extern void	  CPUPowerReset();

void Watchdog_Set(void);
void Burst_Refresh(void);
void CLR_IF();

PRIVATE DWORD CPUBackupRegs[60];

void (*gpfnKitlPowerHandler)(BOOL bOff) = NULL;


//============================================================
// Power Mnanagement Related..
#define PRIVATE     static
	PRIVATE DWORD CPUBackupRegs[60];

	PRIVATE void 
CPUSaveRegs(DWORD *p)
{
    volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
	volatile INTreg *s2440INT = (INTreg *)INT_BASE;
    volatile LCDreg *s2440LCD = (LCDreg *)LCD_BASE;    

    *p++ = s2440IOP->rGPACON;
    *p++ = s2440IOP->rGPADAT;
    *p++ = s2440IOP->rGPBCON;
    *p++ = s2440IOP->rGPBDAT;
    *p++ = s2440IOP->rGPBUP;
    *p++ = s2440IOP->rGPCCON;
    *p++ = s2440IOP->rGPCDAT;
    *p++ = s2440IOP->rGPCUP;
    *p++ = s2440IOP->rGPDCON;
    *p++ = s2440IOP->rGPDDAT;
    *p++ = s2440IOP->rGPDUP;
    *p++ = s2440IOP->rGPECON;
    *p++ = s2440IOP->rGPEDAT;
    *p++ = s2440IOP->rGPEUP;
    *p++ = s2440IOP->rGPFCON;
    *p++ = s2440IOP->rGPFDAT;
    *p++ = s2440IOP->rGPFUP;
    *p++ = s2440IOP->rGPGCON;
    *p++ = s2440IOP->rGPGDAT;
    *p++ = s2440IOP->rGPGUP;
    *p++ = s2440IOP->rGPHCON;
    *p++ = s2440IOP->rGPHDAT;
    *p++ = s2440IOP->rGPHUP;

    *p++ = s2440IOP->rMISCCR;
    *p++ = s2440IOP->rDCKCON;
    *p++ = s2440IOP->rEXTINT0;
    *p++ = s2440IOP->rEXTINT1;
    *p++ = s2440IOP->rEXTINT2;
    *p++ = s2440IOP->rEINTFLT0;
    *p++ = s2440IOP->rEINTFLT1;
    *p++ = s2440IOP->rEINTFLT2;
    *p++ = s2440IOP->rEINTFLT3;
    *p++ = s2440IOP->rEINTMASK;

    *p++ = s2440INT->rINTMOD;
    *p++ = s2440INT->rINTMSK;
    *p++ = s2440INT->rINTSUBMSK;

    *p++ = s2440LCD->rTCONSEL;
    *p++ = s2440LCD->rLCDINTMSK;
    *p++ = s2440LCD->rTPAL;
    *p++ = s2440LCD->rDITHMODE;
    *p++ = s2440LCD->rBLUELUT;
    *p++ = s2440LCD->rGREENLUT;
    *p++ = s2440LCD->rREDLUT;
    *p++ = s2440LCD->rLCDSADDR3;
    *p++ = s2440LCD->rLCDSADDR2;
    *p++ = s2440LCD->rLCDSADDR1;
    *p++ = s2440LCD->rLCDCON5;
    *p++ = s2440LCD->rLCDCON4;
    *p++ = s2440LCD->rLCDCON3;
    *p++ = s2440LCD->rLCDCON2;
    *p++ = s2440LCD->rLCDCON1;
}



	PRIVATE void 
CPULoadRegs(DWORD *p)
{
    volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
	volatile INTreg *s2440INT = (INTreg *)INT_BASE;
    volatile LCDreg *s2440LCD = (LCDreg *)LCD_BASE;    

    s2440IOP->rGPACON    =  *p++;
    s2440IOP->rGPADAT    =  *p++;
    s2440IOP->rGPBCON    =  *p++;
    s2440IOP->rGPBDAT    =  *p++;
    s2440IOP->rGPBUP     =  *p++;
    s2440IOP->rGPCCON    =  *p++;
    s2440IOP->rGPCDAT    =  *p++;
    s2440IOP->rGPCUP     =  *p++;
    s2440IOP->rGPDCON    =  *p++;
    s2440IOP->rGPDDAT    =  *p++;
    s2440IOP->rGPDUP     =  *p++;
    s2440IOP->rGPECON    =  *p++;
    s2440IOP->rGPEDAT    =  *p++;
    s2440IOP->rGPEUP     =  *p++;
    s2440IOP->rGPFCON    =  *p++;
    s2440IOP->rGPFDAT    =  *p++;
    s2440IOP->rGPFUP     =  *p++;
    s2440IOP->rGPGCON    =  *p++;
    s2440IOP->rGPGDAT    =  *p++;
    s2440IOP->rGPGUP     =  *p++;
    s2440IOP->rGPHCON    =  *p++;
    s2440IOP->rGPHDAT    =  *p++;
    s2440IOP->rGPHUP     =  *p++;
                                
    s2440IOP->rMISCCR    =  *p++;
    s2440IOP->rDCKCON    =  *p++;
    s2440IOP->rEXTINT0   =  *p++;
    s2440IOP->rEXTINT1   =  *p++;
    s2440IOP->rEXTINT2   =  *p++;
    s2440IOP->rEINTFLT0  =  *p++;
    s2440IOP->rEINTFLT1  =  *p++;
    s2440IOP->rEINTFLT2  =  *p++;
    s2440IOP->rEINTFLT3  =  *p++;
    s2440IOP->rEINTMASK  =  *p++;

    s2440INT->rINTMOD    =  *p++; 
    s2440INT->rINTMSK    =  *p++; 
    s2440INT->rINTSUBMSK =  *p++; 
                                   
    s2440LCD->rTCONSEL   =  *p++; 
    s2440LCD->rLCDINTMSK =  *p++; 
    s2440LCD->rTPAL      =  *p++; 
    s2440LCD->rDITHMODE  =  *p++; 
    s2440LCD->rBLUELUT   =  *p++; 
    s2440LCD->rGREENLUT  =  *p++; 
    s2440LCD->rREDLUT    =  *p++; 
    s2440LCD->rLCDSADDR3 =  *p++; 
    s2440LCD->rLCDSADDR2 =  *p++; 
    s2440LCD->rLCDSADDR1 =  *p++; 
    s2440LCD->rLCDCON5   =  *p++; 
    s2440LCD->rLCDCON4   =  *p++; 
    s2440LCD->rLCDCON3   =  *p++; 
    s2440LCD->rLCDCON2   =  *p++; 
    s2440LCD->rLCDCON1   =  *p++;
}

void ConfigStopGPIO(void)
{
    volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;

    // Check point
    // 1) NC pin: input pull-up on 
    // 2) If input is driver externally: input pull-up off
    // 3) If a connected component draws some current: output low.
    // 4) If a connected component draws no current: output high.
    
    //chip # = 5

    //CAUTION:Follow the configuration order for setting the ports. 
    // 1) setting value(GPnDAT) 
    // 2) setting control register  (GPnCON)
    // 3) configure pull-up resistor(GPnUP)  

    //32bit data bus configuration  
    //*** PORT A GROUP
    //Ports  : GPA22 GPA21  GPA20 GPA19 GPA18 GPA17 GPA16 GPA15 GPA14 GPA13 GPA12  
    //Signal : nFCE nRSTOUT nFRE  nFWE  ALE   CLE   nGCS5 nGCS4 nGCS3 nGCS2 nGCS1 
    //Binary : 1     1      1,    1     1     1     1,    1     1     1     1,
    //POFF   : 1     0      1,    1     0     0     1,    1     1     1     1,
    //-------------------------------------------------------------------------------------------
    //Ports  : GPA11  GPA10  GPA9   GPA8   GPA7   GPA6   GPA5   GPA4   GPA3   GPA2   GPA1   GPA0
    //Signal : ADDR26 ADDR25 ADDR24 ADDR23 ADDR22 ADDR21 ADDR20 ADDR19 ADDR18 ADDR17 ADDR16 ADDR0 
    //Binary : 1      1      1      1,     1      1      1      1,     1      1      1      1         
    //POFF   : 0      0      0      0,     0      0      0      0,     0      0      0      0
    s2440IOP->rGPACON = 0x7fffff; 

    //**** PORT B GROUP
    //Ports  : GPB10   GPB9    GPB8    GPB7    GPB6    GPB5     GPB4    GPB3   GPB2   GPB1       GPB0
    //Signal : nXDREQ0 nXDACK0 nXDREQ1 nXDACK1 nSS_KBD nDIS_OFF L3CLOCK L3DATA L3MODE nIrDATXDEN Keyboard
    //Setting: INPUT   OUTPUT  INPUT   OUTPUT  INPUT   OUT      OUT     OUT    OUT    INPUT      INPUT 
    //Binary : 00,     01      00,     01      00,     01       01,     01     01,    00         00  (org)
    //Binary : 00,     01      01,     01      01,     01       01,     01     01,    00         00  
    //PU_OFF :  0       1       0,      1      1(ext)  1(*)     1,      1      1      1(ext)     1(ext)  (org)         
    //PU_OFF :  0       1       1,      1      1(ext)  1(*)     1,      1      1      1(ext)     1(ext)           
    //*:nDIS_OFF:4.7K external pull-down resistor                                 
    // s2440IOP->rGPBDAT=  0x0|(1<<9)|(1<<7)|(0<<5)|(1<<4)|(1<<3)|(1<<2);
	s2440IOP->rGPBDAT=  0x0|(0<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2);			// SHLIM 040116
    s2440IOP->rGPBCON = 0x055550;  
    s2440IOP->rGPBUP  = 0x3ff;   //0x2fd->2ff, 3uA is reduced. Why? 

    //*** PORT C GROUP
    //Ports  : GPC15 GPC14 GPC13 GPC12 GPC11 GPC10 GPC9 GPC8 GPC7  GPC6   GPC5   GPC4 GPC3 GPC2  GPC1 GPC0
    //Signal : VD7   VD6   VD5   VD4   VD3   VD2   VD1  VD0 LCDVF2 LCDVF1 LCDVF0 VM VFRAME VLINE VCLK LEND  
    //Setting: IN    IN    IN    IN    IN    IN    IN   IN   OUT   OUT    OUT    IN   IN   IN    IN   IN
    //Binary : 00    00,   00    00,   00    00,   00   00,  01    01,    01     00,  00   00,   00   00
    //PU_OFF :  0     0     0     0,    0     0     0    0,   1     1      1      0,   0    0     0    0
    s2440IOP->rGPCDAT = 0x0;
    s2440IOP->rGPCCON = 0x00005400;  //0x00000000;	
    s2440IOP->rGPCUP  = 0x00e0;      //0x0000;     
    //LCDVFn is connected the analog circuit in LCD. So, this signal should be output L.
    
    //*** PORT D GROUP
    //Ports  : GPD15 GPD14 GPD13 GPD12 GPD11 GPD10 GPD9 GPD8 GPD7 GPD6 GPD5 GPD4 GPD3 GPD2 GPD1 GPD0
    //Signal : VD23  VD22  VD21  VD20  VD19  VD18  VD17 VD16 VD15 VD14 VD13 VD12 VD11 VD10 VD9  VD8
    //Setting: IN    IN    IN    IN    IN    IN    IN   IN   IN   IN   IN   IN   IN   IN   IN   IN
    //Binary : 00    00,   00    00,   00    00,   00   00,  00   00,  00   00,  00   00,  00   00
    //PU_OFF :  0     0     0     0,    0     0     0    0,   0    0    0    0,   0    0    0    0
    s2440IOP->rGPDDAT=  0x0;
    s2440IOP->rGPDCON = 0x0;	
    s2440IOP->rGPDUP  = 0x0;    

    //*** PORT E GROUP
    //Ports  : GPE15  GPE14  GPE13   GPE12    GPE11    GPE10   GPE9    GPE8    GPE7    GPE6  GPE5  GPE4  
    //Signal : IICSDA IICSCL SPICLK0 SPIMOSI0 SPIMISO0 SDDATA3 SDDATA2 SDDATA1 SDDATA0 SDCMD SDCLK I2SSDO 
    //Setting: IN     IN     IN      IN       IN       IN      IN      IN      IN      IN    IN    OUT
    //Binary : 00     00,    00      00,      00       00,     00      00,     00      00,   00    01,     
    //PU_OFF :  1-ext  1-ext  0       0,       0        0       0       0,      0       0     0     1,
    //------------------------------------------------------------------------------------------------
    //Ports  : GPE3   GPE2  GPE1    GPE0    
    //Signal : I2SSDI CDCLK I2SSCLK I2SLRCK     
    //Setting: IN     OUT   OUT     OUT
    //Binary : 00     01,   01      01
    //PU_OFF :  1-ext  1     1       1
    s2440IOP->rGPEDAT = 0x0|(1<<4)|(1<<2)|(1<<1)|(1<<0);
    s2440IOP->rGPECON = 0x00000115;	
    s2440IOP->rGPEUP  = 0xc01f;     

    //*** PORT F GROUP
    //Ports  : GPF7   GPF6   GPF5   GPF4   GPF3        GPF2  GPF1   GPF0
    //Signal : nLED_8 nLED_4 nLED_2 nLED_1 nIRQ_PCMCIA EINT2 KBDINT EINT0
    //Setting: Output Output Output Output IN          IN    IN     EINT0
    //Binary : 01     01,    01     01,    00          00,   00     10
    //PU_OFF :  1      1      1      1,     0-ext       1-ext 1-ext  1-ext
    s2440IOP->rGPFDAT = 0x0  |(0xf<<4);
    s2440IOP->rGPFCON = 0x5502;
    s2440IOP->rGPFUP  = 0xf7;   
                            
    //*** PORT G GROUP
    //Ports  : GPG15 GPG14 GPG13 GPG12 GPG11  GPG10    GPG9     GPG8     GPG7      GPG6    
    //Signal : nYPON YMON  nXPON XMON  EINT19 DMAMODE1 DMAMODE0 DMASTART KBDSPICLK KBDSPIMOSI
    //Setting: OUT   OUT   OUT   OUT   OUT    OUT      OUT      OUT      OUT       OUT
    //Binary : 01    01,   01    01,   01-dbg 01,      01       01,      01        01
    //PU_OFF :  1     1     1     1,    1-ext  1        1        1,       1         1
    //---------------------------------------------------------------------------------------
    //Ports  : GPG5       GPG4      GPG3   GPG2    GPG1    GPG0    
    //Signal : KBDSPIMISO LCD_PWREN EINT11 nSS_SPI IRQ_LAN IRQ_PCMCIA
    //Setting: IN         IN        EINT11 IN      IN      IN
    //Binary : 00         00,       10     00,     00      00
    //PU_OFF :  0-ext      0,        1-ext  0       0       0
#if 0
    s2440IOP->rGPGDAT = 0x0 |(1<<11)|(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<9)|(1<<8)|(1<<7)|(1<<6) ;
    s2440IOP->rGPGCON = 0x55455080;   //GPG11=OUT  //for debug
    s2440IOP->rGPGUP  = 0xfbc8;    
#else	// Modified for 2440
	s2440IOP->rGPGDAT = 0;
	s2440IOP->rGPGCON = 0x00000000;
	s2440IOP->rGPGUP	= 0xffff;
#endif

    //*** PORT H GROUP
    //Ports  : GPH10   GPH9    GPH8 GPH7  GPH6  GPH5 GPH4 GPH3 GPH2 GPH1  GPH0 
    //Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0
    //Setting: IN      IN      IN   IN    IN    IN   OUT  RXD0 TXD0 OUT   IN
    //Binary : 00,     00      00,  00    00,   00   01,  10   10,  01    00
    //PU_OFF :  0       0       0,   1-ext 1-ext 1-ext 1, 1-ext 1    1     1-ext

#if 1
    s2440IOP->rGPHDAT = 0x0|(1<<6)|(1<<1)|(1<<4);    
    s2440IOP->rGPHCON = 0x0001a4; 		   //0x0011a4->0x0001a4 reduces 12uA why -> MAX3232C may sink 12uA.
#else
    //rGPHDAT = 0x0|(1<<6)|(1<<1)|(1<<4);  
    //rGPHCON = 0x0011a4; 
    s2440IOP->rGPHDAT = 0x0|(0<<6)|(1<<1)|(1<<4);  //(1<<6)->(0<<6) reduces 12uA (MAX3232C may sink 12uA.)
    s2440IOP->rGPHCON = 0x0011a4; 
#endif    
    s2440IOP->rGPHUP  = 0x0ff;    // The pull up function is disabled GPH[10:0]


	//PORT J GROUP
	//Ports	:  GPJ12    GPJ11     GPJ10	  GPJ9  GPJ8      GPJ7	GPJ6  GPJ5	GPJ4  GPJ3  GPJ2  GPJ1  GPJ0
	//Signal : CAMRESET CAMCLKOUT CAMHREF CAMVS CAMPCLKIN CAMD7 CAMD6 CAMD5 CAMD4 CAMD3 CAMD2 CAMD1 CAMD0
	//Setting: Out      Out       Out     Out   Out       Out   Out   Out   Out   Out   Out   Out   Out
	//Binary : 01	    01        01      01    01        01    01    01    01    01    01    01    01
	//PU_OFF : 0	    0 		  1	      1     1         1     1     1		1	  1     1     1     1
	//---------------------------------------------------------------------------------------
	
	s2440IOP->rGPJCON = 0x02aaaaaa;
	s2440IOP->rGPJUP  = 0x1fff;    // The pull up function is disabled GPH[10:0]
    
    //External interrupt will be falling edge triggered. 
//    s2440IOP->rEXTINT0 = 0x22222222;    // EINT[7:0]
    s2440IOP->rEXTINT0 = 0x22222224;    // EINT[7:0]			// charlie. button glich
    s2440IOP->rEXTINT1 = 0x22222222;    // EINT[15:8]
    s2440IOP->rEXTINT2 = 0x22222022;    // EINT[23:16]
}

void ConfigMiscReg(void)
{
    volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
	volatile ADCreg *s2440ADC = (ADCreg *)ADC_BASE;
	volatile RTCreg *s2440RTC = (RTCreg *)RTC_BASE;

    s2440RTC->rRTCCON=0x0;   // R/W disable, 1/32768, Normal(merge), No reset
    s2440ADC->rADCCON|=(1<<2);		// ADC StanbyMode

    s2440IOP->rMISCCR|=(1<<12); //USB port0 = suspend
    s2440IOP->rMISCCR|=(1<<13); //USB port1 = suspend

    s2440IOP->rMISCCR|=(1<<2); //Previous state at STOP(?) mode (???)
    
    //D[31:0] pull-up off. The data bus will not be float by the external bus holder.
    //If the pull-up resitsers are turned on,
    //there will be the leakage current through the pull-up resister
    s2440IOP->rMISCCR=s2440IOP->rMISCCR|(3<<0); 

	// In the evaluation board, Even though in sleep mode, the devices are all supplied the power.
	s2440IOP->rMSLCON = (0<<11)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0);
	s2440IOP->rDSC0 = (1<<31)|(3<<8)|(3<<0);
	s2440IOP->rDSC1 = (3<<28)|(3<<26)|(3<24)|(3<<22)|(3<<20)|(3<<18);
}

PRIVATE void 
CPULCDOff(void)
{
    volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
    volatile LCDreg *s2440LCD = (LCDreg *)LCD_BASE;    

    s2440IOP->rGPGDAT &= ~(1 << 4);

    s2440LCD->rLCDCON1   = 0;
    s2440LCD->rLCDCON2   = 0;
    s2440LCD->rLCDCON3   = 0;
    s2440LCD->rLCDCON4   = 0;
    s2440LCD->rLCDCON5   = 0;	
    s2440LCD->rLCDSADDR1 = 0;
    s2440LCD->rLCDSADDR2 = 0;
    s2440LCD->rLCDSADDR3 = 0;
    s2440LCD->rTCONSEL   = 0;
    s2440LCD->rTPAL      = 0;
}

PRIVATE void 
CPUClearCS8900(void)
{
    USHORT temp;

//	RETAILMSG(1,(TEXT("CPUClearCS8900 Enter\r\n")));        

    do 
    {
        temp = *((volatile USHORT *)(CS8900DBG_IOBASE + 8));
    } while (temp != 0);

//	RETAILMSG(1,(TEXT("CPUClearCS8900 Out\r\n")));        
}

void NANDInit(void)
{
	#define NFCONF_INIT                 0xF850
	// HCLK=133Mhz
	#define TACLS		0
	#define TWRPH0		6
	#define TWRPH1		0

	volatile NANDreg *s2440NAND = (NANDreg *)NAND_BASE;
	volatile CLKPWRreg *s2440CLK = (CLKPWRreg *)CLKPWR_BASE;

	//  Enable the clock to NAND controller
	s2440CLK->rCLKCON |= (1<<4);

	//  Now we need enable the NAND Flash controller
//	s2440NAND->rNFCONF = NFCONF_INIT;
    s2440NAND->rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
    s2440NAND->rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(1<<1)|(1<<0);
    s2440NAND->rNFSTAT = 0;

}

VOID OEMPowerOff(void)
{
	volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
 	volatile INTreg *s2440INT = (INTreg *)INT_BASE;
	volatile LCDreg *s2440LCD = (LCDreg *)LCD_BASE;    
	volatile CLKPWRreg * s2440CLKPW = (CLKPWRreg *)CLKPWR_BASE;

//	RETAILMSG(1,(TEXT("++ Enter  OEMPOWER.\r\n")));        

    //  Allow KITL to save its state
//	if(gpfnKitlPowerHandler) {
//		gpfnKitlPowerHandler(TRUE);
//	}

    /* Save Current Important CPU Regs...   */
    CPUSaveRegs(CPUBackupRegs);


    /* LCD Controller Disable               */
    CPULCDOff();

	/* Stop all GPIO */
	ConfigStopGPIO();

	/* Set misc register for power off */
	ConfigMiscReg();

//	s2440CLKPW->rCLKCON = 0xFFFF0;

    /* Actual Power-Off Mode Entry          */
	CPUPowerOff();

//	while(1); // for batt_flt debugging

    /* Recover Process, Load CPU Regs       */
    CPULoadRegs(CPUBackupRegs);

    /* Interrupt Clear                      */
    s2440IOP->rEINTPEND  = s2440IOP->rEINTPEND;
    s2440LCD->rLCDSRCPND = s2440LCD->rLCDSRCPND;
    s2440LCD->rLCDINTPND = s2440LCD->rLCDINTPND;
    s2440INT->rSUBSRCPND = s2440INT->rSUBSRCPND;
//    s2440INT->rSRCPND    = s2440INT->rSRCPND;
//    s2440INT->rINTPND    = s2440INT->rINTPND;

	NANDInit();

    OEMInitDebugSerial();
    CPUClearCS8900();	
	RETAILMSG(1,(TEXT("-- Exit  OEMPOWER.\r\n")));
	RETAILMSG(1,(TEXT("s2440INT->rSRCPND = 0x%x \r\n"), s2440INT->rSRCPND));
	RETAILMSG(1,(TEXT("s2440INT->rINTPND = 0x%x \r\n"), s2440INT->rINTPND));
	RETAILMSG(1,(TEXT("s2440INT->rINTMOD = 0x%x \r\n"), s2440INT->rINTMOD));
	RETAILMSG(1,(TEXT("s2440INT->rINTMSK = 0x%x \r\n"), s2440INT->rINTMSK));

	//	while(1); // for batt_flt debugging

    //  Allow KITL to restore its state
//	if(gpfnKitlPowerHandler) {
//		gpfnKitlPowerHandler(FALSE);
//	}
}


PUBLIC void 
OEMEmergencyPowerOff(void)
{
    volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
 	volatile INTreg *s2440INT = (INTreg *)INT_BASE;
    volatile LCDreg *s2440LCD = (LCDreg *)LCD_BASE;    
    volatile CLKPWRreg *s2440CLK = (CLKPWRreg *)CLKPWR_BASE;    
	
    /* Save Current Important CPU Regs...   */
//	CPUSaveRegs(CPUBackupRegs);

	s2440IOP->rGPFDAT = ~(0x1 << 5);   /* LED Off */
    /* LCD Controller Disable               */
    CPULCDOff();

	s2440IOP->rGPFDAT = ~(0x2 << 5);   /* LED Off */
	/* Stop all GPIO */
	ConfigStopGPIO();

	s2440IOP->rGPFDAT = ~(0x3 << 5);   /* LED Off */
	/* Set misc register for power off */
	ConfigMiscReg();

	s2440IOP->rGPFDAT = ~(0x4 << 5);   /* LED Off */
    /* Actual Power-Off Mode Entry          */

	EmergencyCPUPowerOff();
//	CPUPowerOff();
}

VOID OEMCPUPowerReset()
{
#if 0
	volatile WATCHreg *WTimer = (WATCHreg *) WATCH_BASE;

	// Burst refresh with reading all SDRAM area.
	Burst_Refresh();

	// Mask F bit, I bit.
	CLR_IF();
	
	// Set watch dog reset. After this function, watch-dog reset will occure after 500ms.
	Watchdog_Set();

//	WTimer->rWTCON = ((PCLK/1000000-1) << 8) |		/* The prescaler value => 255 + 1	*/
//					 (0x00 << 6) |		/* Reserved							*/
//					 (0x01 << 5) |		/* Timer enable or disable			*/
//					 (0x03 << 3) |		/* The clock division factor => 16	*/
//					 (0x00 << 2) |		/* Disable bit of interrupt			*/
//					 (0x00 << 1) |		/* Reserved							*/
//					 (0x01 << 0);		/* Enable the reset function of timer */
//
//	while(1);
#endif
	// Set memory with self refresh and enable watchdog reset.
	CPUPowerReset();
}

#define	SDRAM_STARTADDRESS		0x30000000
#define	SDRAM_ENDADDRESS		0x33ffffff

void Burst_Refresh(void)
{
//	int i;

//	for(i=SDRAM_STARTADDRESS; i<SDRAM_ENDADDRESS; i+=8192) 	// Row addr is 13 bit.
//		*(U32 *) i;
}

void CLR_IF()
{
}

//================================================
// Watch-dog timer Interrupt Request Test
//================================================
extern volatile int isWdtInt;
#define	WATCHDOG_TIME	(128)	// [usec], Max=65535*128us.

void Watchdog_Set(void)
{
    volatile INTreg *s2440INT = (INTreg *)INT_BASE;
	volatile WATCHreg *WTimer = (WATCHreg *) WATCH_BASE;

	//t_watchdog = 1 / (PCLK / (Prescaler value + 1 ) / Division_factor)
	s2440INT->rINTMSK &= ~(BIT_WDT_AC97);		   //Watch dog Interrupt service is available
		
	WTimer->rWTCON = ((S2440PCLK/1000000-1) << 8) |		/* The prescaler value => 255 + 1	*/
					 (0x00 << 6) |		/* Reserved							*/
					 (0x00 << 5) |		/* Timer enable or disable			*/
					 (0x03 << 3) |		/* The clock division factor => 16	*/
					 (0x00 << 2) |		/* Disable bit of interrupt			*/
					 (0x00 << 1) |		/* Reserved							*/
					 (0x01 << 0);		/* Enable the reset function of timer */
	WTimer->rWTDAT = 0x1;
	WTimer->rWTCNT = 0x1;
	

//	WTimer->rWTCON = ((PCLK/1000000-1)<<8) | (3<<3) | (1);  //Prescaler=0x31(49),Clock division 128,Reset enable
	// 1*128 usec.

//	WTimer->rWTDAT = WATCHDOG_TIME/128;
//	WTimer->rWTCNT = WATCHDOG_TIME/128;		// (xsec/128us)
}

// End of Power Management 
//------------------------------------------------------------------------------





