📄 flash.cpp
字号:
/*
* $Workfile: Flash.CPP $
* $Revision: 2 $
* $Date: 4/07/00 8:49a $
* $Modtime: 4/07/00 8:37a $
* $Author: Sarma $
*
* Copyright (c) 1998 National Semiconductor Corporation.
* All Rights Reserved.
*
* This software is the confidential and proprietary information of National
* Semiconductor Corporation. ("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
* with National Semiconductor Corporation.
* This code is supplied as is.
*
*/
/*
*$Log: /CE/Platform/Nsc/Drivers/Video/gxvideo/base/Flash.CPP $
*
* 2 4/07/00 8:49a Sarma
* Removed Cyrix Corporation from the legal/confidentail information.
*
* 1 10/14/99 3:02p Sarma
* Added the flash.cpp to help in switching display modes from
* application.
* The ResImg.h has all the images for 640x480, 800x600, 1024x768,
* 1280x1024.
* The atImg.h has the image of @ symbol.
* The Freqimg.h has the images for the frequencies 60Hz, 65Hz, 70Hz,
* 72Hz, 75Hz, 80Hz, 85Hz.
*$History: Flash.CPP $
*
* ***************** Version 2 *****************
* User: Sarma Date: 4/07/00 Time: 8:49a
* Updated in $/CE/Platform/Nsc/Drivers/Video/gxvideo/base
* Removed Cyrix Corporation from the legal/confidentail information.
*
* ***************** Version 1 *****************
* User: Sarma Date: 10/14/99 Time: 3:02p
* Created in $/wince/v2.1/gxvideo
* Added the flash.cpp to help in switching display modes from
* application.
* The ResImg.h has all the images for 640x480, 800x600, 1024x768,
* 1280x1024.
* The atImg.h has the image of @ symbol.
* The Freqimg.h has the images for the frequencies 60Hz, 65Hz, 70Hz,
* 72Hz, 75Hz, 80Hz, 85Hz.
*/
#include "precomp.h"
#include "palette.h"
#include "Resimg.h"
#include "atimg.h"
#include "freqimg.h"
#define IMG_HEIGHT 14
#define IMG_RES_WIDTH 65
#define IMG_AT_WIDTH 20
#define IMG_FREQ_WIDTH 35
extern "C"{
typedef struct _DISPLAY_SETTINGS
{
DWORD Width;
DWORD Height;
DWORD Depth;
DWORD Freq;
} DISPLAY_SETTINGS, * PDISPLAY_SETTINGS, * LPDISPLAY_SETTINGS;
typedef DISPLAY_SETTINGS const * PCDISPLAY_SETTINGS;
typedef DISPLAY_SETTINGS const * LPCDISPLAY_SETTINGS;
//Wait for microSeconds
void wait(int uSec)
{
DEBUGMSG( 1,(TEXT("delay %d\n"),uSec));
unsigned long target = GetTickCount() + uSec;
while (GetTickCount() <= target);
}
void SetDisplayMode(LPCDISPLAY_SETTINGS newMode, LPCDISPLAY_SETTINGS oldMode)
{
GPEMode gpeMode;
int newID, oldID;
DEBUGMSG( 1,(TEXT("SetDisplayMode %d %d %d %d\n"),oldMode->Width, oldMode->Height, oldMode->Depth, oldMode->Freq));
DEBUGMSG( 1,(TEXT("SetDisplayMode %d %d %d %d\n"),newMode->Width, newMode->Height, newMode->Depth, newMode->Freq));
GPE *pGPE = new GxVideo(1);
//set the pallete
// ((GxVideo *)pGPE)->SetPalette(_rgbIdentity, 0, PALETTE_SIZE);
//Display depth is not available in application, we will use the
//currently set depth
gpeMode.Bpp = 8; //test mode
gpeMode.width = oldMode->Width;
gpeMode.height = oldMode->Height;
gpeMode.frequency = oldMode->Freq;
oldID = ((GxVideo *)pGPE)->GetDpyMode(gpeMode);
gpeMode.width = newMode->Width;
gpeMode.height = newMode->Height;
gpeMode.frequency = newMode->Freq;
newID = ((GxVideo *)pGPE)->GetDpyMode(gpeMode);
DEBUGMSG( 1,(TEXT("SetDisplayMode found @ %d\n"),newID));
//Set the new display mode
((GxVideo *)pGPE)->SetTestMode( newID);
//Remove the cursor display
((GxVideo *)pGPE)->ToggleCursor(FALSE);
//Show a bitmap to the user here
((GxVideo *)pGPE)->DisplayTestScreen(newMode->Width,
newMode->Height, 8, newMode->Freq);
//wait for 5 seconds
wait(10000);
//once the display has been tested for new resolution switch to orginal one
((GxVideo *)pGPE)->SetTestMode( oldID);
//put the cursor display
((GxVideo *)pGPE)->ToggleCursor(TRUE);
delete pGPE;
DEBUGMSG( 1,(TEXT("SetDisplayMode exiting\n")));
}
}//"C"
GxVideo::GxVideo(int Test)
{
unsigned char GCRvalue;
unsigned long regaddr;
unsigned long fbaddr;
unsigned long CxId;
unsigned long cx5530addr;
// READ GX PROCESSOR PARAMETERS
ProcessorID = gx_read_processor_id();
GCRvalue = gx_read_gcr();
// SET REGISTER ADDRESS
// Bits [1:0] of the GCR specify the base address.
regaddr = ((unsigned long)(GCRvalue & 0x03)) << 30;
fbaddr = regaddr + 0x00800000;
CxId = GetDeviceId();
switch(CxId)
{
case 0x00001078: //CX5510 present
DeviceId = CX5510;
break;
case 0x00021078: //CX5520 present
DeviceId = CX5520;
break;
case 0x01001078: //CX5530 present
DeviceId = CX5530;
break;
default: //CX5510 present
DeviceId = CX5510;
break;
}
cx5530addr = regaddr + 0x10000;
// SETUP GX REGISTER MEMORY MAPPED ADDRESS RANGE
GXregisters = (unsigned char *)VirtualAlloc(
0,
0x10000, // Reserve 64k of virtual address space
MEM_RESERVE,
PAGE_NOACCESS );
VirtualCopy(
GXregisters,
(LPVOID)(regaddr>>8),
0x10000,
PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);
// SETUP CX5530 MEMORY MAPPED ADDRESS RANGE
CX5530registers = (unsigned char *)VirtualAlloc(
0,
0x10000, // Reserve 64k of virtual address space
MEM_RESERVE,
PAGE_NOACCESS );
VirtualCopy(
CX5530registers,
(LPVOID)(cx5530addr>>8),
0x10000,
PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);
// CHECK SCRATCHPAD SIZE
// Bits [3:2] specify the scratchpad size:
// (0x00 = none, 0x04 = 2K, 0x08 = 3K, 0x0C = 4K)
if (GCRvalue & 0x08)
{
// SET THE BLT BUFFERS FOR 3K (ALSO OK FOR 4K)
BB0_Size_Bytes = 1328;
BB0_Base_Address = 0x400;
BB1_Base_Address = BB0_Base_Address + BB0_Size_Bytes;
execute_cpu_write(GX_BB0_BASE, BB0_Base_Address); // BB0 BASE
execute_cpu_write(GX_BB1_BASE, BB1_Base_Address); // BB1 BASE
}
else
{
// SET THE BLT BUFFERS FOR 2K
BB0_Size_Bytes = 816;
BB0_Base_Address = 0x800;
BB1_Base_Address = BB0_Base_Address + BB0_Size_Bytes;
execute_cpu_write(GX_BB0_BASE, BB0_Base_Address); // BB0 BASE
execute_cpu_write(GX_BB1_BASE, BB1_Base_Address); // BB1 BASE
}
//Default CurrentMode -1
CurrentMode = -1;
DEBUGMSG( 0,(TEXT("%X %X\n"),GXregisters,CX5530registers));
// default to lowest resolution
m_resolution = DDI_640x480x8x60;
m_unlock = 0xFFFFFFFF; //some invalid value
}
//modeId is always ZERO for now
SCODE GxVideo::SetTestMode( int modeId)
{
DISPLAYMODE *pMode;
unsigned long cx55xx_clock, value=0;
DEBUGMSG( 1,(TEXT("GxVideo::SetMode %d\n"),modeId));
//Override the value sent
if( modeId == CurrentMode )
{
// The mode is already set, just return
return S_OK;
}
//Check if the required mode exists
if ((pMode = GetDisplayParams(modeId)) == NULL)
{
DEBUGMSG( 1,(TEXT("GxVideo::SetMode mode %d, Dosen't exist\n"),modeId ));
return E_INVALIDARG;
}
DEBUGMSG( 1,(TEXT("SetMode = id=%d w=%d h=%d bpp=%d Hz=%d fmt=%d\n"),
pMode->gpeMode.modeId, pMode->gpeMode.width, pMode->gpeMode.height,
pMode->gpeMode.Bpp, pMode->gpeMode.frequency, pMode->gpeMode.format));
CurrentMode = modeId; //Save the set mode
m_pMode = &(pMode->gpeMode);
m_nScreenWidth = m_pMode->width;
m_nScreenHeight = m_pMode->height;
m_nScreenStride = (((m_nScreenWidth * m_pMode->Bpp) >> 3) > 1024) ? 2048 : 1024;
#if COMPRESSION_ENABLE
// Enable Compression...
// Clear the "valid" bits in the memory controller
// This must be done before enabling compression so that the display
// controller doesn't accidently read what it thinks to be a compressed
// line. The size of the RAM in the memory controller is 1024 bits,
// which is cleared though registers specifying the index and data value.
for (value = 0; value < 1024; value++) {
WRITE_REG32(GXregisters, MC_DR_ADD, value);
WRITE_REG32(GXregisters, MC_DR_ACC, 0x0);
}
#endif
// UNLOCK THE DISPLAY CONTROLLER REGISTERS
Unlock();
// READ THE CURRENT GX VALUES
gcfg = READ_REG32(GXregisters, DC_GENERAL_CFG);
tcfg = READ_REG32(GXregisters, DC_TIMING_CFG);
ocfg = READ_REG32(GXregisters, DC_OUTPUT_CFG);
// READ THE CURRENT CX5530 VALUES AND BLANK THE CX5530 DISPLAY
dcfg30 = READ_REG32(CX5530registers, CX55xx_DISPLAY_CONFIG);
dcfg30 &= ~(unsigned long) (CX5530_DCFG_DAC_BL_EN
| CX5530_DCFG_DIS_EN | CX5530_DCFG_HSYNC_EN | CX5530_DCFG_VSYNC_EN
| CX5530_DCFG_FP_PWR_EN | CX5530_DCFG_FP_DATA_EN );
WRITE_REG32(CX5530registers, CX55xx_DISPLAY_CONFIG, dcfg30);
// BLANK THE DISPLAY
tcfg &= ~(unsigned long)DC_TCFG_BLKE;
WRITE_REG32(GXregisters, DC_TIMING_CFG, tcfg);
// DISABLE THE TIMING GENERATOR
tcfg &= ~(unsigned long)DC_TCFG_TGEN;
WRITE_REG32(GXregisters, DC_TIMING_CFG, tcfg);
// DELAY: WAIT FOR PENDING MEMORY REQUESTS
// This delay is used to make sure that all pending requests to the
// memory controller have completed before disabling the FIFO load.
delay_milliseconds();
// DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION
gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
WRITE_REG32(GXregisters, DC_GENERAL_CFG, gcfg);
// CLEAR THE "DCLK_MUL" FIELD
gcfg &= ~(unsigned long)(DC_GCFG_DDCK | DC_GCFG_DPCK | DC_GCFG_DFCK);
gcfg &= ~(unsigned long)DC_GCFG_DCLK_MASK;
WRITE_REG32(GXregisters, DC_GENERAL_CFG, gcfg);
if(DeviceId == CX5510)
cx55xx_clock = pMode->cx55xx_clock;
else if(DeviceId == CX5520)
cx55xx_clock = pMode->cx5520_clock;
else if(DeviceId == CX5530)
cx55xx_clock = pMode->cx5530_clock;
// SET THE DOT CLOCK FREQUENCY & SET THE RESET BIT
WRITE_REG32(CX5530registers, CX55xx_DOT_CLK_CONFIG, cx55xx_clock | 0x80000000);
// K1.2 Nick Mati - clear PLL out from max Vco
WRITE_REG32(CX5530registers, CX55xx_DOT_CLK_CONFIG, cx55xx_clock | 0x80000100);
delay_milliseconds();
WRITE_REG32(CX5530registers, CX55xx_DOT_CLK_CONFIG, cx55xx_clock | 0x80000000);
// K1.2
// PROGRAM THE CLOCK FREQUENCY
WRITE_REG32(CX5530registers, CX55xx_DOT_CLK_CONFIG, cx55xx_clock);
// DELAY: WAIT FOR THE PLL TO SETTLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -