dispdrvr.c

来自「该BSP是基于PXA270+WINCE的BSP」· C语言 代码 · 共 1,171 行 · 第 1/3 页

C
1,171
字号
//
// 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.
//
/* 
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.  
** Title to the Material remains with Intel Corporation or its suppliers and licensors. 
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.  
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise 
** Some portion of the Materials may be copyrighted by Microsoft Corporation.
*/

#include <windows.h>
#include <types.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <nkintr.h>
#include <bulverde.h>
#include <ceddk.h>
#include "memdefs.h"

#include "DispDrvr.h"
#define  DEFINE_CURSOR_GLOBALS
#include "cursor.h"

#include "xllp_defs.h"
#include "xllp_serialization.h"
#include "xllp_lcd.h"

#include "xllp_bcr.h"
#include "xllp_ost.h"
#include "xllp_dmac.h"
#include "xllp_i2c.h"
extern XLLP_STATUS_T    XllpDmacInit(void);


extern XLLP_STATUS_T XllpLCDInit(P_XLLP_LCD_T pXllpLCD);
extern void XllpLCDLoadPalette(P_XLLP_LCD_T pXllpLCD);
extern void XllpLCDSuspend(P_XLLP_LCD_T pXllpLCD, int SuspendType);
extern void XllpLCDResume(P_XLLP_LCD_T pXllpLCD);

#define NUM_FRAME_BUFFERS 1

XLLP_LCD_T XllpLCD;
XLLP_STATUS_T status;

#define FRAME_BUFFER_BASE_PHYSICAL FRAME_BUFFER_0_BASE_PHYSICAL

BOOL gDrawCursorFlag = FALSE;
BOOL gInPowerHandler = FALSE;
BOOL bDoRotation     = FALSE;

CRITICAL_SECTION displayMutex;
CRITICAL_SECTION frameDescriptorMutex;

int DispDrvr_cxScreen;
int DispDrvr_cyScreen;
int DispDrvr_cdwStride;  
int activeFrameBuffer=0;
unsigned int frameBufferSize = 0;

PBYTE gDibBuffer        = NULL;     // pointer to first byte of composition buffer
PBYTE gFrameBuffer      = NULL;     // pointer to first byte of screen memory
PBYTE gBlackFrameBuffer = NULL;     // pointer to first byte of screen memory
RECT  gCursorRect;
UINT  nDisplayType;

//Frame buffer. DMA will copy from here to the LCD
DWORD g_DisplayBasePhysical;
DWORD g_DisplayBaseVirtual;

//Black Buffer. DMA will copy from here during idle/suspend IF EnableScreenBlanking RegKey is enabled
DWORD g_DisplayBlackBasePhysical;
DWORD g_DisplayBlackBaseVirtual;

BOOL g_fDisableRotation = FALSE;       //Enable/disable screen rotation 
BOOL g_fEnableDMASourceSwap = FALSE;   //Enable/disable screen blacking with DMA pointer swap

volatile LCDRegs              * v_pLcdRegs                  = NULL;
volatile XLLP_CLKMGR_T        * v_pClkRegs                  = NULL;
volatile XLLP_GPIO_T          * v_pGPIORegs                 = NULL;
volatile LCD_FRAME_DESCRIPTOR * frameDescriptorCh0fd1       = NULL;
volatile LCD_FRAME_DESCRIPTOR * frameDescriptorCh0fd2       = NULL;
volatile LCD_FRAME_DESCRIPTOR * frameDescriptorCh1          = NULL;
volatile LCD_FRAME_DESCRIPTOR * frameDescriptorPalette      = NULL;
volatile LCD_FRAME_DESCRIPTOR * frameDescriptorTemp         = NULL;
volatile LCD_FRAME_DESCRIPTOR * frameDescriptorCh2_YCbCr_Y  = NULL;
volatile LCD_FRAME_DESCRIPTOR * frameDescriptorCh3_YCbCr_Cb = NULL;
volatile LCD_FRAME_DESCRIPTOR * frameDescriptorCh4_YCbCr_Cr = NULL;
volatile LCD_PALETTE          * v_pPaletteBuffer            = NULL;
volatile unsigned int         * pOSCR                       = NULL;

///
volatile unsigned int * v_pOSTRegs = NULL;
volatile unsigned int * v_pCIRegs  = NULL;
volatile unsigned int * v_pI2C     = NULL;
volatile XLLP_DMAC_T  * v_pDMAC    = NULL;

HANDLE hIntEventKnown;
HANDLE hIntEvent;
///

void LCDClearStatusReg();
void LcdSetupGPIOs();
void Cleanup();
void InitLCDController();
void EnableLCDController();
void DisableLCDController();
void InitCursor();
BOOL MapVirtualAddress();
BOOL ReadRegistryData(VOID);
void ClearFrameBuffer(unsigned * fbp, BOOL color);
void ScrollBuffer(int direction);
void Overlay2_Enable(P_XLLP_OVERLAY_T pXllpOverlay);
void Overlay2_Disable(P_XLLP_OVERLAY_T pXllpOverlay);
void Overlay2_DMA_Length(P_XLLP_OVERLAY_T pXllpOverlay);
void ClearDMACInterrupt(int channel);

extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
extern PVOID VirtualAllocCopyPhysical(unsigned size,char *str,PVOID pPhysicalAddress);
extern BOOL VirtualSetAttributes(LPVOID lpvAddress, DWORD cbSize, DWORD dwNewFlags, DWORD dwMask, LPDWORD lpdwOldFlags);
extern void msWait(unsigned int);

unsigned int    halted       = 0;
XLLP_OVERLAY_T  XllpOverlay;
PBYTE           pOverlay2_Y  = NULL;
PBYTE           pOverlay2_Cb = NULL;
PBYTE           pOverlay2_Cr = NULL;
unsigned char * fbpY;
unsigned char * fbpCr;
unsigned char * fbpCb;

//

#define _OPT_ASM

#ifdef _OPT_ASM
    void dirtyRectDump_core_ASM(WORD *pwSrc, WORD *pwDst,int rowLen, DWORD srcWidthB,
            DWORD bytesPerRow, DWORD srcMarginWidth, DWORD dstMarginWidth);

    void DirtyRectDumpPortraitLoop_C(BYTE    *pDstBuf, BYTE  *pSrcBuf, DWORD    yTop, DWORD yBottom,
            DWORD srcWidthB, DWORD bytesPerRow, DWORD bytesPerPixel, DWORD srcMarginWidth, DWORD dstMarginWidth);

    void ellipse_core_ASM(WORD srcColor,DWORD margin,DWORD width,WORD* pDstBuf);
    void DispDrvrDirtyRectDump2(LPCRECT prc,DWORD color);
    void DirtyRectDumpPortraitLoop_C_rectfill(BYTE    *pDstBuf, WORD srcColor,DWORD yTop,DWORD yBottom,
            DWORD srcWidthB, DWORD bytesPerRow, DWORD bytesPerPixel, DWORD srcMarginWidth, DWORD dstMarginWidth);
    void DispDrvrDirtyRectDump_rectfill(LPCRECT prc, DWORD color);

#endif

void DispDrvrSetDibBuffer(void *data)
{
    gDibBuffer = data;        
}

void DispDrvrSetPalette (const PALETTEENTRY source[],unsigned short firstEntry,unsigned short numEntries)
{
    int i;
    int end = firstEntry + numEntries;

    // Don't walk off the end of the palette buffer.
    if (firstEntry > sizeof(source) || end >= sizeof(source))
    {
        return;
    }

    EnterCriticalSection(&frameDescriptorMutex);

    // Store the palette entries into palette ram
    for(i=firstEntry;i<end;i++) 
    {
        // store 5 bits red, 6 bits green, and 5 bits blue
        v_pPaletteBuffer->palette[i] = (
            (source[i].peBlue)            >>  3    |
            ((source[i].peGreen & 0xfc)    <<  3)    |
            ((source[i].peRed    & 0xf8)    <<  8)
            );
    }

    XllpLCDLoadPalette(&XllpLCD);
    
    LeaveCriticalSection(&frameDescriptorMutex);
}

//-------------------------------------------------------------------
typedef struct 
{
	unsigned short	CxScreen;	
	unsigned short	CyScreen;	
	unsigned short	Bpp;
	unsigned long	LCCR0;
	unsigned char	HSW;
	unsigned char	BLW;
	unsigned char	ELW;	
	unsigned char	VSW;
	unsigned char	BFW;
	unsigned char	EFW;
	unsigned char	PCD;
	unsigned long	LCCR3_OTHER;
	unsigned char	DoRotation;
} dDspRegVal;

typedef struct {
    UINT32  signature;
    UINT16  oalVersion;
    UINT16  bspVersion;
} dOAL_ARGS_HEADER;
typedef struct  {
    DWORD IfcType;                  
    DWORD BusNumber;                
    DWORD LogicalLoc;               
    PVOID PhysicalLoc;              
    DWORD Pin;                      
} dDEVICE_LOCATION;
typedef struct {
    UINT32 flags;
    dDEVICE_LOCATION devLoc;             // KITL device location
    union {
        struct {                        // Serial class parameters
            UINT32 baudRate;
            UINT32 dataBits;
            UINT32 stopBits;
            UINT32 parity;
        };         
        struct {                        // Ether class parameters
            UINT16 mac[3];
            UINT32 ipAddress;
            UINT32 ipMask;
            UINT32 ipRoute;
        };
    };
} dOAL_KITL_ARGS;
typedef struct {
    dOAL_ARGS_HEADER header;
    UINT8 deviceId[16];                 // Device identification
    dOAL_KITL_ARGS kitl;
    UINT32 dbgSerPhysAddr;              // Debug serial physical address
    BOOL bUpdateMode;                   // TRUE = Enter update mode on reboot.
    BOOL bHiveCleanFlag;                // TRUE = Clean hive at boot
    BOOL bCleanBootFlag;                // TRUE = Clear RAM, hive, user store at boot
    BOOL bFormatPartFlag;               // TRUE = Format partion when mounted at boot
    UINT32 ImageSignedState;            // enum {IMAGE_NOT_SIGNED, IMAGE_TEST_SIGNED, IMAGE_FINAL_SIGNED}
    dDspRegVal tDspRegVal;  	///
} dBSP_ARGS;

#define GLOB_ARGS_UA_BASE  0xA00FF000	//image_cfg.h: IMAGE_SHARE_ARGS_UA_START
//-------------------------------------------------------------------

void DispDrvrInitialize (void)
{
	//-------------------------------------------------------------------
	dDspRegVal *pDspRegVal;
	dBSP_ARGS *pGlob_args;
	unsigned char mapedBPP;
	
    bpp               = 0;
    DispDrvr_cyScreen = 0;
    DispDrvr_cxScreen = 0;
	bDoRotation = FALSE;

	pGlob_args = (dBSP_ARGS *)GLOB_ARGS_UA_BASE;
	pDspRegVal = &(pGlob_args->tDspRegVal);

	switch(pDspRegVal->Bpp)	{
		case 0x001:		mapedBPP = 0;		break;
		case 0x002:		mapedBPP = 1;		break;
		case 0x004:		mapedBPP = 2;		break;
		case 0x008:		mapedBPP = 3;		break;
		case 0x010:		mapedBPP = 4;		break;
		case 0x020:		mapedBPP = 5;		break;
		case 0x040:		mapedBPP = 6;		break;
		case 0x080:		mapedBPP = 7;		break;
		case 0x100:		mapedBPP = 8;		break;
		case 0x200:		mapedBPP = 9;		break;
		case 0x400:		mapedBPP = 10;		break;
		default:		mapedBPP = 0;		break;
	}	
	DispDrvr_cxScreen = pDspRegVal->CxScreen;
	DispDrvr_cyScreen = pDspRegVal->CyScreen;
	bpp = pDspRegVal->Bpp;
    DispDrvr_cdwStride = DispDrvr_cxScreen * bpp / 8;	// Calculate the stride of the frame buffer

    XllpLCD.LCCR0 = pDspRegVal->LCCR0;
	XllpLCD.LCCR1 = (pDspRegVal->CxScreen-1)|(pDspRegVal->HSW<<10)|(pDspRegVal->BLW<<24)|(pDspRegVal->ELW<<16);
	XllpLCD.LCCR2 = (pDspRegVal->CyScreen-1)|(pDspRegVal->VSW<<10)|(pDspRegVal->BFW<<24)|(pDspRegVal->EFW<<16); 
	XllpLCD.LCCR3 = pDspRegVal->PCD |((((mapedBPP)&0x7)<< 24)|(((mapedBPP)&0x8)<< 26)) |pDspRegVal->LCCR3_OTHER;	

	bDoRotation = pDspRegVal->DoRotation;	//portrait vs landscape
	//-------------------------------------------------------------------

	//-------------------------------------------------------------------
    // Read display driver configuration from system registry
    ///ReadRegistryData();
	//-------------------------------------------------------------------

    frameBufferSize = bpp / 8 * DispDrvr_cxScreen * DispDrvr_cyScreen;

    // Map registers, the frame buffer, and frame descriptors from Kernel mode virtual address 
    // into our user mode virtual address space
    if (!MapVirtualAddress())
    {
        return;
    }

    // Initialize for use with Suspend resume macros
    msWait(1);

    XllpLCD.GPIO = (XLLP_VUINT32_T *) v_pGPIORegs;
    XllpLCD.CLKMan = (XLLP_VUINT32_T *) v_pClkRegs; 
    XllpLCD.LCDC = (XLLP_VUINT32_T *) v_pLcdRegs;
    XllpLCD.DisplayType = nDisplayType;
    XllpLCD.FrameBufferWidth = DispDrvr_cxScreen;
    XllpLCD.FrameBufferHeight = DispDrvr_cyScreen;
    XllpLCD.BPP = BPP_16;
    XllpLCD.PixelDataFormat = PDFOR_00; //with overlays enabled use PDFOR_11 for 16bpp
    XllpLCD.CurrentPage = 0;
    XllpLCD._FRAME_BUFFER_BASE_PHYSICAL = FRAME_BUFFER_BASE_PHYSICAL;
    XllpLCD._PALETTE_BUFFER_BASE_PHYSICAL = PALETTE_BUFFER_BASE_PHYSICAL;
    XllpLCD._DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_PHYSICAL = DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_PHYSICAL;    
    XllpLCD._DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_PHYSICAL = DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_PHYSICAL;
    XllpLCD._DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_PHYSICAL = DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_PHYSICAL;
    XllpLCD._PALETTE_FRAME_DESCRIPTOR_BASE_PHYSICAL = PALETTE_FRAME_DESCRIPTOR_BASE_PHYSICAL;
    XllpLCD.frameDescriptorCh0fd1 = frameDescriptorCh0fd1;
    XllpLCD.frameDescriptorCh0fd2 = frameDescriptorCh0fd2;
    XllpLCD.frameDescriptorCh1 = frameDescriptorCh1;
    XllpLCD.frameDescriptorPalette = frameDescriptorPalette;
    XllpLCD.frameDescriptorTemp = frameDescriptorTemp;

    InitializeCriticalSection(&displayMutex);
    InitializeCriticalSection(&frameDescriptorMutex);

    // Initialize Cursor
    InitCursor();
    
    ClearFrameBuffer((unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize), TRUE);

    if( g_fEnableDMASourceSwap ) 
    {
        ClearFrameBuffer((unsigned *)gBlackFrameBuffer, FALSE);
    }

    // Initialize the LCD Controller and Board Control Register
    XllpLCDInit(&XllpLCD);

    //InitRegs((XLLP_OST_T *)v_pOSTRegs, (P_XLLP_I2C_T)v_pI2C);

    XllpI2cInit((P_XLLP_I2C_T)v_pI2C, (P_XLLP_GPIO_T) v_pGPIORegs, (P_XLLP_CLKMGR_T) v_pClkRegs, (XLLP_UINT32_T) 0);
    
    pOSCR = v_pOSTRegs + 4;

    // Use this event to signal the IST that we now know the dynamically assigned DMA channel
    // And with that information, we know which event to wait on for the interrupt.
    hIntEventKnown = CreateEvent(NULL,FALSE,FALSE,NULL);


    RETAILMSG(1,(TEXT("Display Driver Initialization Complete\r\n")));

    return;
}

void InitCursor()
{
    gDrawCursorFlag = FALSE;
    gCursorRect.left = (DispDrvr_cxScreen - CURSOR_XSIZE) >> 1;
    gCursorRect.right = gCursorRect.left + CURSOR_XSIZE;
    gCursorRect.top = (DispDrvr_cyScreen - CURSOR_YSIZE) >> 1;
    gCursorRect.bottom = gCursorRect.top + CURSOR_YSIZE;
    gxHot = gyHot = 0;
    memset ((BYTE *)gCursorMask, 0xFF, sizeof(gCursorMask));
}

BOOL MapVirtualAddress()
{
    DMA_ADAPTER_OBJECT Adapter;
    PHYSICAL_ADDRESS   PhysAddr;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?