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 + -
显示快捷键?