📄 dispdrvr.c
字号:
// Copyright (c) David Vescovi. All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
// 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.
//
/*++
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.
Module Name: dispdrvr.c
Date Created: 9/22/2003
Abstract: LCD display driver primary routines.
Functions:
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <nkintr.h>
#include <ceddk.h>
#include "bsp.h"
#include "palette.h"
#define DEFINE_CURSOR_GLOBALS
#include "cursor.h"
#define NONE (0)
#define LTM04C380K (1) // Sandgate 640x480 active
#define LTM04C387S (2) // Sandgate 640x480 active
#define LQ039Q2DS54 (3) // Sandgate 320x240 active
#define LM8V31 (4) // Lubbock 640x480 passive
#define LM057QCTT03 (5) // Lubbock 320x240 passive
#define TFTQVGA (6) // Lubbock 320x240 active
#define LQ64D341 (7) // Lubbock 220x176 active
#define NUM_FRAME_BUFFERS 1
#define DMA_DESC_SIZE 0x20
#define PALETTE_BUFFER_SIZE 0x400
#define FRAME_BUFFER_SIZE 0x96000
#define DISPLAY_BUFFER_SIZE 0x2b0000
DWORD g_DisplayBasePhysical;
DWORD g_DisplayBaseVirtual;
#define RESERVED_DISPLAY_BASE_PHYSICAL g_DisplayBasePhysical
#define RESERVED_DISPLAY_BASE_VIRTUAL g_DisplayBaseVirtual
#define DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_PHYSICAL (RESERVED_DISPLAY_BASE_PHYSICAL + 0)
#define DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_VIRTUAL (RESERVED_DISPLAY_BASE_VIRTUAL + 0)
#define DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_PHYSICAL (DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_PHYSICAL + DMA_DESC_SIZE)
#define DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_VIRTUAL (DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_VIRTUAL + DMA_DESC_SIZE)
#define DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_PHYSICAL (DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_PHYSICAL + DMA_DESC_SIZE)
#define DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_VIRTUAL (DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_VIRTUAL + DMA_DESC_SIZE)
#define PALETTE_FRAME_DESCRIPTOR_BASE_PHYSICAL (DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_PHYSICAL + DMA_DESC_SIZE)
#define PALETTE_FRAME_DESCRIPTOR_BASE_VIRTUAL (DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_VIRTUAL + DMA_DESC_SIZE)
#define PALETTE_BUFFER_BASE_PHYSICAL (PALETTE_FRAME_DESCRIPTOR_BASE_PHYSICAL + DMA_DESC_SIZE)
#define PALETTE_BUFFER_BASE_VIRTUAL (PALETTE_FRAME_DESCRIPTOR_BASE_VIRTUAL + DMA_DESC_SIZE)
#define FRAME_BUFFER_0_BASE_PHYSICAL (PALETTE_BUFFER_BASE_PHYSICAL + PALETTE_BUFFER_SIZE)
#define FRAME_BUFFER_0_BASE_VIRTUAL (PALETTE_BUFFER_BASE_VIRTUAL + PALETTE_BUFFER_SIZE)
#define FRAME_BUFFER_1_BASE_PHYSICAL (FRAME_BUFFER_0_BASE_PHYSICAL + FRAME_BUFFER_SIZE)
#define FRAME_BUFFER_1_BASE_VIRTUAL (FRAME_BUFFER_0_BASE_VIRTUAL + FRAME_BUFFER_SIZE)
BOOL gDrawCursorFlag = FALSE;
BOOL gInPowerHandler = FALSE;
BOOL bDoRotation = FALSE;
BOOL bAllowOSFrameBufferUpdates = TRUE;
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 gBlankFrameBuffer=NULL; // pointer to first byte of screen memory
int gDibBufferWidth;
int gDibBufferHeight;
RECT gCursorRect;
UINT nDisplayType;
void* DispDrvrPhysicalFrameBuffer = NULL;
BOOL gUseDispDrvrPhysicalFrameBuffer = FALSE;
volatile LCD_REG_T *v_pLcdRegs = NULL;
volatile PWM_REG_T *v_pPwm1Regs = NULL;
volatile CLK_REG_T *v_pClkRegs = NULL;
volatile OST_REG_T *v_pOstRegs = NULL;
volatile LCD_FRAME_DESCRIPTOR_T *frameDescriptorCh0fd1 = NULL;
volatile LCD_FRAME_DESCRIPTOR_T *frameDescriptorCh0fd2 = NULL;
volatile LCD_FRAME_DESCRIPTOR_T *frameDescriptorCh1 = NULL;
volatile LCD_FRAME_DESCRIPTOR_T *frameDescriptorPalette = NULL;
volatile LCD_FRAME_DESCRIPTOR_T *frameDescriptorTemp = NULL;
volatile LCD_PALETTE_T *v_pPaletteBuffer = NULL;
// Instantiate the 8 bit palette
INSTANTIATE_PALETTE
void usStall(UINT32 microSeconds);
void LCDClearStatusReg();
//BOOL LCDSetupGPIOs(void);
void Cleanup();
void InitLCDController();
void EnableLCDController();
void DisableLCDController();
void InitCursor();
BOOL MapVirtualAddress();
BOOL ReadRegistryData(VOID);
void CopyFrameBuffer(BOOL gDirection);
void ClearFrameBuffer(BOOL color);
void DisplayPageBuffer(int page);
void ScrollBuffer(int direction);
//unsigned int GetDescriptorAddress(unsigned int physical_address);
void ConfigureFrameBufferSectionDescriptor(unsigned int descriptor);
#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 usStall(UINT32 microSeconds)
{
UINT32_T expireTime, time;
time = v_pOstRegs->OSCR;
expireTime = time + (microSeconds * OEM_TICKS_1US);
if (expireTime < time)
{
while (time < v_pOstRegs->OSCR);
}
while (v_pOstRegs->OSCR <= expireTime);
}
void DispDrvrSetDibBuffer(void *data)
{
gDibBuffer = data;
ClearFrameBuffer(FALSE);
}
void DispDrvrSetPalette (const PALETTEENTRY source[],unsigned short firstEntry,unsigned short numEntries)
{
int i;
int end = firstEntry + numEntries;
EnterCriticalSection(&frameDescriptorMutex);
if (end > 256)
{
end = 256;
}
// 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)
);
}
// Reconfigure the second frame descriptor so that when loaded,
// this descriptor loops to itself.
frameDescriptorCh0fd2->FDADR = LCD_FDADR(frameDescriptorCh0fd2->PHYSADDR);
// Reconfigure the palette frame descriptor so that it loads the second frame descriptor
frameDescriptorPalette->FDADR = LCD_FDADR(frameDescriptorCh0fd2->FDADR);
frameDescriptorPalette->FSADR = LCD_FSADR(PALETTE_BUFFER_BASE_PHYSICAL);
frameDescriptorPalette->FIDR = LCD_FIDR(0);
frameDescriptorPalette->LDCMD = LCD_Len(512) | LCD_Pal; // 2^bpp * 2;
frameDescriptorPalette->PHYSADDR = LCD_FDADR(PALETTE_FRAME_DESCRIPTOR_BASE_PHYSICAL);
// Insert the palette descriptor into the descriptor chain to load the palette.
// When this load completes, fd2 is automatically loaded next in the chain.
// fd2 now loops to itself and continues to load frame data.
frameDescriptorCh0fd1->FDADR = LCD_FDADR(PALETTE_FRAME_DESCRIPTOR_BASE_PHYSICAL);
// swap frame descriptor pointers so that this operation is reversed the next time through
frameDescriptorTemp = frameDescriptorCh0fd1;
frameDescriptorCh0fd1 = frameDescriptorCh0fd2;
frameDescriptorCh0fd2 = frameDescriptorTemp;
LeaveCriticalSection(&frameDescriptorMutex);
}
void DispDrvrInitialize (void)
{
// 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 virtual addresse
// into our user mode virtual address space
if (!MapVirtualAddress())
return;
InitializeCriticalSection(&displayMutex);
InitializeCriticalSection(&frameDescriptorMutex);
// Initialize Cursor
InitCursor();
// Initialize the GPIO registers for proper LCD Controller operation
// if (!LCDSetupGPIOs())
// {
// DEBUGMSG(1, (TEXT("PXA255 Video: WARNING: Failed to configure display GPIO signals.\r\n")));
// }
// Clear the frame buffer
ClearFrameBuffer(TRUE);
// Initialize the LCD Controller and backlight
InitLCDController();
// Clear LCD Controller status register
LCDClearStatusReg();
// Enable the LCD controller
EnableLCDController();
// If required, load the default palette into palette ram
// and feed this to the LCD controller.
if (bpp < 16)
{
DispDrvrSetPalette(_rgbIdentity,0,PALETTE_SIZE);
}
RETAILMSG(1,(TEXT("InitializeDisplayHardware Complete\r\n")));
return;
}
void DisableLCDController()
{
// Copy the active frame buffer into a temporary buffer
// because we are going to write over the active frame buffer
// with a blank all black display. When we restore the display
// when we wake up, we want to be able to copy the original
// frame buffer back in.
CopyFrameBuffer(TRUE);
// Turn the display to black
// and allow a few frames to display
ClearFrameBuffer(FALSE);
usStall(100000);
// Initiate power down sequence
v_pLcdRegs->LCCR0 |= LCD_DIS;
// Wait for LDD bit to get set once the last DMA transfer has completed
while (!(v_pLcdRegs->LCSR & LCD_LDD));
// Clear the sticky LDD bit
v_pLcdRegs->LCSR |= LCD_LDD;
}
void EnableLCDController()
{
v_pLcdRegs->LCCR0 |= LCD_ENB;
}
void InitLCDController()
{
unsigned int BPP = 0;
v_pLcdRegs->LCCR0 = 0;
v_pLcdRegs->LCCR1 = 0;
v_pLcdRegs->LCCR2 = 0;
v_pLcdRegs->LCCR3 = 0;
// Configure the general purpose frame descriptors
// Set the physical address of the frame descriptor
frameDescriptorCh0fd1->FDADR = LCD_FDADR(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_PHYSICAL);
// Set the physical address of the frame buffer
frameDescriptorCh0fd1->FSADR = LCD_FSADR(FRAME_BUFFER_0_BASE_PHYSICAL);
// Clear the frame ID
frameDescriptorCh0fd1->FIDR = LCD_FIDR(0);
// Set the DMA transfer length to the size of the frame buffer
frameDescriptorCh0fd1->LDCMD = LCD_Len(frameBufferSize);
// Store the physical address of this frame descriptor in the frame descriptor
frameDescriptorCh0fd1->PHYSADDR = frameDescriptorCh0fd1->FDADR;
// frameDescriptorCh0fd2 is used only if a palette load is performed.
// Set the physical address of the frame descriptor
frameDescriptorCh0fd2->FDADR = LCD_FDADR(DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_PHYSICAL);
// Set the physical address of the frame buffer
frameDescriptorCh0fd2->FSADR = LCD_FSADR(FRAME_BUFFER_0_BASE_PHYSICAL);
// Clear the frame ID
frameDescriptorCh0fd2->FIDR = LCD_FIDR(0);
// Set the DMA transfer length to the size of the frame buffer
frameDescriptorCh0fd2->LDCMD = LCD_Len(frameBufferSize);
// Store the physical address of this frame descriptor in the frame descriptor
frameDescriptorCh0fd2->PHYSADDR = frameDescriptorCh0fd2->FDADR;
// FBR0 is cleared and is not used.
v_pLcdRegs->FBR0 = 0;
// Load the contents of FDADR0 with the physical address of this frame descriptor
v_pLcdRegs->FDADR0 = LCD_FDADR(frameDescriptorCh0fd1->FDADR);
// Convert the bpp setting into a value that the LCD controller understands.
switch (bpp)
{
case 1:
{
BPP = 0;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -