⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smi.cpp

📁 VoyagerGX display driver for Windows CE .NET 5.XX Silicon Motion, Inc. VoyagerGX Driver is architec
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*++
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.
Copyright (c) 1997-2000 Microsoft and/or its suppliers. All rights reserved.
Copyright (c) 2002 Silicon Motion, Inc.

Module Name:    smi.cpp

Abstract:       Main initialization and display set-modes codes

Notes:

--*/


#include "precomp.h"

#ifdef SMI_LINEARPATCH
#include <wdm.h>
#endif

#include "bootarg.h"

#ifdef HOST_ENABLE
#ifdef XSCALE
#include <xsc1.h>
#include <gpio.h>
#include <lcd.h>
#ifdef UMA
#include <memdefs.h>
#endif
#endif
#endif

// Specify all the required functions and variables for WinCE 3.00 and 4.00 compability
#if (_WINCEOSVER == 300) // For CE 300--

// Create own palette entries
#include "palette.h"
INSTANTIATE_PALETTE
#define MONITORS_MAX	1
class GPE* (*pfnGetGPEPerCard)(int);

#else // For CE400++

// Use system palette entries, 8Bpp we use the natural palette
#include <syspal.h>

#endif

// DEBUG ZONE definition (found in GPE.H)
// #define GPE_ZONE_ERROR              DEBUGZONE(0)  = 0x0001
// #define GPE_ZONE_WARNING    		   DEBUGZONE(1)  = 0x0002
// #define GPE_ZONE_PERF               DEBUGZONE(2)  = 0x0004
// #define GPE_ZONE_TEMP               DEBUGZONE(3)  = 0x0008
//
// #define GPE_ZONE_ENTER              DEBUGZONE(4)  = 0x0010
// #define GPE_ZONE_INIT               DEBUGZONE(5)  = 0x0020
// #define GPE_ZONE_BLT_HI             DEBUGZONE(6)  = 0x0040
// #define GPE_ZONE_BLT_LO             DEBUGZONE(7)  = 0x0080
// 
// #define GPE_ZONE_CREATE             DEBUGZONE(8)  = 0x0100
// #define GPE_ZONE_FLIP               DEBUGZONE(9)  = 0x0200
// #define GPE_ZONE_LINE               DEBUGZONE(10) = 0x0400
// #define GPE_ZONE_HW                 DEBUGZONE(11) = 0x0800
// 
// #define GPE_ZONE_POLY               DEBUGZONE(12) = 0x1000
// #define GPE_ZONE_CURSOR             DEBUGZONE(13) = 0x2000
// #define GPE_ZONE_                   DEBUGZONE(14) = 0x4000
// #define GPE_ZONE_                   DEBUGZONE(15) = 0x8000

// Start with Errors, warnings, and init messages
INSTANTIATE_GPE_ZONES(0x0023, "SMI Driver", "unused1", "unused2")


// Specify all macros here
#define	DRIVER_REGISTRY_STRING				TEXT("Drivers\\Display\\SMIVGX")
#define	DRIVER_MULTIMON_REGISTRY_STRING		TEXT("Drivers\\Display\\SMIVGX\\MONITOR")
#define	MONITOR_REGISTRY_STRING 			TEXT("SYSTEM\\GDI\\MONITORS")

#define dim(x)								(sizeof(x) / sizeof(x[0]))

// Macro for printing debug messages
#if 1
// Print messages only in DEBUG mode
#define MESSAGE DEBUGMSG
#define MESSAGE_ZONE GPE_ZONE_WARNING
#else
// Force messages even in RELEASE mode
#define MESSAGE RETAILMSG
#define MESSAGE_ZONE 0
#endif

// Specify all global variables here
#ifdef DD_ENABLE
static DDGPE	*pGPE = (DDGPE *)NULL;
#else // ! DD_ENABLE
static GPE		*pGPE = (GPE *)NULL;
#endif // DD_ENABLE

static SMI			*pSMI[MONITORS_MAX]={NULL};
static DWORD 		g_dwMonitorsExpected=1;
static SMISETTINGS 	g_DefaultSettings;
static TCHAR 		g_szBaseInstance[256];
PUCHAR              g_pREG;
BOOL                g_bSaveSurface = FALSE;

#ifdef ENABLE_DIRECT3D
SMI*	ppdev	= (SMI*)NULL;
_SMDMA   gblSMDMA;		//_SMDMA defined in smdma.h
#endif // ENABLE_DIRECT3D

// Specify all global functions here
// This prototype avoids problems exporting from .lib
BOOL APIENTRY GPEEnableDriver(ULONG iEngineVersion, ULONG cj, DRVENABLEDATA *pded, PENGCALLBACKS pEngCallbacks);
GPE *GetGPEPerCard(int iCard);

#if (_WINCEOSVER==420)
int (__cdecl* pfnDrvGradientFill)(struct _SURFOBJ *,struct _CLIPOBJ *,struct _XLATEOBJ *,struct _TRIVERTEX *,
	unsigned long,void *,unsigned long,struct _RECTL *,struct _POINTL *,unsigned long) = NULL;
#endif

// DisplayInit
//
// GWES will invoke this routine once prior to making any other calls into the driver.
// This routine needs to save its instance path information and return TRUE.  If it
// returns FALSE, GWES will abort the display initialization.
//
// Inputs:		pszInstance = Instance name of SMI driver
//				g_dwNumMonitors = Number of monitors expected to be supported
//
// Returns:		See description above
//
BOOL APIENTRY DisplayInit(LPCTSTR pszInstance, DWORD dwNumMonitors)
{
    DEBUGMSG(GPE_ZONE_INIT, (TEXT("SMI: Display instance '%s', Num monitors = %d\r\n"),
		pszInstance != NULL ? pszInstance : TEXT("<NULL>"), dwNumMonitors));
	
    // if we expect to be a PCI device, then there must be an instance
    if(pszInstance != NULL) 
    {
        // save our first instance path (without instance specifier) along with
		// the number of monitors we expect to support
        _tcsncpy(g_szBaseInstance, pszInstance, dim(g_szBaseInstance));
        //g_szBaseInstance[_tcslen(g_szBaseInstance) - 1] = 0;
    }
	else
	{
		g_szBaseInstance[0] = 0;
	}

	g_dwMonitorsExpected = dwNumMonitors;
	
    return TRUE;
}


//
// DrvEnableDriver
//
// This function sets up the main entry point of the GPE compliant Display Driver.
// GetGPE and GetGPEPerCard
//
BOOL APIENTRY DrvEnableDriver(ULONG iEngineVersion, ULONG cj, DRVENABLEDATA *pded, PENGCALLBACKS pEngCallbacks)
{
    pfnGetGPEPerCard = GetGPEPerCard;
	return GPEEnableDriver(iEngineVersion, cj, pded, pEngCallbacks);
}


//
//	VirtualAddress
//
//	Translate and convert a physical address range into a virtual address range.
//  NOTE: This is probably where most platform compability needs to be addressed
//        eg. Certain platform may not support MMMapIoSpace, they may instead
//            need VirtualAlloc, VirtualCopy combination.
//            OR. They may not support HalTranslateBusAddress, thus need to 
//                use other functions.
//
//  Inputs: 	StartAddress = PCI Address of the hardware
//         		Length       = Size of the memory space required
//
//  Returns: 	Accessible virtual address of StartAddress
//
PUCHAR VirtualAddress(ULONG StartAddress, ULONG Length)
{
#ifndef HOST_ENABLE
	ULONG inIoSpace;
#endif
	PHYSICAL_ADDRESS ioPhysicalBase;
	PUCHAR pjAddress;

#if 0	// Enable this section of the code for certain platforms, as necessary

	// Some platform may not need this part... 

#else
	// Do translate to System address
#ifndef HOST_ENABLE	
	inIoSpace = 0;
#endif
	ioPhysicalBase.HighPart = 0;
	ioPhysicalBase.LowPart = StartAddress;
#ifndef HOST_ENABLE
	if (!HalTranslateBusAddress(PCIBus, 0, ioPhysicalBase,
							   &inIoSpace,&ioPhysicalBase)
	   )
	{
		return(NULL);
	}
#endif
#endif

#if 0//defined(XSCALE)	// Enable this section of the code for certain platforms, as necessary

	// Allocate a pointer that holds the virtual address.
	pjAddress = (PUCHAR) VirtualAlloc(0, Length, MEM_RESERVE, PAGE_NOACCESS);
	if (pjAddress == NULL)
		return(NULL);

	// (ioPhysicalBase.LowPart >> 8) because of PAGE_PHYSICAL flag
	if (!VirtualCopy((PVOID) pjAddress, (PVOID) (ioPhysicalBase.LowPart >> 8), Length,
			PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL))
	{
		VirtualFree((PVOID)pjAddress, 0, MEM_RELEASE);
		return(NULL);
	}

#else

	pjAddress = (UCHAR*) MmMapIoSpace(ioPhysicalBase, Length, FALSE);

#endif

	return(pjAddress);
}

BOOL UnMapMemory(PVOID pVirtualAddress, DWORD SourceSize)
{
	BOOL bSuccess = TRUE;

	if (!VirtualFree(pVirtualAddress, SourceSize,MEM_DECOMMIT))
	{
		RETAILMSG(1, (TEXT("ERROR! Unable to decommit memory 0x%08X!\r\n"), pVirtualAddress));
		bSuccess = FALSE;
	}
  				
	if (!VirtualFree(pVirtualAddress, 0,MEM_RELEASE))
	{
  		RETAILMSG(1, (TEXT("ERROR! Unable to release memory 0x%08X!\r\n"), pVirtualAddress));
		bSuccess = FALSE;
	}
	
	return bSuccess;
}

//
// DetectCard
// Detects an SMI card and allocate virtual memory for the Framebuffer Base Address
// and Register Base Address video card
// Inputs:		nMonitorNo	= Current monitor number
// 				pss			= Pointer to the SMISETTINGS
//
// Outputs:		pss			= Contains video card hardware info (Base Addresses, 
//								Int, Chip ID)
//
// Returns:		Boolean on whether or not an SMI card is found
//
BOOL DetectCard(int nMonitorNo, SMISETTINGS *pss)
{
// For All Different Platforms Detection
#ifdef PLATFORM_WCEFA 		//For Automotive based detection

#elif defined(PLATFORM_WCE400PCI)	// For special WindowsCE 400 based PCI detection

	HKEY hkInstance;		  
	DDKWINDOWINFO dwi;
	DDKPCIINFO dpi;
	TCHAR szInstance[256];
		
	// read the registry to get our PCI instance information
	wsprintf(szInstance, _T("%s%u"), g_szBaseInstance, nMonitorNo + 1);
	dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szInstance, 0, 0, &hkInstance);
	if (dwStatus == ERROR_SUCCESS) {
		dwi.cbSize = sizeof(dwi);
		dwStatus = DDKReg_GetWindowInfo(hkInstance, &dwi);
		if (dwStatus == ERROR_SUCCESS) {
			dpi.cbSize = sizeof(dpi);
			dwStatus = DDKReg_GetPciInfo(hkInstance, &dpi);
		}
		RegCloseKey(hkInstance);
	}
		
	// check the registry information
	if (dwStatus == ERROR_SUCCESS) 
	{
		if ((dpi.dwWhichIds & 
		    (PCIIDM_VENDORID | PCIIDM_CLASS | PCIIDM_SUBCLASS)) != (PCIIDM_VENDORID | PCIIDM_CLASS | PCIIDM_SUBCLASS)
		   ) 
		{
			dwStatus = ERROR_INVALID_DATA;
		} 
		else if (dpi.idVals[PCIID_VENDORID] != PCI_VENDOR_SMI || 
				 dpi.idVals[PCIID_CLASS] != PCI_CLASS_DISPLAY || 
				 (dpi.idVals[PCIID_SUBCLASS] != PCI_SUBCLASS_DISPLAY && dpi.idVals[PCIID_SUBCLASS] != 0x80)
				) 
			{
				dwStatus = ERROR_INVALID_DATA;
			} 
			else if (dwi.dwNumMemWindows != 2) 
			{
				dwStatus = ERROR_INVALID_DATA;
			}
	}
		
	// did we find the device?
	if (dwStatus != ERROR_SUCCESS) 
	{
		// Couldn't find an SMI card, what to do now?
		RETAILMSG (1, ((L"SMI card instance %d not found at '%s'\r\n"), nMonitorNo + 1, szInstance));
		bRet = FALSE;
	} 
	else 
	{
		TCHAR szResolution[16],szResString[16];
		PCI_SLOT_NUMBER	slotNumber;
		PCI_COMMON_CONFIG pciConfig;
		USHORT newCommand;
		int length;

		// make sure the card is enabled -- some platforms may only enable one video card
		slotNumber.u.AsULONG = 0;
		slotNumber.u.bits.DeviceNumber = dpi.dwDeviceNumber;
		slotNumber.u.bits.FunctionNumber = dpi.dwFunctionNumber;
		length = HalGetBusData(PCIConfiguration, dwi.dwBusNumber, slotNumber.u.AsULONG,
			&pciConfig, sizeof(pciConfig) - sizeof(pciConfig.DeviceSpecific));
	
		if (length == 0 || pciConfig.VendorID == 0xFFFF)
		{
			dwStatus = ERROR_GEN_FAILURE;
			bRet = FALSE;
		}
		else
		{
			newCommand = pciConfig.Command | 0x07;
			HalSetBusDataByOffset (PCIConfiguration, dwi.dwBusNumber, slotNumber.u.AsULONG, &newCommand, 0x04, 0x02);
		}
	}
	
	return (bRet);
#elif defined(HOST_ENABLE)
// Add by John Huang *********************************************
#if defined(XSCALE)
{
#if defined (ACCELENT)
	volatile PUCHAR pBuf, pBuf2;
	PGPIO_REGS  pGpio;
	PMEMC pMemController;
	SA2lcdregs *pLCDController;

	pMemController= (PMEMC)VirtualAddress(MEMC_BASE_PHYSICAL, sizeof(MEMC_STRUCT));
	pBuf = (volatile PUCHAR) pMemController;
	if (pBuf == NULL) return (FALSE);

	pMemController->msc1 &= 0xffff0000;
	pMemController->msc1 |= 0x00009204; // 0x00009234

 	pMemController->mdrefr |= 0x01010000;	// Set free running clock and SDCLK[1] to 100MHz
// 	pMemController->mdrefr |= 0x01030000;	// Bit:17 1 Set SDCLK[1] to 50MHz
	UnMapMemory(pBuf, sizeof(MEMC_STRUCT));

	pLCDController= (SA2lcdregs *)VirtualAddress(LCD_BASE_PHYSICAL, sizeof(SA2lcdregs));
	pBuf = (volatile PUCHAR) pLCDController;
	if (pBuf == NULL) return (FALSE);

	pLCDController->LCCR0 |= LCD_DIS;	// BIT:10 DISABLE lcd CONTROLLER
	RETAILMSG(1, (TEXT("LCCR0 value -> 0x%08X\r\n"), pLCDController->LCCR0));

	UnMapMemory(pBuf, sizeof(SA2lcdregs));

	
	RETAILMSG(1,(TEXT("\r\n- GPIO\r\n")));
	pGpio = (PGPIO_REGS) VirtualAddress(0x40E00000, sizeof(GPIO_REGS));
	pBuf2 = (volatile PUCHAR)pGpio;
	if (pBuf2 == NULL) return (FALSE);

	pGpio->GAFR0_z = (pGpio->GAFR0_z & ~0x30000000) | 0x20000000; 
	pGpio->GAFR1_x = (pGpio->GAFR1_x & ~0x30) | 0x10;
	pGpio->GAFR1_y = (pGpio->GAFR1_y & ~0xf) | 0xa;

	UnMapMemory(pBuf2, sizeof(GPIO_REGS));

	RETAILMSG(1,(TEXT("\r\n- Voyager\r\n")));
	pBuf2 = (volatile PUCHAR)VirtualAddress(0x17C00000, 0x100);
	if (pBuf2 == NULL) return (FALSE);
	RETAILMSG(1, (TEXT("CPLDS VIRTUAL ADDRESS -> 0x%08X\r\n"), pBuf2));
	RETAILMSG(1,(TEXT("CPLDS Value -> 0x%08X\r\n"),(*(volatile PULONG)(pBuf2+0x38))));
	
	*(volatile PULONG) (pBuf2+0x38) = (*(volatile PULONG)(pBuf2+0x38)) & ~0x10; 
	RETAILMSG(1,(TEXT("CPLDS Value -> 0x%08X\r\n"),(*(volatile PULONG)(pBuf2+0x38))));
	UnMapMemory(pBuf2, 0x100);	
#endif // ACCELENT
}		
#endif	// XSCALE
//		PHYSICAL_ADDRESS ioPhysicalBase;
		RETAILMSG(1, (TEXT("Detect Card\r\n")));

		pss->m_nChipID = CHIPID_SM501;

#ifndef UMA		
 		pss->m_pLAW = (unsigned char *)VirtualAddress(pss->m_nLAWPhysical, pss->MaxVideoMemorySize());
#else
		PUCHAR pAddr = (PUCHAR)VirtualAlloc(0, pss->MaxVideoMemorySize(), MEM_RESERVE, PAGE_NOACCESS);

    	VirtualCopy((void *)pAddr, (void *)pss->m_nLAWPhysical, pss->MaxVideoMemorySize(), PAGE_READWRITE | PAGE_NOCACHE);
		pss->m_pLAW = (PUCHAR)pAddr;
#endif
		if (pss->m_pLAW == NULL)
			return (FALSE);

		RETAILMSG(1, (TEXT("m_pLAW = 0x%08X\r\n"), pss->m_pLAW));

 		pss->m_pREG = (unsigned char *)VirtualAddress(pss->m_nREGPhysical, pss->RegMemorySize());

		RETAILMSG(1, (TEXT("m_pREG = 0x%08X\r\n"), pss->m_pREG));

		return (TRUE);

// ****************************************************************
#else // For Regular CEPC detection

	PCI_SLOT_NUMBER slotNumber;
	ULONG bus, device, function;
	ULONG length;
	PCI_COMMON_CONFIG pciConfig;
	int nMonNo = nMonitorNo;

	for (bus = 0; bus < PCI_MAX_BUS; bus++)
	{
		for (device = 0; device < PCI_MAX_DEVICES; device++)
		{
			slotNumber.u.bits.DeviceNumber = device;
			for (function = 0; function < PCI_MAX_FUNCTION; function++)
			{
				slotNumber.u.bits.FunctionNumber = function;
				length = HalGetBusDataByOffset(PCIConfiguration, bus,
											   slotNumber.u.AsULONG, &pciConfig,
											   0, sizeof(pciConfig));

				if (length == 0 || pciConfig.VendorID == 0xFFFF)
					break;
				else
				{
					if ((pciConfig.VendorID == PCI_VENDOR_SMI) &&
					    (pciConfig.BaseClass == PCI_CLASS_DISPLAY) &&
						((pciConfig.SubClass == PCI_SUBCLASS_DISPLAY) || (pciConfig.SubClass == 0x80))
						)
					{
						if (pss->isSupportedChipID(pciConfig.DeviceID))
						{
							// Check counter to make sure that we find the
							// correct card instance 
							if (nMonNo-- != 0)
								break;

							length = HalGetBusDataByOffset(PCIConfiguration, bus,
							   slotNumber.u.AsULONG, &pciConfig,
							   0, sizeof(pciConfig));

							// Patch Alpha chip and its ID
							if ((pciConfig.RevisionID == 0xA0) &&
								(pciConfig.DeviceID == CHIPID_SM501ALPHA))  // RevA Patch
							{
								DWORD dwBaseAdd = 0x80000000; //pciConfig.Command | 0x07;
								HalSetBusDataByOffset (PCIConfiguration, bus, 
									slotNumber.u.AsULONG, &dwBaseAdd, 0x10, 0x04);
							
								length = HalGetBusDataByOffset(PCIConfiguration, bus,
								   slotNumber.u.AsULONG, &pciConfig,
								   0, sizeof(pciConfig));
							}

							if (pciConfig.DeviceID == CHIPID_SM501ALPHA)
								pciConfig.DeviceID = CHIPID_SM501;

							pss->m_nChipID = pciConfig.DeviceID;
							pss->m_IRQ = pciConfig.u.type0.InterruptLine;
							pss->m_nLAWPhysical = pciConfig.u.type0.BaseAddresses[0];
							pss->m_nREGPhysical = pciConfig.u.type0.BaseAddresses[1];
							
							pss->m_nBusNo = bus;
							pss->m_nSlotNo = slotNumber.u.AsULONG;

				   	 		pss->m_pLAW = VirtualAddress(pss->m_nLAWPhysical,
				   	 							pss->MaxVideoMemorySize());
							if (pss->m_pLAW == NULL)
								return (FALSE);
							
				   	 		pss->m_pREG = VirtualAddress(pss->m_nREGPhysical,
				   	 							pss->RegMemorySize());
							if (pss->m_pREG == NULL)

⌨️ 快捷键说明

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