my_mq200.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 258 行
C
258 行
/*****************************************************************************
* File: my_mq200.c
* Author: Naresh Gupta
* Synopsis: Picked up some initialization code from MQ200 spec and sample
* code.
*****************************************************************************/
#include <StandAlone.h>
#include <platform.h>
/* USer modifiable paramters. */
#define MQ200_REGBASE 0xA7E00000
#define uBUSW 4 // processor bus width
#define MQ200_DEVICE 0x02004D51 // device=0x0100, vendor=0x0000
////////////////////////////////////////////////////////////////////////////////////
// DC (Device Configuration Unit) Registers
//
#define DC_0 (0x00 * uBUSW) // Device Configruation Register 0
#define DC_1 (0x01 * uBUSW) // Device Configruation Register 1
#define DC_SW_0 (0x02 * uBUSW) // Software Register 0
#define DC_SW_1 (0x03 * uBUSW) // Software Register 1
#define M_SIZE 0x00002000L // Size of each MQ module (8KB)
// MQ200 module offset
//
#define PM_BASE 0 // Power Management + Clk Gen
#define CC_BASE (PM_BASE+M_SIZE) // CPU interface
#define MM_BASE (CC_BASE+M_SIZE) // Memory Controller (m1/m2)
#define VI_BASE (MM_BASE+M_SIZE) // Video-in controller
#define IN_BASE (VI_BASE+M_SIZE) // Interrupt controller
#define GC_BASE (IN_BASE+M_SIZE) // Graphics Controller 1/2
#define GE_BASE (GC_BASE+M_SIZE) // Graphics engine
#define FP_BASE (GE_BASE+M_SIZE) // Flat panel interface
#define C1_BASE (FP_BASE+M_SIZE) // Color palette 1
#define C2_BASE (C1_BASE+M_SIZE) // Color palette 2
#define DC_BASE (C2_BASE+M_SIZE) // Device Configuration Space
#define PC_BASE (DC_BASE+M_SIZE) // PCI Configuration Header
#define PSF_BASE (PC_BASE+M_SIZE) // Primary Source FIFO Space
#define SSF_BASE (PSF_BASE+M_SIZE) // Secondary Source FIFO Space
#define LAST_BASE (PSF_BASE+M_SIZE) // First byte outside of MMIO
#define GE2_BASE (GE_BASE+0x200 ) // Graphics engine (GE2)
#define MMIO_SIZE (LAST_BASE - PM_BASE) // memory-mapped size
#define FB_SIZE 0x200000L // 2MB memory
#define LAST_ADDR 0x200000L
#define LAST_KB 1024
#define GC_OFFSET 0x80
///////////////////////////////////////////////////////////////////////////////
//
////
// PCI Power Management Interface Registers
//
#define PCI_VENDOR_DEVICE 0x00
#define PCI_CMD_STATUS 0x04
#define PCI_REV_CLASS 0x08
#define PCI_HEADER_TYPE 0x0c
#define PCI_SUB_ID 0x2c
#define PCI_ROM_BASE 0x30
#define PCI_CAP_PTR 0x34
#define PCI_INTERRUPT 0x3c
#define PCI_PM_REGISTER 0x40
#define PCI_PM_CNTL_STATUS 0x44
// POWER_STATE
//
#define POWER_STATE_MASK 0x00000003UL // Device power state mask
#define ENTER_D0 0x00000000UL // Enter D0 state
#define ENTER_D1 0x00000001UL // Enter D1 state
#define ENTER_D2 0x00000002UL // Enter D2 state
#define ENTER_D3 0x00000003UL // Enter D3 state
#define REG32(base, id) (*((volatile unsigned *)(m_pMMIO+(base)+(id))))
#define dcREG(id,data) (REG32(DC_BASE,id)=data)
#define pciREG(id,data) (REG32(PC_BASE,id)=data)
#define pciREAD(id) (REG32(PC_BASE,id))
//This macro wait for a certain power state
#define CHECK_IF_STATE_D(s) \
{ \
ULONG ulState = (s); \
ULONG ulPMReg; \
\
while (1) \
{ \
ulPMReg = pciREAD(PCI_PM_CNTL_STATUS); \
if ((ulPMReg & 0x03L) == ulState) \
break; \
} \
}
volatile unsigned char *m_pMMIO;
unsigned glbTmp;
#define Sleep(x) { for(glbTmp = 0; glbTmp < (x*1000); glbTmp++); }
int mq200_init(void)
{
unsigned ulDC0 = 0xEF2082A; // 0x0EB22A2A; /* Hopefully !!! */
int retries = 0;
unsigned val;
unsigned dev_ven;
RETAILMSG(1,( TEXT("+mq200_init()\r\n")));
/* Initialize m_pMMIO to the base address. */
m_pMMIO = (unsigned char *)MQ200_REGBASE;
/* Bring out the chip from the Reset state. Not sure whether this is
* required for MQ also or only for 465 */
*(volatile unsigned long *) 0xB8000000 = 0x02000040;
dev_ven = REG32(PC_BASE, 0);
DEBUGMSG(1, (TEXT("PC_BASE = 0x%x, Got Device ID, Vendor ID = 0x%x, Expected = 0x%x\r\n"), PC_BASE, dev_ven, MQ200_DEVICE));
if(dev_ven != MQ200_DEVICE) {
DEBUGMSG(1, (TEXT("Wrong Device !!. Still trying to initialize\n")));
}
/* Try detecting MQ device in the PCI Configuration space of MQ chip first. */
/* pp 5-7. Upon initialization the MQ200 is in PM state D3.
* Bring it to D0
*/
dcREG(DC_0, ulDC0); //Always from OSC and used to drive MIU/GE
//50Mhz=0x0EB22A2A, 83MHz=0x0EF2082A
pciREG(PCI_PM_CNTL_STATUS, ENTER_D0);
do {
retries ++;
Sleep(40);
/* Read back PMCSR to see whether the chip got initialized properly */
/* If not then loop back to wait. */
val = REG32(PC_BASE, PCI_PM_CNTL_STATUS);
DEBUGMSG(1, (TEXT("PMCSR reads back 0x%x\n"), val));
if(val == 0) {
DEBUGMSG(1, (TEXT("Entered power management state %d\n"), val));
break;
}
} while(retries < 10);
if(retries >= 10) {
ERRORMSG(1, (TEXT("Could not initialize MQ200 in %d tries\r\n"), retries));
return 1;
}
CHECK_IF_STATE_D(0); //Make sure in a stable state
//- shouldn't be necessary here !!!
RETAILMSG(1,( TEXT("MQGC::SetMQMode - in D0 state now ...\r\n")));
#if 0
Sleep(80);
if ( pciREAD(PCI_VENDOR_DEVICE) != MQ200_DEVICE )
{
RETAILMSG(1,( TEXT("MQGC::ID=%08x ...\r\n"),pciREAD(PCI_VENDOR_DEVICE)));
RETAILMSG(1,( TEXT("MQGC::SetMQMode - invalid Device ID ...\r\n")));
return;
}
if ( m_ulBPP >= 8UL )
{
//Enable GE if >= 8bpp. Use PLL1 as initial clk src for GE.
pmuREG(PM_MISC, (GE_ENABLE | GE_BY_PLL1) );
}
//To initialize MIU bloc,:
//
miuREG(MIU_CONTROL1, DRAM_RESET_DISABLE);
Sleep(100);
miuREG(MIU_CONTROL1, 0x00);
Sleep(50);
//ulMIU2 = 0x40EA0020; // PLL1=MIU,trun on bit 30 for rev1a
ulMIU2 = 0x00EA0086; // PLL1=MIU,trun on bit 30 for rev1a
//ulMIU2 = 0x00EA0087; // PLL2=MIU,trun on bit 30 for rev1a
//ulMIU3 = 0x6d0ddc00;
ulMIU3 = 0x6d6aabff;
ulMIU5 = 0x10d;
ulMIU4 = 0x00000001;
miuREG(MIU_CONTROL2, ulMIU2);
miuREG(MIU_CONTROL3, ulMIU3);
// MIU REG 5 MUST BE PROGRAMMED BEFORE MIU REG 4
miuREG(MIU_CONTROL5, ulMIU5);
miuREG(MIU_CONTROL4, ulMIU4);
Sleep(10); //Step 2
miuREG(MIU_CONTROL1, MIU_ENABLE | MIU_RESET_DISABLE);
Sleep(50);
// MIU init complete ...
// Set up gc1 stride and start address
gc1REG(IW1_STRIDE, ulIW_StrideXX);
gc1REG(IW1_START_ADDR, ulIW_StartAddrXX);
// flat panel registers
if (m_nDSTNFBControl != -1) // DSTN is used in the system
fpREG(DSTN_FB_CONTROL, m_nDSTNFBControl);
//Set up the rest of flat panel registers - depend on panel type
fpREG(FP_CONTROL, m_pFPControl->ulFPControl);
fpREG(FP_PIN_CONTROL, m_pFPControl->ulFPPinControl);
fpREG(FP_GPO_CONTROL, OemInfo.ulFPGPO);
fpREG(FP_GPIO_CONTROL, OemInfo.ulFPGPIO);
fpREG(STN_CONTROL, m_pFPControl->ulSTNControl);
fpREG(PWM_CONTROL, ulTemp);
//FRC is NOT needed for TFT panel
if ( (m_pFPControl->ulFPControl & FP_TYPE_MASK) != FP_TYPE_TFT )
{
int i;
for ( i = 0; i < FRC_PATTERN_CNT; i++ )
fpREG((FRC_PATTERN + i * uBUSW), FRCControlData[0].ulFRCPattern[i]);
for ( i = 0; i < FRC_WEIGHT_CNT; i++ )
fpREG((FRC_WEIGHT + i * uBUSW), FRCControlData[0].ulFRCWeight[i]);
}
// Set up CRT control register - don't enable yet
gc1REG(GC1_CRT_CONTROL, BLANK_PED_ENABLE);
// GC timing
gcREG(ulGCBase, HW1_CONTROL, ulHW_ControlLCD);
gcREG(ulGCBase, VW1_CONTROL, ulVW_ControlLCD);
gcREG(ulGCBase, HD1_CONTROL, m_pFPControl->ulHD);
gcREG(ulGCBase, VD1_CONTROL, m_pFPControl->ulVD);
gcREG(ulGCBase, HS1_CONTROL, m_pFPControl->ulHS);
gcREG(ulGCBase, VS1_CONTROL, m_pFPControl->ulVS);
// 640x480x8 60Hz, use pll3 to driver LCD and CRT at simultaneous mode
// PLL3=0x00a30930 (25.175MHz)
gcREG(ulGCBase,GC1_CONTROL, ulTemp);
#ifdef NKCH
HW_Enable_LCD( GC1 );
HW_Enable_CRT( GC1 );
Done.
see other files for reference regarding data structure, timing etc.
#endif NKCH
#endif 0
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?