cfw.c
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:46k
源码类别:
Windows CE
开发平台:
Windows_Unix
- /*++
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- PARTICULAR PURPOSE.
- Copyright (c) 2001. Samsung Electronics, co. ltd All rights reserved.
- --*/
- #include "windows.h"
- #include "nkintr.h"
- #include "oalintr.h"
- #include "shx.h"
- #include "p2.h"
- #include "p2debug.h"
- #include "tchaud.h"
- #include "drv_glob.h"
- #include <memory.h>
- #ifdef MODULE_CERTIFY
- #include "key1024.c" // OEMLoadInit/OEMLoadModule implementation and the public key used for module signature verification.
- #endif
- //#include "timer.h"
- #include <S2440.h>
- #include <pehdr.h>
- #include <romldr.h>
- extern const unsigned short ScreenBitmap[];
- /*
- @doc EXTERNAL KERNEL HAL
- @module cfwp2.c - P2 HW Support |
- OEM support Functions for the Windows CE P2 Platform.
- @xref <f OEMInit> <f OEMInterruptEnable> <f OEMInterruptDisable>
- <f OEMInterruptDone> <l HAL Overview.Windows CE Kernel OEM Interface>
- @topic Windows CE Kernel OEM Interface |
- This defines the HAL layer - OEM and platform dependent pieces of
- code which we expect the OEM to deliver to us. There are three pieces
- of OEM deliverable code - the bootstrap loader & monitor (for
- debugging), the HAL portions which are interfaces between the kernel
- and the firmware, and the driver interface. This topic covers just
- the HAL portion.
- The philosophy is to keep the HAL layer as simple as possible. The
- HAL should not be confused with the machine or CPU independence. HAL
- is specific for a particular CPU and platform. It includes interfaces
- for the following devices:<nl>
- Real Time Clock<nl>
- Interval Timer (used for the scheduler operation) <nl>
- Interrupt handlers and support <nl>
- Note that it does not include abstractions for devices like the DMA
- controller etc. since the kernel does not use one. Also note that the
- list could change for different CPU's and platforms - for instance,
- some chips might include a lot of peripheral devices (like the
- interval timer) on the CPU chip itself, removing the need for a
- separate interface for them.
- The interfaces for the real time clock and interval timer are still
- being developed. But they should in general be extremely simple and
- straightforward. For details on the interrupt support model in the
- kernel look at <l Interrupt Support Overview.Kernel Interrupt Support>
- @xref <l Interrupt Support Overview.Kernel Interrupt Support>
- <f OEMInit> <f OEMInterruptEnable> <f OEMInterruptDisable>
- <f OEMInterruptDone> <f HookInterrupt>
- */
- unsigned long OEMClockFreq; // OEM clock frequency is used only in OAL
- //
- // Kernel global variables used by GetIdleTime( ) to determine CPU utilization
- //
- extern DWORD idleconv; // translation constant in 1 ms units
- extern DWORD curridlehigh, curridlelow; // 64-bit idle time in ms
- extern int P2ISR();
- extern void InitClock();
- extern void HalCpuInit();
- extern void HalTimerInit();
- extern void HalSleep(DWORD);
- extern void TIMERINIT();
- extern void InitDebugEther(void);
- static void InitDisplay(void);
- static void OEMInitInterrupts(void);
- static void InitSDMMC(void);
- typedef volatile WORD *PVWORD; /* pointer to a volatile word */
- typedef volatile DWORD *PVDWORD; /* pointer to a volatile dword */
- #define REG(base, id) (*(PVWORD)((base)+(id)))
- #define REG32(base, id) (*(PVDWORD)((base)+(id)))
- #define SDIO_FOR_100BD 0
- /*
- #if (CE_MAJOR_VER == 0x0003)
- //Cedar
- // The kernel exports...
- #ifdef AddrCurMSec
- // Some kernels export a pointer to the CurMSec variable.
- static volatile DWORD * pCurMSec = (volatile DWORD *) AddrCurMSec;
- static volatile DWORD * pDiffMSec = (volatile DWORD *) AddrDiffMSec;
- #else
- extern volatile DWORD CurMSec;
- extern volatile DWORD DiffMSec;
- static volatile DWORD * pCurMSec = &CurMSec;
- static volatile DWORD * pDiffMSec = &DiffMSec;
- #endif
- extern DWORD dwSleepMin;
- extern DWORD dwPartialDiffMSec;
- extern DWORD ticksleft;
- #else
- // dougfir or later
- //
- #ifdef AddrCurMSec
- // Some kernels export a pointer to the CurMSec variable.
- static volatile DWORD * pCurMSec = (volatile DWORD *) AddrCurMSec;
- #else
- extern volatile DWORD CurMSec;
- static volatile DWORD * pCurMSec = &CurMSec;
- #endif
- extern DWORD dwReschedTime;
- #endif
- */
- // dougfir or later
- //
- #ifdef AddrCurMSec
- // Some kernels export a pointer to the CurMSec variable.
- static volatile DWORD * pCurMSec = (volatile DWORD *) AddrCurMSec;
- #else
- extern volatile DWORD CurMSec;
- static volatile DWORD * pCurMSec = &CurMSec;
- #endif
- extern DWORD dwReschedTime;
- extern BOOL fIntrTime;
- extern BOOL bProfileTimerRunning;
- volatile ULARGE_INTEGER CurTicks = { 0, 0 };
- volatile ULARGE_INTEGER * pCurTicks = &CurTicks;
- extern DWORD dwReschedIncrement;
- extern DWORD OEMCount1ms;
- //extern void Camera_Initialize(void);
- #define NOT_FIXEDUP (DWORD*)-1
- DWORD *pdwXIPLoc = NOT_FIXEDUP;
- extern ROMChain_t *OEMRomChain;
- /*
- @func void | InitRomChain | Collects chain information for all image regions for the kernel.
- @rdesc N/A.
- @comm
- @xref
- */
- /*
- void InitRomChain(void)
- {
- static ROMChain_t s_pNextRom[MAX_ROM] = {0};
- DWORD dwRomCount = 0;
- DWORD dwChainCount = 0;
- DWORD *pdwCurXIP;
- DWORD dwNumXIPs;
- PXIPCHAIN_ENTRY pChainEntry = NULL;
- if(pdwXIPLoc == NOT_FIXEDUP)
- {
- return; // no chain or not fixed up properly
- }
- // set the top bit to mark it as a virtual address
- pdwCurXIP = (DWORD*)(((DWORD)pdwXIPLoc) | 0x80000000);
- // first DWORD is number of XIPs
- dwNumXIPs = (*pdwCurXIP);
- if(dwNumXIPs > MAX_ROM)
- {
- lpWriteDebugStringFunc(TEXT("ERROR: Number of XIPs exceeds MAXn"));
- return;
- }
- pChainEntry = (PXIPCHAIN_ENTRY)(pdwCurXIP + 1);
- while(dwChainCount < dwNumXIPs)
- {
- if ((pChainEntry->usFlags & ROMXIP_OK_TO_LOAD) && // flags indicates valid XIP
- *(LPDWORD)(((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
- {
- s_pNextRom[dwRomCount].pTOC = *(ROMHDR **)(((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET + 4);
- s_pNextRom[dwRomCount].pNext = NULL;
- if (dwRomCount != 0)
- {
- s_pNextRom[dwRomCount-1].pNext = &s_pNextRom[dwRomCount];
- }
- else
- {
- OEMRomChain = s_pNextRom;
- }
- dwRomCount++;
- }
- else
- {
- lpWriteDebugStringFunc( _T("Invalid XIP foundn") );
- }
- ++pChainEntry;
- dwChainCount++;
- }
- }
- */
- #define FROM_BCD(n) ((((n) >> 4) * 10) + ((n) & 0xf))
- //------------------------------------------------------------------------------
- //
- // @func void | OEMInit | Initialize Hardware Interfaces
- // @rdesc none
- // @comm OEMInit is called by the kernel after it has performed minimal
- // initialization. Interrupts are disabled and the kernel is not
- // ready to handle exceptions. The only kernel service available
- // to this function is <f HookInterrupt>. This should be used to
- // install ISR's for all the hardware interrupts to be handled by
- // the firmware. Note that ISR's must be installed for any interrupt
- // that is to be routed to a device driver - otherwise the
- // <f InterruptInitialize> call from the driver will fail.
- // @xref <l Overview.Windows CE Kernel OEM Interface> <f HookInterrupt>
- // <f InterruptInitialize>
- //
- //------------------------------------------------------------------------------
- void OEMInit()
- {
- volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
- // Instead of calling OEMWriteDebugString directly, call through exported
- // function pointer. This will allow these messages to be seen if debug
- // message output is redirected to Ethernet or the parallel port. Otherwise,
- // lpWriteDebugStringFunc == OEMWriteDebugString.
- lpWriteDebugStringFunc(TEXT("nWindows CE Firmware Initrn"));
- #ifdef MODULE_CERTIFY
- //
- // Set the module signature verification hooks
- //
- pOEMLoadInit = OEMLoadInit;
- pOEMLoadModule = OEMLoadModule;
- //
- // Init the signature verification public key
- //
- InitPubKey(g_bSignPublicKeyBlob,sizeof(g_bSignPublicKeyBlob));
- #endif
- //
- // Set up translation constant for GetIdleTime() (1 ms units).
- // Note: Since curridlehigh, curridlelow is counting in ms, and GetIdleTime()
- // reports in ms, the conversion ratio is one. If curridlehigh, curridlelow
- // were using other units (like ticks), then the conversion would be calculated
- // from the clock frequency.
- //
- idleconv = 1;
- // Initialize interrupts.
- //
- lpWriteDebugStringFunc(TEXT("INFO: Initializing system interrupts...rn"));
- OEMInitInterrupts();
- // Initialize the system clock(s).
- //
- lpWriteDebugStringFunc(TEXT("INFO: Initializing system clock(s)...rn"));
- InitClock();
- // Initialize driver globals area.
- //
- lpWriteDebugStringFunc(TEXT("INFO: Initializing driver globals area...rn"));
- memset((PVOID)DRIVER_GLOBALS_ZEROINIT_START, 0, DRIVER_GLOBALS_ZEROINIT_SIZE);
- // Initialize S2440X01 LCD controller
- InitDisplay();
- // Initialize debug Ethernet (KITL) connection.
- //
- // InitDebugEther();
- // Initialize GPIO /// ;;; SHL
- s2440IOP->rPAD9 = (1<<12) | (0<<11);
- //s2440IOP->rGPJCON = 0x016aaaa;
- //s2440IOP->rGPJUP = ~((0<<12) | (1<<11));
- s2440IOP->rGPHCON = (s2440IOP->rGPHCON & ~(0xf<<18)) | (1<<20) | (1<<18); // CLKOUT1, CLKOUT0
- s2440IOP->rDSC0 = 0x3ff;
- s2440IOP->rDSC1 = 0x3fffffff;
- // camera
- //Camera_Initialize();
- //s2440IOP->rGPJCON = 0x2aaaaaa;
- //s2440IOP->rGPJUP = 0x1fff;
- InitSDMMC();
- // Initialize the ROM chain (multi-region).
- //
- // InitRomChain();
- lpWriteDebugStringFunc(TEXT("OEMInit Done...rn"));
- }
- //------------------------------------------------------------------------------
- //
- // @func BOOL | OEMInterruptEnable | Enable a hardware interrupt
- // @rdesc Returns TRUE if valid interrupt ID or FALSE if invalid ID.
- // @comm This function is called by the Kernel when a device driver
- // calls <f InterruptInitialize>. The system is not preemptible when this
- // function is called.
- // @xref <l Overview.Windows CE Kernel OEM Interface> <f InterruptInitialize>
- //
- //------------------------------------------------------------------------------
- BOOL
- OEMInterruptEnable(DWORD idInt, // @parm Interrupt ID to be enabled. See <l Interrupt ID's.Interrupt ID's> for a list of possble values.
- LPVOID pvData, // @parm ptr to data passed in in the <f InterruptInitialize> call
- DWORD cbData) // @parm Size of data pointed to be <p pvData>
- {
- volatile INTreg *s2440INT = (INTreg *)INT_BASE;
- volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
- volatile MMCreg *s2440SDIO = (MMCreg *)MMC_BACE;
- BOOL bRet = TRUE;
- INTERRUPTS_OFF();
- switch (idInt)
- {
- case SYSINTR_VMINI: // Vmini.
- //return (TRUE);
- break;
- case SYSINTR_BREAK: // There is no halt button on P2.
- //return(FALSE);
- break;
- case SYSINTR_DMA0:
- s2440INT->rINTMSK &= ~BIT_DMA0; // SDIO DMA interrupt
- //RETAILMSG(1,(TEXT("::: SYSINTR_DMA0 OEMInterruptDisablern")));
- break;
- case SYSINTR_SDMMC:
- s2440INT->rINTMSK &= ~BIT_MMC;
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC OEMInterruptDisablern")));
- break;
- case SYSINTR_SDMMC_SDIO_INTERRUPT:
- s2440INT->rINTMSK &= ~BIT_MMC;
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_SDIO_INTERRUPT OEMInterruptEnablern")));
- break;
- case SYSINTR_SDMMC_CARD_DETECT:
- #if SDIO_FOR_100BD // for b'd revision 1.00
- s2440IOP->rEINTPEND = (1 << 18);
- s2440IOP->rEINTMASK &= ~(1 << 18);
- //s2440INT->rSRCPND = BIT_EINT8_23;
- // if (s2440INT->rINTPND & BIT_EINT8_23)
- // s2440INT->rINTMSK &= ~BIT_EINT8_23;
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_CARD_DETECT OEMInterruptEnablern")));
- #else // for b'd revision 0.17
- s2440IOP->rEINTPEND = (1 << 16);
- s2440IOP->rEINTMASK &= ~(1 << 16);
- #endif
- s2440INT->rSRCPND = BIT_EINT8_23;
- s2440INT->rINTPND = BIT_EINT8_23;
- s2440INT->rINTMSK &= ~BIT_EINT8_23;
- break;
- case SYSINTR_TOUCH:
- //RETAILMSG(0,(TEXT("OEMInterruptEnable:TOUCHnrn")));
- break;
- case SYSINTR_TOUCH_CHANGED:
- //RETAILMSG(0,(TEXT("OEMInterruptEnable:TOUCH CHANGEDrnrn")));
- s2440INT->rINTMSK &= ~BIT_ADC;
- s2440INT->rINTSUBMSK &= ~INTSUB_TC;
- break;
- case SYSINTR_KEYBOARD: // Keyboard on EINT1.
- /*
- s2440INT->rSRCPND = BIT_EINT1;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_EINT1) s2440INT->rINTPND = BIT_EINT1;
- */
- s2440INT->rINTMSK &= ~BIT_EINT1;
- break;
- case SYSINTR_SERIAL: // Serial port.
- s2440INT->rSUBSRCPND = (INTSUB_RXD0 | INTSUB_TXD0 | INTSUB_ERR0);
- s2440INT->rINTSUBMSK &= ~INTSUB_RXD0;
- s2440INT->rINTSUBMSK &= ~INTSUB_TXD0;
- s2440INT->rINTSUBMSK &= ~INTSUB_ERR0;
- s2440INT->rSRCPND = BIT_UART0;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_UART0) s2440INT->rINTPND = BIT_UART0;
- s2440INT->rINTMSK &= ~BIT_UART0;
- break;
- case SYSINTR_IR: // IrDA.
- s2440INT->rSUBSRCPND = (INTSUB_RXD2 | INTSUB_TXD2 | INTSUB_ERR2);
- s2440INT->rINTSUBMSK &= ~INTSUB_RXD2;
- s2440INT->rINTSUBMSK &= ~INTSUB_TXD2;
- s2440INT->rINTSUBMSK &= ~INTSUB_ERR2;
- s2440INT->rSRCPND = BIT_UART2;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_UART2) s2440INT->rINTPND = BIT_UART2;
- s2440INT->rINTMSK &= ~BIT_UART2;
- break;
- // update audio old ;;; SHL
- // case SYSINTR_AUDIO: // Audio controller (the controller uses both DMA1 and DMA2 interrupts).
- // // DMA1 (input).
- // //
- // s2440INT->rSRCPND = BIT_DMA1;
- // // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- // if (s2440INT->rINTPND & BIT_DMA1) s2440INT->rINTPND = BIT_DMA1;
- // s2440INT->rINTMSK &= ~BIT_DMA1;
- // // DMA2 (output).
- // //
- // s2440INT->rSRCPND = BIT_DMA2;
- // // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- // if (s2440INT->rINTPND & BIT_DMA2) s2440INT->rINTPND = BIT_DMA2;
- // s2440INT->rINTMSK &= ~BIT_DMA2;
- // break;
- // update audio bug.
- case SYSINTR_AUDIO: // Audio controller (the controller uses both DMA1 and DMA2 interrupts).
- // DMA1 (input).
- //
- s2440INT->rINTMSK &= ~BIT_DMA1;
- // DMA2 (output).
- s2440INT->rINTMSK &= ~BIT_DMA2;
- break;
- case SYSINTR_ADC:
- //return(FALSE);
- break;
- case SYSINTR_PCMCIA_LEVEL: // PCMCIA data on EINT8.
- s2440INT->rINTMSK &= ~BIT_EINT8_23;
- //s2440INT->rSRCPND = BIT_EINT8_23;
- //s2440INT->rINTPND = BIT_EINT8_23;
- s2440IOP->rEINTMASK &= ~0x100;
- //s2440IOP->rEINTPEND = 0x100;
- //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_LEVEL OEMInterruptEnablern")));
- break;
- case SYSINTR_PCMCIA_EDGE:
- //return(FALSE);
- break;
- case SYSINTR_PCMCIA_STATE: // PCMCIA insertion interrupt.
- s2440INT->rSRCPND = BIT_EINT3; // to clear the previous pending states
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_EINT3) s2440INT->rINTPND = BIT_EINT3;
- s2440INT->rINTMSK &= ~BIT_EINT3;
- //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_STATE OEMInterruptEnablern")));
- break;
- case SYSINTR_TIMING:
- //return(FALSE);
- break;
- case SYSINTR_ETHER: // Ethernet on EINT9.
- s2440IOP->rEINTPEND = 0x200;
- s2440IOP->rEINTMASK &= ~0x200;
- //s2440INT->rSRCPND = BIT_EINT8_23; // by shim
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_EINT8_23) s2440INT->rINTPND = BIT_EINT8_23;
- s2440INT->rINTMSK &= ~BIT_EINT8_23;
- //RETAILMSG(1,(TEXT("::: SYSINTR_ETHER OEMInterruptEnablern")));
- break;
- #if 0
- case SYSINTR_USB:
- // USB host interrupt enable bit. by hjcho
- s2440INT->rINTMSK &= ~BIT_USBH;
- break;
- case SYSINTR_USBD:
- s2440INT->rINTMSK &= ~BIT_USBD;
- //RETAILMSG(1,(TEXT("::: SYSINTR_USBD OEMInterruptEnablern")));
- break;
- #else
- case SYSINTR_USB: // USB host.
- s2440INT->rSRCPND = BIT_USBH;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_USBH) s2440INT->rINTPND = BIT_USBH;
- s2440INT->rINTMSK &= ~BIT_USBH;
- break;
- case SYSINTR_USBD:
- s2440INT->rSRCPND = BIT_USBD;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_USBD) s2440INT->rINTPND = BIT_USBD;
- s2440INT->rINTMSK &= ~BIT_USBD;
- RETAILMSG(1, (TEXT("USB enable interrutprn")));
- break;
- #endif
- case SYSINTR_POWER:
- s2440INT->rSRCPND = BIT_EINT0;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_EINT0) s2440INT->rINTPND = BIT_EINT0;
- s2440INT->rINTMSK &= ~BIT_EINT0;
- s2440INT->rSRCPND = BIT_EINT2;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_EINT2) s2440INT->rINTPND = BIT_EINT2;
- s2440INT->rINTMSK &= ~BIT_EINT2;
- break;
- case SYSINTR_CAM:
- s2440INT->rINTSUBMSK &= ~(BIT_SUB_CAM_P | BIT_SUB_CAM_C);
- s2440INT->rINTMSK &= ~BIT_CAM;
- break;
- case SYSINTR_IIC:
- s2440INT->rINTMSK &= ~BIT_IIC;
- break;
- default:
- bRet = FALSE; /* unsupported interrupt value */
- //return(FALSE);
- break;
- }
- INTERRUPTS_ON();
- return bRet;
- //return(TRUE);
- }
- //------------------------------------------------------------------------------
- //
- // @func BOOL | OEMInterruptDisable | Disable a hardware interrupt
- // @rdesc none
- // @comm OEMInterruptDisable is called by the Kernel when a device driver
- // calls <f InterruptDisable>. The system is not preemtible when this
- // function is called.
- // @xref <l Overview.Windows CE Kernel OEM Interface> <f InterruptDisable>
- //
- //------------------------------------------------------------------------------
- void
- OEMInterruptDisable(DWORD idInt) // @parm Interrupt ID to be disabled. See <t Interrupt ID's>
- // for the list of possible values.
- {
- volatile INTreg *s2440INT = (INTreg *)INT_BASE;
- volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
- volatile MMCreg *s2440SDIO = (MMCreg *)MMC_BACE;
- INTERRUPTS_OFF();
- switch (idInt)
- {
- case SYSINTR_BREAK: // There is no halt button on P2.
- break;
- case SYSINTR_DMA0:
- s2440INT->rINTMSK |= BIT_DMA0; // SDIO DMA interrupt
- //RETAILMSG(1,(TEXT("::: SYSINTR_DMA0 OEMInterruptDisablern")));
- break;
- case SYSINTR_SDMMC:
- s2440INT->rINTMSK |= BIT_MMC;
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC OEMInterruptDisablern")));
- break;
- case SYSINTR_SDMMC_SDIO_INTERRUPT:
- s2440INT->rINTMSK |= BIT_MMC;
- s2440SDIO->rSDIINTMSK &= ~(0x1<<12); // interrupt from SDIO card
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_SDIO_INTERRUPT OEMInterruptDisablern")));
- break;
- case SYSINTR_SDMMC_CARD_DETECT:
- #if SDIO_FOR_100BD // for b'd revision 1.00
- s2440IOP->rEINTMASK |= (1 << 18);
- #else // for b'd revision 0.17
- s2440IOP->rEINTMASK |= (1 << 16);
- #endif
- s2440INT->rINTMSK |= BIT_EINT8_23;
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_CARD_DETECT OEMInterruptDisablern")));
- break;
- case SYSINTR_TOUCH:
- break;
- case SYSINTR_TOUCH_CHANGED:
- s2440INT->rINTMSK |= BIT_ADC;
- s2440INT->rINTSUBMSK |= INTSUB_TC;
- break;
- case SYSINTR_KEYBOARD:
- s2440INT->rINTMSK |= BIT_EINT1;
- break;
- case SYSINTR_SERIAL:
- s2440INT->rINTMSK |= BIT_UART0;
- s2440INT->rINTSUBMSK |= INTSUB_RXD0;
- s2440INT->rINTSUBMSK |= INTSUB_TXD0;
- s2440INT->rINTSUBMSK |= INTSUB_ERR0;
- break;
- case SYSINTR_IR:
- s2440INT->rINTMSK |= BIT_UART2;
- s2440INT->rINTSUBMSK |= INTSUB_RXD2;
- s2440INT->rINTSUBMSK |= INTSUB_TXD2;
- s2440INT->rINTSUBMSK |= INTSUB_ERR2;
- break;
- case SYSINTR_AUDIO:
- s2440INT->rINTMSK |= BIT_DMA1; // Audio input DMA.
- s2440INT->rINTMSK |= BIT_DMA2; // Audio output DMA.
- break;
- case SYSINTR_ADC:
- break;
- case SYSINTR_PCMCIA_LEVEL:
- s2440IOP->rEINTMASK |= 0x100;
- s2440INT->rINTMSK |= BIT_EINT8_23;
- //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_LEVEL OEMInterruptDisablern")));
- break;
- case SYSINTR_PCMCIA_EDGE:
- break;
- case SYSINTR_PCMCIA_STATE:
- s2440INT->rINTMSK |= BIT_EINT3;
- //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_STATE OEMInterruptDisablern")));
- break;
- case SYSINTR_ETHER:
- s2440INT->rINTMSK |= BIT_EINT8_23;
- s2440IOP->rEINTMASK |= 0x200;
- //RETAILMSG(1,(TEXT("::: SYSINTR_ETHER OEMInterruptDisablern")));
- break;
- case SYSINTR_USB:
- s2440INT->rINTMSK |= BIT_USBH;
- break;
- case SYSINTR_USBD:
- s2440INT->rINTMSK |= BIT_USBD;
- //RETAILMSG(1,(TEXT("::: SYSINTR_USBD OEMInterruptDisablern")));
- break;
- case SYSINTR_POWER:
- s2440INT->rINTMSK |= BIT_EINT0;
- s2440INT->rINTMSK |= BIT_EINT2;
- break;
- case SYSINTR_CAM:
- s2440INT->rINTMSK |= BIT_CAM;
- s2440INT->rINTSUBMSK |= (INTSUB_CAM_P | INTSUB_CAM_C);
- break;
- case SYSINTR_IIC:
- s2440INT->rINTMSK |= BIT_IIC;
- break;
- default:
- break;
- }
- INTERRUPTS_ON();
- }
- //------------------------------------------------------------------------------
- //
- // @func BOOL | OEMInterruptDone | Signal completion of interrupt processing
- // @rdesc none
- // @comm OEMInterruptDone is called by the Kernel when a device driver
- // calls <f InterruptDone>. The system is not preemtible when this
- // function is called.
- // @xref <l Overview.Kernel Interrupt Support> <f InterruptDone>
- //
- //------------------------------------------------------------------------------
- void
- OEMInterruptDone(DWORD idInt) // @parm Interrupt ID. See <t Interrupt ID's>
- // for the list of possible values.
- {
- volatile INTreg *s2440INT = (INTreg *)INT_BASE;
- volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
- INTERRUPTS_OFF();
- switch (idInt)
- {
- case SYSINTR_DMA0:
- s2440INT->rINTMSK &= ~BIT_DMA0; // SDIO DMA interrupt
- //RETAILMSG(1,(TEXT("::: SYSINTR_DMA0 OEMInterruptDonern")));
- break;
- case SYSINTR_SDMMC:
- s2440INT->rINTMSK &= ~BIT_MMC;
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC OEMInterruptDonern")));
- break;
- case SYSINTR_SDMMC_SDIO_INTERRUPT:
- s2440INT->rINTMSK &= ~BIT_MMC;
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_SDIO_INTERRUPT OEMInterruptDonern")));
- break;
- case SYSINTR_SDMMC_CARD_DETECT:
- #if SDIO_FOR_100BD // for b'd revision 1.00
- s2440IOP->rEINTPEND = (1<<18);
- s2440IOP->rEINTMASK &= ~(1 << 18);
- //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_CARD_DETECT OEMInterruptDonern")));
- #else // for b'd revision 0.17
- s2440IOP->rEINTPEND = (1<<16);
- s2440IOP->rEINTMASK &= ~(1 << 16);
- #endif
- s2440INT->rINTMSK &= ~BIT_EINT8_23;
- break;
- case SYSINTR_TOUCH:
- /*
- * Nothing has to be done here as interrupts are masked and unmasked by the touch
- * handler in the HAL.
- */
- s2440INT->rINTMSK &= ~BIT_TIMER1;
- break;
- case SYSINTR_TOUCH_CHANGED:
- /*
- * Nothing has to be done here as interrupts are masked and unmasked by the touch
- * handler in the HAL.
- */
- s2440INT->rINTMSK &= ~BIT_ADC;
- s2440INT->rINTSUBMSK &= ~INTSUB_TC;
- //RETAILMSG(0,(TEXT("OEMInterruptDone:TOUCH CHANGEDnrn")));
- break;
- case SYSINTR_KEYBOARD:
- s2440INT->rINTMSK &= ~BIT_EINT1;
- break;
- case SYSINTR_SERIAL:
- s2440INT->rINTMSK &= ~BIT_UART0;
- s2440INT->rINTSUBMSK &= ~INTSUB_RXD0;
- break;
- case SYSINTR_IR:
- s2440INT->rINTMSK &= ~BIT_UART2;
- s2440INT->rINTSUBMSK &= ~INTSUB_RXD2;
- break;
- case SYSINTR_AUDIO:
- // DMA1 is for audio input.
- // DMA2 is for audio output.
- s2440INT->rSRCPND = (BIT_DMA1 | BIT_DMA2);
- if (s2440INT->rINTPND & BIT_DMA1) s2440INT->rINTPND = BIT_DMA1;
- if (s2440INT->rINTPND & BIT_DMA2) s2440INT->rINTPND = BIT_DMA2;
- s2440INT->rINTMSK &= ~BIT_DMA1;
- s2440INT->rINTMSK &= ~BIT_DMA2;
- break;
- case SYSINTR_ADC:
- break;
- case SYSINTR_PCMCIA_LEVEL:
- s2440INT->rSRCPND = BIT_EINT8_23;
- if (s2440INT->rINTPND & BIT_EINT8_23) s2440INT->rINTPND = BIT_EINT8_23;
- s2440INT->rINTMSK &= ~BIT_EINT8_23;
- s2440IOP->rEINTMASK &= ~(1<<8);
- //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_LEVEL OEMInterruptDonern")));
- break;
- case SYSINTR_PCMCIA_EDGE:
- //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_EDGE OEMInterruptDonern")));
- break;
- case SYSINTR_PCMCIA_STATE:
- s2440INT->rINTMSK &= ~BIT_EINT3;
- //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_STATE OEMInterruptDonern")));
- break;
- case SYSINTR_ETHER:
- s2440INT->rINTMSK &= ~BIT_EINT8_23;
- s2440IOP->rEINTMASK &= ~0x200;
- //RETAILMSG(1, (TEXT("::: SYSINTR_USBD OEMInterruptDonern")));
- break;
- case SYSINTR_USB:
- s2440INT->rINTMSK &= ~BIT_USBH;
- break;
- case SYSINTR_USBD:
- s2440INT->rINTMSK &= ~BIT_USBD;
- //RETAILMSG(1,(TEXT("::: SYSINTR_USBD OEMInterruptDonern")));
- break;
- case SYSINTR_POWER:
- s2440INT->rSRCPND = BIT_EINT0;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_EINT0) s2440INT->rINTPND = BIT_EINT0;
- s2440INT->rINTMSK &= ~BIT_EINT0;
- s2440INT->rSRCPND = BIT_EINT2;
- // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
- if (s2440INT->rINTPND & BIT_EINT2) s2440INT->rINTPND = BIT_EINT2;
- s2440INT->rINTMSK &= ~BIT_EINT2;
- break;
- case SYSINTR_CAM:
- s2440INT->rSUBSRCPND = INTSUB_CAM_P;
- s2440INT->rSUBSRCPND = INTSUB_CAM_C;
- s2440INT->rSRCPND = BIT_CAM;
- if (s2440INT->rINTPND & BIT_CAM)
- {
- s2440INT->rINTPND = BIT_CAM;
- }
- s2440INT->rINTSUBMSK &= ~(INTSUB_CAM_P | INTSUB_CAM_C);
- s2440INT->rINTMSK &= ~BIT_CAM;
- break;
- case SYSINTR_IIC:
- s2440INT->rINTMSK &= ~BIT_IIC;
- break;
- }
- INTERRUPTS_ON();
- }
- //------------------------------------------------------------------------------
- //------------------------------------------------------------------------------
- BOOL
- OEMGetExtensionDRAM(
- LPDWORD lpMemStart,
- LPDWORD lpMemLen
- )
- {
- return FALSE; // no extension DRAM
- }
- //------------------------------------------------------------------------------
- //
- // OEMQueryPerformanceCounter
- //
- // The OEMQueryPerformanceCounter function retrieves the current value of
- // the high-resolution performance counter, if one exists.
- //
- // BOOL QueryPerformanceCounter(
- //
- // LARGE_INTEGER *lpliPerformanceCount // address of current counter value
- // );
- //
- // Parameters
- //
- // lpliPerformanceCount
- //
- // Points to a variable that the function sets, in counts, to the current
- // performance-counter value. If the installed hardware does not support
- // a high-resolution performance counter, this parameter can be to zero.
- //
- // Return Value
- //
- // If the installed hardware supports a high-resolution performance
- // counter, the return value is TRUE.
- // If the installed hardware does not support a high-resolution
- // performance counter, the return value is FALSE.
- //
- // If this function is implemented by the OEM, the pointer pQueryPerformanceCounter
- // should be initialized as follows:
- //
- // BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
- //
- //------------------------------------------------------------------------------
- BOOL
- OEMQueryPerformanceCounter(
- LARGE_INTEGER *lpliPerformanceCount
- )
- {
- extern DWORD PerfCountSinceTick();
- ULARGE_INTEGER liBase;
- DWORD dwCurCount;
- // Make sure CurTicks is the same before and after read of counter to account for
- // possible rollover
- do {
- liBase = CurTicks;
- dwCurCount = PerfCountSinceTick();
- } while (liBase.LowPart != CurTicks.LowPart) ;
- lpliPerformanceCount->QuadPart = liBase.QuadPart + dwCurCount;
- return TRUE;
- }
- //------------------------------------------------------------------------------
- //
- // OEMQueryPerformanceFrequency
- //
- // The OEMQueryPerformanceFrequency function retrieves the frequency of
- // the high-resolution performance counter, if one exists.
- //
- // BOOL OEMQueryPerformanceFrequency(
- //
- // LARGE_INTEGER *lpliPerformanceFreq // address of current frequency
- // );
- //
- // Parameters
- //
- // lpliPerformanceFreq
- //
- // Points to a variable that the function sets, in counts per second, to
- // the current performance-counter frequency. If the installed hardware
- // does not support a high-resolution performance counter, this parameter
- // can be to zero.
- //
- // Return Value
- //
- // If the installed hardware supports a high-resolution performance
- // counter, the return value is TRUE.
- // If the installed hardware does not support a high-resolution
- // performance counter, the return value is FALSE.
- //
- // If this function is implemented by the OEM, the pointer pQueryPerformanceFrequency
- // should be initialized as follows:
- //
- // BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpPerformanceFrequency)=OEMQueryPerformanceFrequency;
- //
- //------------------------------------------------------------------------------
- BOOL
- OEMQueryPerformanceFrequency(
- LARGE_INTEGER *lpliPerformanceFreq
- )
- {
- extern DWORD PerfCountFreq();
- lpliPerformanceFreq->HighPart = 0;
- lpliPerformanceFreq->LowPart = PerfCountFreq();
- return TRUE;
- }
- // set pointers to OEM functions
- BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
- BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpliPerformanceFreq)=OEMQueryPerformanceFrequency;
- //
- // CPU-specific functions for OEMIdle
- //
- extern void CPUEnterIdle(DWORD dwIdleParam);
- extern DWORD CPUGetSysTimerCountMax(DWORD dwIdleMSecRequested);
- extern void CPUSetSysTimerCount(DWORD dwIdleMSec);
- extern BOOL CPUClearSysTimerIRQ(void);
- //
- // dougfir or later
- //
- extern DWORD
- CPUGetSysTimerCountElapsed(
- DWORD dwTimerCountdownMSec,
- volatile DWORD *pCurMSec,
- DWORD *pPartialCurMSec,
- volatile ULARGE_INTEGER *pCurTicks
- );
- //------------------------------------------------------------------------------
- //
- // This routine is called by the kernel when there are no threads ready to
- // run. The CPU should be put into a reduced power mode and halted. It is
- // important to be able to resume execution quickly upon receiving an interrupt.
- // Note: It is assumed that interrupts are off when OEMIdle is called. Interrrupts
- // are turned off when OEMIdle returns.
- //
- //------------------------------------------------------------------------------
- static DWORD dwPartialCurMSec = 0; // Keep CPU-specific sub-millisecond leftover.
- void
- OEMIdle( DWORD dwIdleParam )
- {
- DWORD dwIdleMSec;
- DWORD dwPrevMSec = *pCurMSec;
- // Use for 64-bit math
- ULARGE_INTEGER currIdle = { curridlelow, curridlehigh };
- if ((int) (dwIdleMSec = dwReschedTime - dwPrevMSec) <= 0)
- {
- return; // already time to wakeup
- }
- // just idle till tick if profiling or running iltiming
- if (bProfileTimerRunning || fIntrTime) // fIntrTime : Interrupt Latency timeing.
- {
- // idle till end of 'tick'
- CPUEnterIdle(dwIdleParam);
- // Update global idle time and return
- currIdle.QuadPart += RESCHED_PERIOD;
- curridlelow = currIdle.LowPart;
- curridlehigh = currIdle.HighPart;
- return;
- }
- //
- // Since OEMIdle( ) is being called in the middle of a normal reschedule
- // period, CurMSec, dwPartialCurMSec, and CurTicks need to be updated accordingly.
- // Once we reach this point, we must re-program the timer (if we ever did)
- // because dwPartialCurMSec will be modified in the next function call.
- //
- CPUGetSysTimerCountElapsed(RESCHED_PERIOD, pCurMSec, &dwPartialCurMSec, pCurTicks);
- if ((int) (dwIdleMSec -= *pCurMSec - dwPrevMSec) > 0)
- {
- dwPrevMSec = *pCurMSec;
- //
- // The system timer may not be capable of arbitrary timeouts. Get the
- // CPU-specific highest possible timeout available.
- //
- dwIdleMSec = CPUGetSysTimerCountMax(dwIdleMSec);
- //
- // Set the timer to wake up much later than usual, if needed.
- //
- CPUSetSysTimerCount(dwIdleMSec);
- CPUClearSysTimerIRQ( );
- //
- // Enable wakeup on any interrupt, then go to sleep.
- //
- // DEBUGMSG(1, (TEXT("OEMIDle rn")));
- CPUEnterIdle(dwIdleParam);
- INTERRUPTS_OFF( );
- //
- // We're awake! The wake-up ISR (or any other ISR) has already run.
- //
- if (dwPrevMSec != *pCurMSec)
- {
- //
- // We completed the full period we asked to sleep. Update the counters.
- //
- *pCurMSec += (dwIdleMSec - RESCHED_PERIOD); // Subtract resched period, because ISR also incremented.
- CurTicks.QuadPart += (dwIdleMSec - RESCHED_PERIOD) * dwReschedIncrement;
- currIdle.QuadPart += dwIdleMSec;
- } else {
- //
- // Some other interrupt woke us up before the full idle period was
- // complete. Determine how much time has elapsed.
- //
- currIdle.QuadPart += CPUGetSysTimerCountElapsed(dwIdleMSec, pCurMSec, &dwPartialCurMSec, pCurTicks);
- }
- }
- // Re-arm counters
- CPUSetSysTimerCount(RESCHED_PERIOD);
- CPUClearSysTimerIRQ( );
- // Update global idle time
- curridlelow = currIdle.LowPart;
- curridlehigh = currIdle.HighPart;
- return;
- }
- //------------------------------------------------------------------------------
- //
- // DWORD GetTickCount(VOID) Return count of time since boot in milliseconds
- //
- //------------------------------------------------------------------------------
- DWORD
- SC_GetTickCount(void)
- {
- DWORD dwInc = 0, dwPartial = dwPartialCurMSec;
- DWORD curReturnMSec;
- ULARGE_INTEGER cdummy = {0, 0};
- curReturnMSec=*pCurMSec;
- CPUGetSysTimerCountElapsed(RESCHED_PERIOD, &dwInc, &dwPartial, &cdummy);
- return (curReturnMSec==*pCurMSec)?curReturnMSec+dwInc:*pCurMSec;
- }
- volatile BOOL fResumeFlag;
- extern void CPUEnterIdleMode(void);
- //------------------------------------------------------------------------------
- // Initialize SDMMC block..
- //------------------------------------------------------------------------------
- static void InitSDMMC(void)
- {
- volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
- // Initialize SDMMC and Configure SDMMC Card Detect
- // GPIO Configure
- // RETAILMSG(1,(TEXT("SDMMC config current rGPGCON: %xrn"), s2440IOP->rGPGCON));
- // We must need this PULL-UP routines to inialize.
- // s2440IOP->rGPGUP = 0xF800;
- #if SDIO_FOR_100BD // for b'd revision 1.00
- // s2440IOP->rGPGUP &= ~(1<<10);
- s2440IOP->rGPGUP = 0xF800;
- s2440IOP->rGPGCON &= ~((0x3 << 20));
- s2440IOP->rGPGCON |= ((0x2 << 20)); // External Interrupt #18 Enable
- //RETAILMSG(1,(TEXT("SDMMC config set rGPGCON: %xrn"), s2440IOP->rGPGCON));
- // s2440IOP->rEXTINT2 &= ~(0x7 << 8); // Configure EINT18 as Both Edge Mode
- // s2440IOP->rEXTINT2 |= (0x7 << 8);
- #else // for b'd revision 0.17
- s2440IOP->rGPGUP = 0xF800;
- s2440IOP->rGPGCON &= ~((0x3 << 16));
- s2440IOP->rGPGCON |= ((0x0 << 16)); //input /* External Interrupt #16 Enable */
- RETAILMSG(1,(TEXT("SDMMC config set rGPGCON: %xrn"), s2440IOP->rGPGCON));
- s2440IOP->rEINTPEND = (1 << 16); //clear
- s2440IOP->rEINTMASK |= (1 << 16); //disable
- // s2440IOP->rEXTINT2 &= ~(0x7 << 0); /* Configure EINT16 as Both Edge Mode */
- // s2440IOP->rEXTINT2 |= (0x0 << 0); // low level trig
- #endif
- /* Configure SDMMC Write Protect */
- s2440IOP->rGPHUP = 0x0;
- s2440IOP->rGPHCON &= ~((0x3 << 16));
- s2440IOP->rGPHCON |= ((0x0 << 16)); /* GPH8/UCLK Write Protect Pin */
- //RETAILMSG(1,(TEXT("SDMMC config Init Done.rn")));
- }
- //------------------------------------------------------------------------------
- // Initialize and test the LCD block..
- //------------------------------------------------------------------------------
- /*
- // Define some values for TFT 16bpp
- #if(LCDTYPE == TFT16BPP) // TFT 640*480 / 16bpp
- #define FR_WIDTH 240
- #define FR_HEIGHT 320
- #define PhysicalVmemSize FR_HEIGHT*FR_WIDTH*LCDTYPE
- struct FrameBuffer {
- unsigned short pixel[FR_HEIGHT][FR_WIDTH];
- };
- #else if(LCDTYPE == STN8BPP)// STN 320*240 / 8bpp
- #define FR_WIDTH 320
- #define FR_HEIGHT 240
- #define PhysicalVmemSize FR_HEIGHT*FR_WIDTH
- struct FrameBuffer {
- unsigned char pixel[FR_HEIGHT][FR_WIDTH];
- };
- #endif
- */
- #if (LCD_TYPE == TFT640_480)
- struct FrameBuffer {
- unsigned short pixel[LCD_YSIZE_TFT][LCD_XSIZE_TFT];
- };
- struct FrameBuffer *FBuf;
- #elif (LCD_TYPE == TFT240_320)
- struct FrameBuffer *FBuf;
- #endif
- static void InitDisplay()
- {
- int i, j;
- volatile IOPreg *s2440IOP;
- volatile LCDreg *s2440LCD;
- s2440IOP = (IOPreg *)IOP_BASE;
- s2440LCD = (LCDreg *)LCD_BASE;
- // LCD port initialize.
- s2440IOP->rGPCUP = 0xFFFFFFFF;
- s2440IOP->rGPCCON = 0xAAAAAAAA;
- s2440IOP->rGPDUP = 0xFFFFFFFF;
- s2440IOP->rGPDCON = 0xAAAAAAAA;
- s2440IOP->rGPGCON &= ~(3 << 8); // Set LCD_PWREN as output
- s2440IOP->rGPGCON |= (1 << 8);
- s2440IOP->rGPGDAT |= (1 << 4); // Backlight ON
- #if (LCD_TYPE == TFT640_480)
- s2440LCD->rLCDCON1 = (1 << 8) | // VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz // ;;; SHL
- (0 << 7) | // 0 : Each Frame
- (3 << 5) | // TFT LCD Pannel
- (12<< 1) | // 16bpp Mode
- (0 << 0) ; // Disable LCD Output
- s2440LCD->rLCDCON2 = (VBPD << 24) | // VBPD : 1
- (LINEVAL_TFT << 14) | // Virtical Size : 320 - 1
- (VFPD << 6) | // VFPD : 2
- (VSPW << 0) ; // VSPW : 1
- s2440LCD->rLCDCON3 = (HBPD << 19) | // HBPD : 6
- (HOZVAL_TFT << 8) | // HOZVAL_TFT : 240 - 1
- (HFPD << 0) ; // HFPD : 2
- s2440LCD->rLCDCON4 = (MVAL << 8) | // MVAL : 13 */
- (HSPW << 0) ; // HSPW : 4 */
- s2440LCD->rLCDCON5 = (0 << 12) | // BPP24BL : LSB valid
- (1 << 11) | // FRM565 MODE : 5:6:5 Format
- (0 << 10) | // INVVCLK : VCLK Falling Edge
- (1 << 9) | // INVVLINE : Inverted Polarity
- (1 << 8) | // INVVFRAME : Inverted Polarity
- (0 << 7) | // INVVD : Normal
- (0 << 6) | // INVVDEN : Normal
- (0 << 5) | // INVPWREN : Normal
- (0 << 4) | // INVENDLINE : Normal
- (0 << 3) | // PWREN : Disable PWREN
- (0 << 2) | // ENLEND : Disable LEND signal
- (0 << 1) | // BSWP : Swap Disable
- (1 << 0) ; // HWSWP : Swap Enable
- s2440LCD->rLCDSADDR1 = ((FRAMEBUF_DMA_BASE >> 22) << 21) |
- ((M5D(FRAMEBUF_DMA_BASE >> 1)) << 0);
- s2440LCD->rLCDSADDR2 = M5D((FRAMEBUF_DMA_BASE + (LCD_XSIZE_TFT * LCD_YSIZE_TFT * 2)) >> 1);
- s2440LCD->rLCDSADDR3 = (((LCD_XSIZE_TFT - LCD_XSIZE_TFT) / 1) << 11) | (LCD_XSIZE_TFT / 1);
- // s2440LCD->rLPCSEL |= 0x3; // for aiji
- s2440LCD->rLCDINTMSK |= (3);
- s2440LCD->rTCONSEL &= ~(0x7); // ;;; SHL
- s2440LCD->rTCONSEL |= 0x2; //240*320
- s2440LCD->rTPAL = 0x0;
- s2440LCD->rTCONSEL &= ~((1<<4) | 1); // Disable LCC3600, LCP3600
- s2440IOP->rGPGUP = s2440IOP->rGPGUP & (~(1<<4)) | (1<<4); // Pull-up disbale
- s2440IOP->rGPGCON = s2440IOP->rGPGCON & (~(3<<8)) | (3<<8);
- s2440LCD->rLCDCON5 = s2440LCD->rLCDCON5 & (~(1<<3)) | (1<<3); // PWREN
- s2440LCD->rLCDCON5 = s2440LCD->rLCDCON5 & (~(1<<5)) | (0<<5); // INVPWREN
- s2440LCD->rLCDCON1 |= 1; // Enable LCD output
- #elif (LCD_TYPE == TFT240_320)
- // s2440LCD->rLCDCON1 = (6 << 8) | /* VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz */
- s2440LCD->rLCDCON1 = (12 << 8) | /* VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz */ // ;;; SHL
- (MVAL_USED << 7) | /* 0 : Each Frame */
- (3 << 5) | /* TFT LCD Pannel */
- (12 << 1) | /* 16bpp Mode */
- (0 << 0) ; /* Disable LCD Output */
- s2440LCD->rLCDCON2 = (VBPD << 24) | /* VBPD : 1 */
- (LINEVAL_TFT << 14) | /* Virtical Size : 320 - 1 */
- (VFPD << 6) | /* VFPD : 2 */
- (VSPW << 0) ; /* VSPW : 1 */
- s2440LCD->rLCDCON3 = (HBPD << 19) | /* HBPD : 6 */
- (HOZVAL_TFT << 8) | /* HOZVAL_TFT : 240 - 1 */
- (HFPD << 0) ; /* HFPD : 2 */
- s2440LCD->rLCDCON4 = (MVAL << 8) | /* MVAL : 13 */
- (HSPW << 0) ; /* HSPW : 4 */
- s2440LCD->rLCDCON5 = (0 << 12) | /* BPP24BL : LSB valid */
- (1 << 11) | /* FRM565 MODE : 5:6:5 Format */
- (0 << 10) | /* INVVCLK : VCLK Falling Edge */
- (1 << 9) | /* INVVLINE : Inverted Polarity */
- (1 << 8) | /* INVVFRAME : Inverted Polarity */
- (0 << 7) | /* INVVD : Normal */
- (0 << 6) | /* INVVDEN : Normal */
- (0 << 5) | /* INVPWREN : Normal */
- (0 << 4) | /* INVENDLINE : Normal */
- (0 << 3) | /* PWREN : Disable PWREN */
- (0 << 2) | /* ENLEND : Disable LEND signal */
- (0 << 1) | /* BSWP : Swap Disable */
- (1 << 0) ; /* HWSWP : Swap Enable */
- s2440LCD->rLCDSADDR1 = ((FRAMEBUF_DMA_BASE >> 22) << 21) |
- ((M5D(FRAMEBUF_DMA_BASE >> 1)) << 0);
- s2440LCD->rLCDSADDR2 = M5D((FRAMEBUF_DMA_BASE + (LCD_XSIZE_TFT * LCD_YSIZE_TFT * 2)) >> 1);
- s2440LCD->rLCDSADDR3 = (((LCD_XSIZE_TFT - LCD_XSIZE_TFT) / 1) << 11) | (LCD_XSIZE_TFT / 1);
- // s2440LCD->rLPCSEL |= 0x3; // for aiji
- s2440LCD->rTCONSEL &= ~(0x7); // ;;; SHL
- s2440LCD->rTCONSEL |= 0x2; //240*320
- s2440LCD->rTCONSEL &= ~((1<<4) | 1); // Disable LCC3600, LCP3600
- // s2440LCD->rTCONSEL |= (1<<4); // ;;; SHL
- s2440LCD->rTPAL = 0x0;
- s2440LCD->rLCDCON1 |= 1;
- #endif
- #if (LCD_TYPE == TFT640_480)
- FBuf = (struct FrameBuffer *) (FRAMEBUF_BASE);
- // Test LCD display status with R.G.B and White color.
- for (i=0; i<LCD_YSIZE_TFT/2; i++)
- {
- for (j=0; j<LCD_XSIZE_TFT; j++)
- {
- if (j<LCD_XSIZE_TFT/2)
- #if (LCDTYPE == TFT16BPP)
- FBuf->pixel[i][j]=0xffff;
- #else
- FBuf->pixel[i][j]=0xff;
- #endif
- else
- #if (LCDTYPE == TFT16BPP)
- FBuf->pixel[i][j]=0xf800;
- #else
- FBuf->pixel[i][j]=0xe0;
- #endif
- }
- }
- for (i=LCD_YSIZE_TFT/2; i<LCD_YSIZE_TFT; i++)
- {
- for (j=0; j<LCD_XSIZE_TFT; j++)
- {
- if (j<LCD_XSIZE_TFT/2)
- #if (LCDTYPE == TFT16BPP)
- FBuf->pixel[i][j]=0x07e0;
- #else
- FBuf->pixel[i][j]=0x1c;
- #endif
- else
- #if (LCDTYPE == TFT16BPP)
- FBuf->pixel[i][j]=0x001f;
- #else
- FBuf->pixel[i][j]=0x03;
- #endif
- }
- }
- #elif (LCD_TYPE == TFT240_320)
- memcpy((void *)FRAMEBUF_BASE, ScreenBitmap, ARRAY_SIZE_TFT_16BIT);
- // rle_express(ScreenBitmap, (unsigned short *)FRAMEBUF_BASE, 0x8a8c / 2);
- #endif
- }
- static void OEMInitInterrupts(void) // for KITL 030828
- {
- volatile INTreg *s2440INT = (INTreg *)INT_BASE;
- volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
- // Configure EINT9 for CS8900 interrupt.
- //
- s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 0x2)) | (0x2 << 0x2); // GPG1 == EINT9.
- s2440IOP->rGPGUP = (s2440IOP->rGPGUP | (0x1 << 0x1)); // Disable pull-up.
- s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 0x4)) | (0x1 << 0x4); // Level-high triggered.
- // Configure EINT8 for PD6710 interrupt.
- //
- s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 0x0)) | (0x2 << 0x0); // GPG0 == EINT8.
- s2440IOP->rGPGUP = (s2440IOP->rGPGUP | (0x1 << 0x0)); // Disable pull-up.
- s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 0x0)) | (0x1 << 0x0); // Level-high triggered.
- // Mask and clear all peripheral interrupts (these come through a second-level "GPIO" interrupt register).
- //
- s2440IOP->rEINTMASK = BIT_ALLMSK; // Mask all EINT interrupts.
- s2440IOP->rEINTPEND = BIT_ALLMSK; // Clear pending EINT interrupts.
- // Mask and clear all interrupts.
- //
- s2440INT->rINTMSK = BIT_ALLMSK; // Mask all interrupts (reset value).
- s2440INT->rINTMSK &= ~BIT_BAT_FLT;
- s2440INT->rSRCPND = BIT_ALLMSK; // Clear pending interrupts.
- s2440INT->rINTPND = s2440INT->rINTPND; // S3C2440X developer notice (page 4) warns against writing a 1 to any
- // 0 bit field in the INTPND register. Instead we'll write the INTPND value itself.
- }