You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1412 lines
46 KiB
1412 lines
46 KiB
/************************************************************************/
|
|
/* */
|
|
/* INIT_M.C */
|
|
/* */
|
|
/* Sep 27 1993 (c) 1993, ATI Technologies Incorporated. */
|
|
/************************************************************************/
|
|
|
|
/********************** PolyTron RCS Utilities
|
|
|
|
$Revision: 1.16 $
|
|
$Date: 15 May 1996 16:35:42 $
|
|
$Author: RWolff $
|
|
$Log: S:/source/wnt/ms11/miniport/archive/init_m.c_v $
|
|
*
|
|
* Rev 1.16 15 May 1996 16:35:42 RWolff
|
|
* Waits for idle after setting accelerator mode.
|
|
*
|
|
* Rev 1.15 17 Apr 1996 13:09:26 RWolff
|
|
* Backed out Alpha LFB mapping as dense.
|
|
*
|
|
* Rev 1.14 11 Apr 1996 15:12:40 RWolff
|
|
* Now maps framebuffer as dense on DEC Alpha with PCI graphics card.
|
|
*
|
|
* Rev 1.13 31 Mar 1995 11:53:46 RWOLFF
|
|
* Changed from all-or-nothing debug print statements to thresholds
|
|
* depending on importance of the message.
|
|
*
|
|
* Rev 1.12 14 Feb 1995 15:41:20 RWOLFF
|
|
* Changed conditional compile that uses or fakes failure of
|
|
* VideoPortMapBankedMemory() to look for IOCTL_VIDEO_SHARE_VIDEO_MEMORY
|
|
* instead of the routine itself. Looking for the routine always failed,
|
|
* and since the routine is supplied in order to allow DCI to be used
|
|
* on systems without a linear framebuffer, it should be available on
|
|
* any DDK version that supports the IOCTL. If it isn't, a compile-time
|
|
* error will be generated (unresolved external reference).
|
|
*
|
|
* Rev 1.11 03 Feb 1995 15:17:00 RWOLFF
|
|
* Added support for DCI, removed dead code.
|
|
*
|
|
* Rev 1.10 23 Dec 1994 10:47:18 ASHANMUG
|
|
* ALPHA/Chrontel-DAC
|
|
*
|
|
* Rev 1.9 22 Jul 1994 17:48:50 RWOLFF
|
|
* Merged with Richard's non-x86 code stream.
|
|
*
|
|
* Rev 1.8 27 Jun 1994 16:30:12 RWOLFF
|
|
* Now reports all hardware default mode tables as noninterlaced to
|
|
* avoid confusing the display applet.
|
|
*
|
|
* Rev 1.7 15 Jun 1994 11:07:08 RWOLFF
|
|
* Now uses VideoPortZeroDeviceMemory() to clear 24BPP screens on NT builds
|
|
* where this function is available.
|
|
*
|
|
* Rev 1.6 12 May 1994 11:05:32 RWOLFF
|
|
* Reports the refresh rate from the mode table, rather than always
|
|
* reporting "Use hardware default".
|
|
*
|
|
* Rev 1.5 31 Mar 1994 15:02:00 RWOLFF
|
|
* Added SetPowerManagement_m() function to implement DPMS handling.
|
|
*
|
|
* Rev 1.4 14 Mar 1994 16:31:36 RWOLFF
|
|
* XMillimeter field of mode information structure now set properly.
|
|
*
|
|
* Rev 1.3 03 Mar 1994 12:37:54 ASHANMUG
|
|
* Pageable
|
|
*
|
|
* Rev 1.1 31 Jan 1994 16:27:06 RWOLFF
|
|
* Now fills in Frequency and VideoMemoryBitmap[Width|Height] fields of
|
|
* mode information structure. Sets Number[Red|Green|Blue]Bits fields
|
|
* for palette modes to 6 (assumes VGA-compatible DAC) instead of 0
|
|
* to allow Windows NT to set the palette colours to the best match
|
|
* for the colours to be displayed.
|
|
*
|
|
* Rev 1.0 31 Jan 1994 11:10:40 RWOLFF
|
|
* Initial revision.
|
|
*
|
|
* Rev 1.6 24 Jan 1994 18:04:28 RWOLFF
|
|
* Now puts DAC in known state before setting video mode. This is to
|
|
* accomodate the Graphics Wonder (1M DRAM Mach 32 with BT48x DAC).
|
|
*
|
|
* Rev 1.5 14 Jan 1994 15:21:22 RWOLFF
|
|
* SetCurrentMode_m() and (new routine) ResetDevice_m() now initialize
|
|
* and deinitialize the bank manager.
|
|
*
|
|
* Rev 1.4 15 Dec 1993 15:26:48 RWOLFF
|
|
* Added note to clean up before sending to Microsoft.
|
|
*
|
|
* Rev 1.3 30 Nov 1993 18:16:34 RWOLFF
|
|
* MapVideoMemory_m() now sets memoryInformation->FrameBufferLength to
|
|
* aperture size rather than amount of video memory present.
|
|
*
|
|
* Rev 1.2 05 Nov 1993 13:25:24 RWOLFF
|
|
* Switched to defined values for memory type, 1280x1024 DAC initialization is
|
|
* now done in the same manner as for other resolutions.
|
|
*
|
|
* Rev 1.0 08 Oct 1993 11:20:34 RWOLFF
|
|
* Initial revision.
|
|
|
|
End of PolyTron RCS section *****************/
|
|
|
|
#ifdef DOC
|
|
INIT_M.C - Highest-level card-dependent routines for miniport.
|
|
|
|
DESCRIPTION
|
|
This file contains initialization and packet handling routines
|
|
for 8514/A-compatible ATI accelerators. Routines in this module
|
|
are called only by routines in ATIMP.C, which is card-independent.
|
|
|
|
OTHER FILES
|
|
|
|
#endif
|
|
|
|
#include "dderror.h"
|
|
|
|
#include "miniport.h"
|
|
#include "ntddvdeo.h"
|
|
#include "video.h"
|
|
|
|
#include "stdtyp.h"
|
|
#include "amach.h"
|
|
#include "amach1.h"
|
|
#include "atimp.h"
|
|
#include "atint.h"
|
|
|
|
#define INCLUDE_INIT_M
|
|
#include "init_m.h"
|
|
#include "modes_m.h"
|
|
#include "services.h"
|
|
#include "setup_m.h"
|
|
|
|
|
|
/*
|
|
* Prototypes for static functions.
|
|
*/
|
|
static void QuerySingleMode_m(PVIDEO_MODE_INFORMATION ModeInformation, struct query_structure *QueryPtr, ULONG ModeIndex);
|
|
|
|
|
|
/*
|
|
* Allow miniport to be swapped out when not needed.
|
|
*/
|
|
#if defined (ALLOC_PRAGMA)
|
|
#pragma alloc_text(PAGE_M, AlphaInit_m)
|
|
#pragma alloc_text(PAGE_M, Initialize_m)
|
|
#pragma alloc_text(PAGE_M, MapVideoMemory_m)
|
|
#pragma alloc_text(PAGE_M, QueryPublicAccessRanges_m)
|
|
#pragma alloc_text(PAGE_M, QueryCurrentMode_m)
|
|
#pragma alloc_text(PAGE_M, QueryAvailModes_m)
|
|
#pragma alloc_text(PAGE_M, QuerySingleMode_m)
|
|
#pragma alloc_text(PAGE_M, SetCurrentMode_m)
|
|
#pragma alloc_text(PAGE_M, ResetDevice_m)
|
|
#pragma alloc_text(PAGE_M, SetPowerManagement_m)
|
|
#pragma alloc_text(PAGE_M, ShareVideoMemory_m)
|
|
/* BankMap_m() can't be made pageable */
|
|
#endif
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* void AlphaInit_m(void);
|
|
*
|
|
* DESCRIPTION:
|
|
* Perform the initialization that would normally be done by the ROM
|
|
* BIOS on x86 machines.
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* ATIMPFindAdapter()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
void AlphaInit_m(void)
|
|
{
|
|
OUTPW(MEM_CFG, 0);
|
|
DEC_DELAY
|
|
OUTPW(MISC_OPTIONS, 0xb0a9);
|
|
DEC_DELAY
|
|
OUTPW(MEM_BNDRY, 0);
|
|
DEC_DELAY
|
|
#if 0
|
|
OUTPW(CONFIG_STATUS_1, 0x1410);
|
|
DEC_DELAY
|
|
OUTPW(SCRATCH_PAD_1, 0);
|
|
DEC_DELAY
|
|
OUTPW(SCRATCH_PAD_0, 0);
|
|
DEC_DELAY
|
|
#endif
|
|
OUTPW(CLOCK_SEL, 0x250);
|
|
DEC_DELAY
|
|
OUTPW(DAC_W_INDEX, 0x40);
|
|
DEC_DELAY
|
|
OUTPW(MISC_CNTL, 0xC00);
|
|
DEC_DELAY
|
|
OUTPW(LOCAL_CONTROL, 0x1402);
|
|
#if defined (MIPS) || defined (_MIPS_)
|
|
DEC_DELAY
|
|
OUTPW(OVERSCAN_COLOR_8, 0); //RKE: to eliminate left overscan on MIPS
|
|
#endif
|
|
DEC_DELAY
|
|
|
|
return;
|
|
|
|
} /* AlphaInit_m() */
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* void Initialize_m(void);
|
|
*
|
|
* DESCRIPTION:
|
|
* This routine is the 8514/A-compatible hardware initialization routine
|
|
* for the miniport driver. It is called once an adapter has been found
|
|
* and all the required data structures for it have been created.
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* ATIMPInitialize()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
void Initialize_m(void)
|
|
{
|
|
/*
|
|
* Make sure we have enough available FIFO entries
|
|
* to initialize the card.
|
|
*/
|
|
CheckFIFOSpace_m(SIXTEEN_WORDS);
|
|
|
|
/*
|
|
* On the 68800, set the memory boundary to shared VGA memory.
|
|
* On all cards, set the screen and drawing engine to start
|
|
* at the beginning of accelerator memory and MEM_CNTL
|
|
* to linear.
|
|
*/
|
|
if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
|
|
OUTP (MEM_BNDRY,0);
|
|
|
|
OUTPW(CRT_OFFSET_LO, 0);
|
|
OUTPW(GE_OFFSET_LO, 0);
|
|
OUTPW(CRT_OFFSET_HI, 0);
|
|
OUTPW(GE_OFFSET_HI, 0);
|
|
OUTPW(MEM_CNTL,0x5006);
|
|
|
|
/*
|
|
* Reset the engine and FIFO, then return to normal operation.
|
|
*/
|
|
OUTPW(SUBSYS_CNTL,0x9000);
|
|
OUTPW(SUBSYS_CNTL,0x5000);
|
|
|
|
/*
|
|
* The hardware cursor is available only for Mach 32 cards.
|
|
* disable the cursor and initialize it to display quadrant I - 0
|
|
*/
|
|
if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
|
|
{
|
|
OUTPW(CURSOR_OFFSET_HI,0);
|
|
|
|
OUTPW(HORZ_CURSOR_OFFSET,0);
|
|
OUTP(VERT_CURSOR_OFFSET,0);
|
|
OUTPW(CURSOR_COLOR_0, 0x0FF00); /* Colour 0 black, colour 1 white */
|
|
OUTPW(EXT_CURSOR_COLOR_0,0); // black
|
|
OUTPW(EXT_CURSOR_COLOR_1,0xffff); // white
|
|
}
|
|
|
|
return;
|
|
|
|
} /* Initialize_m() */
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* VP_STATUS MapVideoMemory_m(RequestPacket, QueryPtr);
|
|
*
|
|
* PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
|
|
* struct query_structure *QueryPtr; Query information for the card
|
|
*
|
|
* DESCRIPTION:
|
|
* Map the card's video memory into system memory and store the mapped
|
|
* address and size in OutputBuffer.
|
|
*
|
|
* RETURN VALUE:
|
|
* NO_ERROR if successful
|
|
* error code if failed
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* FrameLength and PhysicalFrameAddress fields of phwDeviceExtension
|
|
* if Mach 32 card without linear framebuffer.
|
|
*
|
|
* CALLED BY:
|
|
* IOCTL_VIDEO_MAP_VIDEO_MEMORY packet of ATIMPStartIO()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
VP_STATUS MapVideoMemory_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
|
|
{
|
|
PVIDEO_MEMORY_INFORMATION memoryInformation;
|
|
ULONG inIoSpace; /* Scratch variable used by VideoPortMapMemory() */
|
|
VP_STATUS status; /* Error code obtained from O/S calls */
|
|
|
|
memoryInformation = RequestPacket->OutputBuffer;
|
|
|
|
memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
|
|
(RequestPacket->InputBuffer))->RequestedVirtualAddress;
|
|
|
|
/*
|
|
* The VideoRamLength field contains the amount of video memory
|
|
* on the card. The FrameBufferLength field contains the
|
|
* size of the aperture in bytes
|
|
*
|
|
* Initially assume that the linear aperture is available.
|
|
* For our 8514/A-compatible cards, we always enable a 4M aperture
|
|
* if the LFB is available, so map the full 4M even if the
|
|
* aperture size is greater than the amount of video memory.
|
|
*/
|
|
memoryInformation->VideoRamLength = phwDeviceExtension->VideoRamSize;
|
|
memoryInformation->FrameBufferLength = 4 * ONE_MEG;
|
|
|
|
/*
|
|
* If the linear aperture is not available (==0), and we are
|
|
* dealing with a card which can use the VGA 64k aperture,
|
|
* map it in.
|
|
*/
|
|
if (QueryPtr->q_aperture_cfg == 0)
|
|
{
|
|
if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
|
|
(QueryPtr->q_VGA_type == 1))
|
|
{
|
|
phwDeviceExtension->FrameLength = 0x10000;
|
|
phwDeviceExtension->PhysicalFrameAddress.LowPart = 0x0A0000;
|
|
memoryInformation->FrameBufferLength = phwDeviceExtension->FrameLength;
|
|
}
|
|
else{
|
|
/*
|
|
* This card can't use either linear or VGA aperture.
|
|
* Set frame buffer size to zero and return.
|
|
*/
|
|
memoryInformation->VideoRamBase = 0;
|
|
memoryInformation->FrameBufferLength = 0;
|
|
memoryInformation->FrameBufferBase = 0;
|
|
return NO_ERROR;
|
|
}
|
|
}
|
|
inIoSpace = 0;
|
|
#if 0 /* defined(ALPHA) if display driver can handle dense LFB */
|
|
if (QueryPtr->q_bus_type == BUS_PCI)
|
|
inIoSpace = 4;
|
|
#endif
|
|
|
|
status = VideoPortMapMemory(phwDeviceExtension,
|
|
phwDeviceExtension->PhysicalFrameAddress,
|
|
&(memoryInformation->FrameBufferLength),
|
|
&inIoSpace,
|
|
&(memoryInformation->VideoRamBase));
|
|
|
|
memoryInformation->FrameBufferBase = memoryInformation->VideoRamBase;
|
|
|
|
return status;
|
|
|
|
} /* MapVideoMemory_m() */
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* VP_STATUS QueryPublicAccessRanges_m(RequestPacket);
|
|
*
|
|
* PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
|
|
*
|
|
* DESCRIPTION:
|
|
* Map and return information on the video card's public access ranges.
|
|
*
|
|
* RETURN VALUE:
|
|
* NO_ERROR if successful
|
|
* error code if failed
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES packet of ATIMPStartIO()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
VP_STATUS QueryPublicAccessRanges_m(PVIDEO_REQUEST_PACKET RequestPacket)
|
|
{
|
|
PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
|
|
PHYSICAL_ADDRESS physicalPortBase;
|
|
ULONG physicalPortLength;
|
|
|
|
if ( RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) )
|
|
{
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
portAccess = RequestPacket->OutputBuffer;
|
|
|
|
portAccess->VirtualAddress = (PVOID) NULL; // Requested VA
|
|
portAccess->InIoSpace = 1; // In IO space
|
|
portAccess->MappedInIoSpace = portAccess->InIoSpace;
|
|
|
|
physicalPortBase.HighPart = 0x00000000;
|
|
physicalPortBase.LowPart = 0x00000000;
|
|
// physicalPortLength = LINEDRAW+2 - physicalPortBase.LowPart;
|
|
physicalPortLength = 0x10000;
|
|
|
|
|
|
// *SANITIZE* If MM available, give MM ports instead.
|
|
|
|
return VideoPortMapMemory(phwDeviceExtension,
|
|
physicalPortBase,
|
|
&physicalPortLength,
|
|
&(portAccess->MappedInIoSpace),
|
|
&(portAccess->VirtualAddress));
|
|
|
|
} /* QueryPublicAccessRanges_m() */
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* VP_STATUS QueryCurrentMode_m(RequestPacket, QueryPtr);
|
|
*
|
|
* PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
|
|
* struct query_structure *QueryPtr; Query information for the card
|
|
*
|
|
* DESCRIPTION:
|
|
* Get screen information and colour masks for the current video mode.
|
|
*
|
|
* RETURN VALUE:
|
|
* NO_ERROR if successful
|
|
* error code if failed
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* IOCTL_VIDEO_QUERY_CURRENT_MODE packet of ATIMPStartIO()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
VP_STATUS QueryCurrentMode_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
|
|
{
|
|
PVIDEO_MODE_INFORMATION ModeInformation;
|
|
|
|
/*
|
|
* If the output buffer is too small to hold the information we need
|
|
* to put in it, return with the appropriate error code.
|
|
*/
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
sizeof(VIDEO_MODE_INFORMATION)) )
|
|
{
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
/*
|
|
* Fill in the mode information structure.
|
|
*/
|
|
ModeInformation = RequestPacket->OutputBuffer;
|
|
|
|
QuerySingleMode_m(ModeInformation, QueryPtr, phwDeviceExtension->ModeIndex);
|
|
|
|
return NO_ERROR;
|
|
|
|
} /* QueryCurrentMode_m() */
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* VP_STATUS QueryAvailModes_m(RequestPacket, QueryPtr);
|
|
*
|
|
* PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
|
|
* struct query_structure *QueryPtr; Query information for the card
|
|
*
|
|
* DESCRIPTION:
|
|
* Get screen information and colour masks for all available video modes.
|
|
*
|
|
* RETURN VALUE:
|
|
* NO_ERROR if successful
|
|
* error code if failed
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* IOCTL_VIDEO_QUERY_AVAIL_MODES packet of ATIMPStartIO()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
VP_STATUS QueryAvailModes_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
|
|
{
|
|
PVIDEO_MODE_INFORMATION ModeInformation;
|
|
ULONG CurrentMode;
|
|
|
|
/*
|
|
* If the output buffer is too small to hold the information we need
|
|
* to put in it, return with the appropriate error code.
|
|
*/
|
|
if (RequestPacket->OutputBufferLength <
|
|
(RequestPacket->StatusBlock->Information =
|
|
QueryPtr->q_number_modes * sizeof(VIDEO_MODE_INFORMATION)) )
|
|
{
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
/*
|
|
* Fill in the mode information structure.
|
|
*/
|
|
ModeInformation = RequestPacket->OutputBuffer;
|
|
|
|
/*
|
|
* For each mode supported by the card, store the mode characteristics
|
|
* in the output buffer.
|
|
*/
|
|
for (CurrentMode = 0; CurrentMode < QueryPtr->q_number_modes; CurrentMode++, ModeInformation++)
|
|
QuerySingleMode_m(ModeInformation, QueryPtr, CurrentMode);
|
|
|
|
return NO_ERROR;
|
|
|
|
} /* QueryCurrentMode_m() */
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* static void QuerySingleMode_m(ModeInformation, QueryPtr, ModeIndex);
|
|
*
|
|
* PVIDEO_MODE_INFORMATION ModeInformation; Table to be filled in
|
|
* struct query_structure *QueryPtr; Query information for the card
|
|
* ULONG ModeIndex; Index of mode table to use
|
|
*
|
|
* DESCRIPTION:
|
|
* Fill in a single Windows NT mode information table using data from
|
|
* one of our CRT parameter tables.
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* QueryCurrentMode_m() and QueryAvailModes_m()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
static void QuerySingleMode_m(PVIDEO_MODE_INFORMATION ModeInformation,
|
|
struct query_structure *QueryPtr,
|
|
ULONG ModeIndex)
|
|
{
|
|
struct st_mode_table *CrtTable; /* Pointer to current mode table */
|
|
CrtTable = (struct st_mode_table *)QueryPtr;
|
|
((struct query_structure *)CrtTable)++;
|
|
CrtTable += ModeIndex;
|
|
|
|
|
|
ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
|
|
ModeInformation->ModeIndex = ModeIndex;
|
|
|
|
ModeInformation->VisScreenWidth = CrtTable->m_x_size;
|
|
ModeInformation->VisScreenHeight = CrtTable->m_y_size;
|
|
|
|
// * Bytes per line = ((pixels/line) * (bits/pixel)) / (bits/byte))
|
|
ModeInformation->ScreenStride = (CrtTable->m_screen_pitch * CrtTable->m_pixel_depth) / 8;
|
|
|
|
ModeInformation->NumberOfPlanes = 1;
|
|
ModeInformation->BitsPerPlane = (USHORT) CrtTable->m_pixel_depth;
|
|
|
|
ModeInformation->Frequency = CrtTable->Refresh;
|
|
|
|
/*
|
|
* Driver can't measure the screen size,
|
|
* so take reasonable values (16" diagonal).
|
|
*/
|
|
ModeInformation->XMillimeter = 320;
|
|
ModeInformation->YMillimeter = 240;
|
|
|
|
switch(ModeInformation->BitsPerPlane)
|
|
{
|
|
case 16:
|
|
ModeInformation->RedMask = 0x0000f800;
|
|
ModeInformation->GreenMask = 0x000007e0;
|
|
ModeInformation->BlueMask = 0x0000001f;
|
|
ModeInformation->NumberRedBits = 5;
|
|
ModeInformation->NumberGreenBits = 6;
|
|
ModeInformation->NumberBlueBits = 5;
|
|
CrtTable->ColourDepthInfo = PIX_WIDTH_16BPP | ORDER_16BPP_565;
|
|
break;
|
|
|
|
case 24:
|
|
/*
|
|
* Windows NT uses RGB as the standard 24BPP mode,
|
|
* so use this ordering for all DACs except the
|
|
* Brooktree 48x which only supports BGR.
|
|
*/
|
|
if (QueryPtr->q_DAC_type != DAC_BT48x)
|
|
{
|
|
ModeInformation->RedMask = 0x00ff0000;
|
|
ModeInformation->GreenMask = 0x0000ff00;
|
|
ModeInformation->BlueMask = 0x000000ff;
|
|
CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_RGB;
|
|
}
|
|
else{
|
|
ModeInformation->RedMask = 0x000000ff;
|
|
ModeInformation->GreenMask = 0x0000ff00;
|
|
ModeInformation->BlueMask = 0x00ff0000;
|
|
CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_BGR;
|
|
}
|
|
ModeInformation->NumberRedBits = 8;
|
|
ModeInformation->NumberGreenBits = 8;
|
|
ModeInformation->NumberBlueBits = 8;
|
|
break;
|
|
|
|
case 32:
|
|
/*
|
|
* Only the Brooktree 481 requires BGR,
|
|
* and it doesn't support 32BPP.
|
|
*/
|
|
ModeInformation->RedMask = 0xff000000;
|
|
ModeInformation->GreenMask = 0x00ff0000;
|
|
ModeInformation->BlueMask = 0x0000ff00;
|
|
ModeInformation->NumberRedBits = 8;
|
|
ModeInformation->NumberGreenBits = 8;
|
|
ModeInformation->NumberBlueBits = 8;
|
|
CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_RGBx;
|
|
break;
|
|
|
|
default:
|
|
ModeInformation->RedMask = 0x00000000;
|
|
ModeInformation->GreenMask = 0x00000000;
|
|
ModeInformation->BlueMask = 0x00000000;
|
|
ModeInformation->NumberRedBits = 6;
|
|
ModeInformation->NumberGreenBits = 6;
|
|
ModeInformation->NumberBlueBits = 6;
|
|
CrtTable->ColourDepthInfo = PIX_WIDTH_8BPP;
|
|
break;
|
|
}
|
|
|
|
ModeInformation->AttributeFlags = VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS;
|
|
|
|
if (CrtTable->m_pixel_depth <= 8)
|
|
{
|
|
ModeInformation->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN |
|
|
VIDEO_MODE_MANAGED_PALETTE;
|
|
}
|
|
|
|
/*
|
|
* Bit 4 of the m_disp_cntl field is set for interlaced and
|
|
* cleared for noninterlaced.
|
|
*
|
|
* The display applet gets confused if some of the "Use hardware
|
|
* default" modes are interlaced and some are noninterlaced
|
|
* (two "Use hardware default" entries are shown in the refresh
|
|
* rate list). To avoid this, report all mode tables stored in
|
|
* the EEPROM as noninterlaced, even if they are interlaced.
|
|
* "Canned" mode tables give true reports.
|
|
*/
|
|
if ((CrtTable->m_disp_cntl & 0x010) && (ModeInformation->Frequency != DEFAULT_REFRESH))
|
|
ModeInformation->AttributeFlags |= VIDEO_MODE_INTERLACED;
|
|
else
|
|
ModeInformation->AttributeFlags &= ~VIDEO_MODE_INTERLACED;
|
|
|
|
/*
|
|
* Fill in the video memory bitmap width and height fields.
|
|
* The descriptions are somewhat ambiguous - assume that
|
|
* "bitmap width" is the same as ScreenStride (bytes from
|
|
* start of one scanline to start of the next) and "bitmap
|
|
* height" refers to the number of complete scanlines which
|
|
* will fit into video memory.
|
|
*/
|
|
ModeInformation->VideoMemoryBitmapWidth = ModeInformation->ScreenStride;
|
|
ModeInformation->VideoMemoryBitmapHeight = (QueryPtr->q_memory_size * QUARTER_MEG) / ModeInformation->VideoMemoryBitmapWidth;
|
|
|
|
return;
|
|
|
|
} /* QuerySingleMode_m() */
|
|
|
|
//
|
|
// When coming back from hibernate, mach32s can lock up and blackscreen.
|
|
// This is because the card itself has to be reinitialized.
|
|
// This initialization include at least the frame buffer initialization
|
|
// and the initialization of the use of memory mapped registers.
|
|
//
|
|
|
|
VOID
|
|
EnableMach32FrameBufferAndMemMappedRegisters(
|
|
PHW_DEVICE_EXTENSION pHwDeviceExtension
|
|
)
|
|
{
|
|
USHORT temp, temp1;
|
|
|
|
//
|
|
// enable the framebuffer.
|
|
//
|
|
|
|
temp = INPW(MEM_CFG) & 0x0fffc; /* Preserve bits 2-15 */
|
|
temp |= 0x0002; /* 4M aperture */
|
|
OUTPW(MEM_CFG, temp);
|
|
|
|
//
|
|
// enable memory mapped register use.
|
|
// save SRC_X ???
|
|
|
|
OUTPW(SRC_X, 0x0AAAA);
|
|
temp = INPW(R_SRC_X);
|
|
if (temp != 0x02AA)
|
|
VideoDebugPrint((DEBUG_NORMAL, "Can't use memory mapped ranges, read %x\n", temp));
|
|
|
|
temp1 = INPW(LOCAL_CONTROL);
|
|
temp1 |= 0x0020; // Enable memory mapped registers
|
|
OUTPW(LOCAL_CONTROL, temp1);
|
|
|
|
//restore SRC_X???: OUTPW(SRC_X, temp);
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* void SetCurrentMode_m(QueryPtr, CrtTable);
|
|
*
|
|
* struct query_structure *QueryPtr; Query information for the card
|
|
* struct st_mode_table *CrtTable; CRT parameter table for desired mode
|
|
*
|
|
* DESCRIPTION:
|
|
* Switch into the specified video mode.
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* IOCTL_VIDEO_SET_CURRENT_MODE packet of ATIMPStartIO()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
* 1994 01 13 Added initialization of bank manager
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
void SetCurrentMode_m(struct query_structure *QueryPtr, struct st_mode_table *CrtTable)
|
|
{
|
|
WORD MiscOptions; /* Contents of MISC_OPTIONS register */
|
|
USHORT Scratch, USTemp; /* Temporary variable */
|
|
|
|
//
|
|
// When coming back from hibernate, mach32s can lock up and blackscreen.
|
|
// This is because the card itself has to be reinitialized.
|
|
// This initialization include at least the frame buffer initialization
|
|
// and the initialization of the use of memory mapped registers.
|
|
//
|
|
|
|
if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
|
|
{
|
|
// enable the framebuffer.
|
|
Scratch = INPW(MEM_CFG) & 0x0fffc; /* Preserve bits 2-15 */
|
|
Scratch |= 0x0002; /* 4M aperture */
|
|
OUTPW(MEM_CFG, Scratch);
|
|
|
|
// enable memory mapped register use.
|
|
// save SRC_X ???
|
|
OUTPW(SRC_X, 0x0AAAA);
|
|
Scratch = INPW(R_SRC_X);
|
|
if (Scratch != 0x02AA)
|
|
VideoDebugPrint((DEBUG_NORMAL, "Can't use memory mapped ranges, read %x\n", Scratch));
|
|
|
|
USTemp = INPW(LOCAL_CONTROL);
|
|
USTemp |= 0x0020; // Enable memory mapped registers
|
|
OUTPW(LOCAL_CONTROL, USTemp);
|
|
//restore SRC_X???: OUTPW(SRC_X, Scratch);
|
|
}
|
|
|
|
|
|
/*
|
|
* Put the DAC in a known state before we start.
|
|
*/
|
|
UninitTiDac_m();
|
|
|
|
Passth8514_m(SHOW_ACCEL); // turn vga pass through off
|
|
|
|
/*
|
|
* On cards with the "MISC_OPTIONS doesn't report video memory size
|
|
* correctly" bug, reset MISC_OPTIONS to show the true amount of
|
|
* video memory. This is done here rather than when we determine
|
|
* how much memory is present in order to avoid trashing the "blue
|
|
* screen" (no adverse effects on operation, but would generate
|
|
* large numbers of user complaints).
|
|
*/
|
|
if (((QueryPtr->q_asic_rev == CI_68800_6) || (QueryPtr->q_asic_rev == CI_68800_AX)) &&
|
|
(QueryPtr->q_VGA_type == 1) &&
|
|
((QueryPtr->q_memory_type == VMEM_DRAM_256Kx4) ||
|
|
(QueryPtr->q_memory_type == VMEM_DRAM_256Kx16) ||
|
|
(QueryPtr->q_memory_type == VMEM_DRAM_256Kx4_GRAP)))
|
|
{
|
|
MiscOptions = INPW(MISC_OPTIONS) & MEM_SIZE_STRIPPED;
|
|
|
|
switch (QueryPtr->q_memory_size)
|
|
{
|
|
case VRAM_512k:
|
|
MiscOptions |= MEM_SIZE_512K;
|
|
break;
|
|
|
|
case VRAM_1mb:
|
|
MiscOptions |= MEM_SIZE_1M;
|
|
break;
|
|
|
|
case VRAM_2mb:
|
|
MiscOptions |= MEM_SIZE_2M;
|
|
break;
|
|
|
|
case VRAM_4mb:
|
|
MiscOptions |= MEM_SIZE_4M;
|
|
break;
|
|
}
|
|
OUTPW(MISC_OPTIONS, MiscOptions);
|
|
}
|
|
|
|
setmode_m(CrtTable, (ULONG_PTR) &(phwDeviceExtension->RomBaseRange), (ULONG) phwDeviceExtension->ModelNumber);
|
|
|
|
/*
|
|
* On a Mach 8 card, 1280x1024 can only be done in split
|
|
* pixel mode. If we are running on a Mach 8, and this
|
|
* resolution was selected, go into split pixel mode.
|
|
*
|
|
* Bit 4 of EXT_GE_CONFIG is set for split pixel mode and
|
|
* clear for normal mode. Bit 3 must be set, since clearing
|
|
* it accesses EEPROM read/write mode.
|
|
*/
|
|
if ((phwDeviceExtension->ModelNumber == _8514_ULTRA)
|
|
|| (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA))
|
|
{
|
|
if (QueryPtr->q_desire_x == 1280)
|
|
OUTPW(EXT_GE_CONFIG, 0x0018);
|
|
else OUTPW(EXT_GE_CONFIG, 0x0008);
|
|
}
|
|
|
|
/*
|
|
* Default to 8 bits per pixel. Modes which require a different
|
|
* setting will change this in the init_ti_<depth>_m() function.
|
|
*/
|
|
OUTP(DAC_MASK, 0xff);
|
|
|
|
if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
|
|
{
|
|
switch (CrtTable->m_pixel_depth) // program the DAC for the
|
|
{ // other resolutions
|
|
case 4:
|
|
case 8:
|
|
InitTi_8_m((WORD)(CrtTable->ColourDepthInfo | 0x0a));
|
|
break;
|
|
|
|
case 16:
|
|
InitTi_16_m((WORD)(CrtTable->ColourDepthInfo | 0x0a), (ULONG_PTR) &(phwDeviceExtension->RomBaseRange)); /* 16 bit 565 */
|
|
break;
|
|
|
|
case 24:
|
|
case 32:
|
|
/*
|
|
* RGB/BGR and 24/32 bit mode information is
|
|
* stored in CrtTable->ColourDepthInfo.
|
|
*/
|
|
InitTi_24_m((WORD)(CrtTable->ColourDepthInfo | 0x0a), (ULONG_PTR) &(phwDeviceExtension->RomBaseRange));
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* If we are going to be using the VGA aperture on a Mach 32,
|
|
* initialize the bank manager by saving the ATI extended register
|
|
* values and putting the VGA controller into packed pixel mode.
|
|
*
|
|
* We can't identify this case by looking at
|
|
* phwDeviceExtension->FrameLength because it is set to 0x10000
|
|
* when the VGA aperture is being used in the
|
|
* IOCTL_VIDEO_MAP_VIDEO_MEMORY packet which may or may not
|
|
* have been called by the time we reach this point.
|
|
*/
|
|
if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
|
|
(QueryPtr->q_aperture_cfg == 0) &&
|
|
(QueryPtr->q_VGA_type == 1))
|
|
{
|
|
for (Scratch = 0; Scratch <= 2; Scratch++)
|
|
{
|
|
OUTP(reg1CE, (BYTE)(SavedExtRegs[Scratch] & 0x00FF));
|
|
SavedExtRegs[Scratch] = (SavedExtRegs[Scratch] & 0x00FF) | (INP(reg1CF) << 8);
|
|
}
|
|
OUTPW(HI_SEQ_ADDR, 0x0F02);
|
|
OUTPW(HI_SEQ_ADDR, 0x0A04);
|
|
OUTPW(reg3CE, 0x1000);
|
|
OUTPW(reg3CE, 0x0001);
|
|
OUTPW(reg3CE, 0x0002);
|
|
OUTPW(reg3CE, 0x0003);
|
|
OUTPW(reg3CE, 0x0004);
|
|
OUTPW(reg3CE, 0x0005);
|
|
OUTPW(reg3CE, 0x0506);
|
|
OUTPW(reg3CE, 0x0F07);
|
|
OUTPW(reg3CE, 0xFF08);
|
|
OUTPW(reg1CE, 0x28B0); /* Enable 256 colour, 1M video RAM */
|
|
OUTPW(reg1CE, 0x04B6); /* Select linear addressing */
|
|
OUTP(reg1CE, 0xBE);
|
|
OUTPW(reg1CE, (WORD)(((INP(reg1CF) & 0xF7) << 8) | 0xBE));
|
|
}
|
|
|
|
|
|
/*
|
|
* phwDeviceExtension->ReInitializing becomes TRUE in
|
|
* IOCTL_VIDEO_SET_COLOR_REGISTERS packet of ATIMPStartIO().
|
|
*
|
|
* If this is not the first time we are switching into graphics
|
|
* mode, set the palette to the last set of colours that was
|
|
* selected while in graphics mode.
|
|
*/
|
|
if (phwDeviceExtension->ReInitializing)
|
|
{
|
|
SetPalette_m(phwDeviceExtension->Clut,
|
|
phwDeviceExtension->FirstEntry,
|
|
phwDeviceExtension->NumEntries);
|
|
}
|
|
|
|
/*
|
|
* Clear visible screen.
|
|
*
|
|
* 24 and 32 BPP would require a q_desire_y value beyond the
|
|
* maximum allowable clipping value (1535) if we clear the screen
|
|
* using a normal blit. Since these pixel depths are only supported
|
|
* up to 800x600, we can fake it by doing a 16BPP blit of double the
|
|
* screen height, clipping the special case of 640x480 24BPP on
|
|
* a 1M card (this is the only true colour mode that will fit in
|
|
* 1M, so if we hit this case on a 1M card, we know which mode
|
|
* we're dealing with) to avoid running off the end of video memory.
|
|
*/
|
|
if (CrtTable->m_pixel_depth >= 24)
|
|
{
|
|
/*
|
|
* Save the colour depth configuration and switch into 16BPP
|
|
*/
|
|
Scratch = INPW(R_EXT_GE_CONFIG);
|
|
OUTPD(EXT_GE_CONFIG, (Scratch & 0xFFCF) | PIX_WIDTH_16BPP);
|
|
|
|
CheckFIFOSpace_m(SIXTEEN_WORDS);
|
|
|
|
OUTPW(DP_CONFIG, 0x2011);
|
|
OUTPW(ALU_FG_FN, 0x7); // Paint
|
|
OUTPW(FRGD_COLOR, 0); // Black
|
|
OUTPW(CUR_X, 0);
|
|
OUTPW(CUR_Y, 0);
|
|
OUTPW(DEST_X_START, 0);
|
|
OUTPW(DEST_X_END, QueryPtr->q_desire_x);
|
|
|
|
if (QueryPtr->q_memory_size == VRAM_1mb)
|
|
OUTPW(DEST_Y_END, 720); /* Only 640x480 24BPP will fit in 1M */
|
|
else
|
|
OUTPW(DEST_Y_END, (WORD)(2*(QueryPtr->q_desire_y)));
|
|
|
|
/*
|
|
* Let the blit finish then restore the colour depth configuration
|
|
*/
|
|
WaitForIdle_m();
|
|
OUTPD(EXT_GE_CONFIG, Scratch);
|
|
|
|
}
|
|
else{
|
|
/*
|
|
* Other colour depths can be handled by a normal blit, and the
|
|
* LFB may not be available, so use a blit to clear the screen.
|
|
*/
|
|
CheckFIFOSpace_m(SIXTEEN_WORDS);
|
|
|
|
OUTPW(DP_CONFIG, 0x2011);
|
|
OUTPW(ALU_FG_FN, 0x7); // Paint
|
|
OUTPW(FRGD_COLOR, 0); // Black
|
|
OUTPW(CUR_X, 0);
|
|
OUTPW(CUR_Y, 0);
|
|
OUTPW(DEST_X_START, 0);
|
|
OUTPW(DEST_X_END, QueryPtr->q_desire_x);
|
|
OUTPW(DEST_Y_END, QueryPtr->q_desire_y);
|
|
}
|
|
|
|
#if 0
|
|
/*
|
|
* In 800x600 24BPP, set the offset to start 1 pixel into video
|
|
* memory to avoid screen tearing. The MAP_VIDEO_MEMORY packet
|
|
* must adjust the framebuffer base to compensate for this.
|
|
*/
|
|
if ((QueryPtr->q_desire_x == 800) && (QueryPtr->q_pix_depth == 24))
|
|
{
|
|
OUTPW(CRT_OFFSET_LO, 3);
|
|
}
|
|
else
|
|
{
|
|
OUTPW(CRT_OFFSET_HI, 0);
|
|
}
|
|
#endif
|
|
|
|
WaitForIdle_m();
|
|
|
|
return;
|
|
|
|
} /* SetCurrentMode_m() */
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* void ResetDevice_m(void);
|
|
*
|
|
* DESCRIPTION:
|
|
* Reset the accelerator to allow the VGA miniport to switch
|
|
* into a VGA mode.
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* IOCTL_VIDEO_RESET_DEVICE packet of ATIMPStartIO()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
void ResetDevice_m(void)
|
|
{
|
|
VIDEO_X86_BIOS_ARGUMENTS Registers; /* Used in VideoPortInt10() calls */
|
|
|
|
/*
|
|
* If we are using the VGA aperture on a Mach 32, put its
|
|
* VGA controller into planar mode.
|
|
*/
|
|
if (phwDeviceExtension->FrameLength == 0x10000)
|
|
{
|
|
OUTPW(reg1CE, SavedExtRegs[0]);
|
|
OUTPW(reg1CE, SavedExtRegs[1]);
|
|
OUTPW(reg1CE, SavedExtRegs[2]);
|
|
OUTP(reg1CE, 0xBE);
|
|
OUTPW(reg1CE, (WORD)(((INP(reg1CF) & 0xF7) << 8) | 0xBE));
|
|
}
|
|
UninitTiDac_m();
|
|
Passth8514_m(SHOW_VGA);
|
|
|
|
VideoPortZeroMemory(&Registers, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
|
|
Registers.Eax = 0x0003; // set text mode 3
|
|
VideoPortInt10(phwDeviceExtension, &Registers);
|
|
|
|
} /* ResetDevice_m() */
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* VP_STATUS SetPowerManagement_m(QueryPtr, DpmsState);
|
|
*
|
|
* struct query_structure *QueryPtr; Query information for the card
|
|
* DWORD DpmsState; Desired DPMS state
|
|
* (VIDEO_POWER_STATE enumeration)
|
|
*
|
|
* DESCRIPTION:
|
|
* Switch into the desired DPMS state.
|
|
*
|
|
* RETURN VALUE:
|
|
* NO_ERROR if successful
|
|
* ERROR_INVALID_PARAMETER if invalid state requested.
|
|
*
|
|
* GLOBALS CHANGED:
|
|
* none
|
|
*
|
|
* CALLED BY:
|
|
* IOCTL_VIDEO_SET_POWER_MANAGEMENT packet of ATIMPStartIO()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
VP_STATUS SetPowerManagement_m(struct query_structure *QueryPtr, DWORD DpmsState)
|
|
{
|
|
struct st_mode_table *CrtTable; /* Mode table, used to obtain sync values */
|
|
|
|
/*
|
|
* Only accept valid states.
|
|
*/
|
|
if ((DpmsState < VideoPowerOn) || (DpmsState > VideoPowerOff))
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
/*
|
|
* Set CrtTable to point to the mode table associated with the
|
|
* selected mode.
|
|
*
|
|
* When a pointer to a structure is incremented by an integer,
|
|
* the integer represents the number of structure-sized blocks
|
|
* to skip over, not the number of bytes to skip over.
|
|
*/
|
|
CrtTable = (struct st_mode_table *)QueryPtr;
|
|
((struct query_structure *)CrtTable)++;
|
|
CrtTable += phwDeviceExtension->ModeIndex;
|
|
|
|
SavedDPMSState = DpmsState;
|
|
|
|
/*
|
|
* Mach 32 rev. 6 and later supports turning the sync signals on and off
|
|
* through the HORZ_OVERSCAN registers, but some chips that report as
|
|
* rev. 6 don't have this implemented. Also, Mach 32 rev. 3 and Mach 8
|
|
* don't support this mechanism.
|
|
*
|
|
* Disabling the sync by setting it to start after the total will work
|
|
* for all chips. Most chips will de-synchronize if the sync is set
|
|
* to 1 more than the total, but some need higher values. To be sure
|
|
* of de-synchronizing, set the disabled sync signal to start at
|
|
* the highest possible value.
|
|
*/
|
|
switch (DpmsState)
|
|
{
|
|
case VideoPowerOn:
|
|
OUTP(H_SYNC_STRT, CrtTable->m_h_sync_strt);
|
|
OUTPW(V_SYNC_STRT, CrtTable->m_v_sync_strt);
|
|
break;
|
|
|
|
case VideoPowerStandBy:
|
|
OUTP(H_SYNC_STRT, 0xFF);
|
|
OUTPW(V_SYNC_STRT, CrtTable->m_v_sync_strt);
|
|
break;
|
|
|
|
case VideoPowerSuspend:
|
|
OUTP(H_SYNC_STRT, CrtTable->m_h_sync_strt);
|
|
OUTPW(V_SYNC_STRT, 0x0FFF);
|
|
break;
|
|
|
|
case VideoPowerOff:
|
|
OUTP(H_SYNC_STRT, 0xFF);
|
|
OUTPW(V_SYNC_STRT, 0x0FFF);
|
|
break;
|
|
|
|
/*
|
|
* This case should never happen, because the initial
|
|
* acceptance of only valid states should have already
|
|
* rejected anything that will appear here.
|
|
*/
|
|
default:
|
|
break;
|
|
}
|
|
return NO_ERROR;
|
|
|
|
} /* SetPowerManagement_m() */
|
|
|
|
|
|
DWORD GetPowerManagement_m(PHW_DEVICE_EXTENSION phwDeviceExtension)
|
|
/*
|
|
* DESCRIPTION:
|
|
* Report which DPMS state we are in.
|
|
*
|
|
* PARAMETERS:
|
|
* phwDeviceExtension Points to per-adapter device extension.
|
|
*
|
|
* RETURN VALUE:
|
|
* Current DPMS state (VIDEO_POWER_STATE enumeration).
|
|
*/
|
|
{
|
|
ASSERT(phwDeviceExtension != NULL);
|
|
|
|
/*
|
|
* On the Mach 8, the sync start registers are write-only, so
|
|
* we can't check which state we are in. For this reason, we
|
|
* have saved the state we switched into using SetPowerManagement_m().
|
|
* On the Mach 32, we can either use this saved state or read
|
|
* the sync start registers, but using the same method as for
|
|
* the Mach 8 reduces complexity.
|
|
*/
|
|
return SavedDPMSState;
|
|
} /* GetPowerManagement_m() */
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* VP_STATUS ShareVideoMemory_m(RequestPacket, QueryPtr);
|
|
*
|
|
* PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
|
|
* struct query_structure *QueryPtr; Query information for the card
|
|
*
|
|
* DESCRIPTION:
|
|
* Allow applications to do direct screen access through DCI.
|
|
*
|
|
* RETURN VALUE:
|
|
* NO_ERROR if successful
|
|
* error code if failed
|
|
*
|
|
* CALLED BY:
|
|
* IOCTL_VIDEO_SHARE_VIDEO_MEMORY packet of ATIMPStartIO()
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
VP_STATUS ShareVideoMemory_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
|
|
{
|
|
PVIDEO_SHARE_MEMORY InputPtr; /* Pointer to input structure */
|
|
PVIDEO_SHARE_MEMORY_INFORMATION OutputPtr; /* Pointer to output structure */
|
|
PHYSICAL_ADDRESS ShareAddress; /* Physical address of video memory */
|
|
PVOID VirtualAddress; /* Virtual address to map video memory at */
|
|
ULONG SharedViewSize; /* Size of block to share */
|
|
ULONG SpaceType; /* Sparse or dense space? */
|
|
VP_STATUS Status; /* Status to return */
|
|
|
|
/*
|
|
* We can only share the aperture with application programs if there
|
|
* is an aperture available. If both the LFB and the on-board VGA
|
|
* and therefore the VGA aperture) are disabled, report that we
|
|
* can't share the aperture.
|
|
*/
|
|
if ((QueryPtr->q_aperture_cfg == 0) && (QueryPtr->q_VGA_type == 0))
|
|
return ERROR_INVALID_FUNCTION;
|
|
|
|
InputPtr = RequestPacket->InputBuffer;
|
|
|
|
if ((InputPtr->ViewOffset > phwDeviceExtension->VideoRamSize) ||
|
|
((InputPtr->ViewOffset + InputPtr->ViewSize) > phwDeviceExtension->VideoRamSize))
|
|
{
|
|
VideoDebugPrint((DEBUG_ERROR, "ShareVideoMemory_m() - access beyond video memory\n"));
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
RequestPacket->StatusBlock->Information = sizeof(VIDEO_SHARE_MEMORY_INFORMATION);
|
|
|
|
/*
|
|
* Beware: the input buffer and the output buffer are the same buffer,
|
|
* and therefore data should not be copied from one to the other.
|
|
*/
|
|
VirtualAddress = InputPtr->ProcessHandle;
|
|
SharedViewSize = InputPtr->ViewSize;
|
|
|
|
SpaceType = 0;
|
|
#if defined(_ALPHA_)
|
|
/*
|
|
* Use dense space mapping whenever we can, because that will
|
|
* allow us to support DCI and direct GDI access.
|
|
*
|
|
* Dense space is extremely slow with ISA cards on the newer Alphas,
|
|
* because any byte- or word-write requires a read/modify/write
|
|
* operation, and the ALpha can only ever do 64-bit reads when in
|
|
* dense mode. As a result, these operations would always require
|
|
* 4 reads and 2 writes on the ISA bus. Also, some older Alphas
|
|
* don't support dense space mapping.
|
|
*
|
|
* Any Alpha that supports PCI can support dense space mapping, and
|
|
* because the bus is wider and faster, the read/modify/write has
|
|
* less of an impact on performance.
|
|
*/
|
|
if (QueryPtr->q_bus_type == BUS_PCI)
|
|
SpaceType = 4;
|
|
#endif
|
|
|
|
/*
|
|
* NOTE: we are ignoring ViewOffset
|
|
*/
|
|
ShareAddress.QuadPart = phwDeviceExtension->PhysicalFrameAddress.QuadPart;
|
|
|
|
|
|
/*
|
|
* If the LFB is enabled, use ordinary mapping. If we have only
|
|
* the paged aperture, we must map to banked memory. Since the
|
|
* LFB is always aligned on a 1M boundary (4M boundary for 4M
|
|
* aperture), this check for the paged aperture will never falsely
|
|
* detect a LFB as paged.
|
|
*/
|
|
if (phwDeviceExtension->PhysicalFrameAddress.LowPart == 0x0A0000)
|
|
{
|
|
/*
|
|
* On some versions of the DDK, VideoPortMapBankedMemory() is
|
|
* not available. If this is the case, force an error.
|
|
* This routine should be available in all versions of
|
|
* the DDK which support DCI, since it is used for DCI
|
|
* support on cards with banked apertures.
|
|
*/
|
|
#if defined(IOCTL_VIDEO_SHARE_VIDEO_MEMORY)
|
|
Status = VideoPortMapBankedMemory(
|
|
phwDeviceExtension,
|
|
ShareAddress,
|
|
&SharedViewSize,
|
|
&SpaceType,
|
|
&VirtualAddress,
|
|
0x10000, /* 64k VGA aperture */
|
|
FALSE, /* No separate read/write banks */
|
|
BankMap_m, /* Our bank-mapping routine */
|
|
(PVOID) phwDeviceExtension);
|
|
#else
|
|
Status = ERROR_INVALID_FUNCTION;
|
|
#endif
|
|
}
|
|
else /* LFB */
|
|
{
|
|
Status = VideoPortMapMemory(phwDeviceExtension,
|
|
ShareAddress,
|
|
&SharedViewSize,
|
|
&SpaceType,
|
|
&VirtualAddress);
|
|
}
|
|
|
|
OutputPtr = RequestPacket->OutputBuffer;
|
|
OutputPtr->SharedViewOffset = InputPtr->ViewOffset;
|
|
OutputPtr->VirtualAddress = VirtualAddress;
|
|
OutputPtr->SharedViewSize = SharedViewSize;
|
|
|
|
return Status;
|
|
|
|
} /* ShareVideoMemory_m() */
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* void BankMap_m(BankRead, BankWrite, Context);
|
|
*
|
|
* ULONG BankRead; Bank to read
|
|
* ULONG BankWrite; Bank to write
|
|
* PVOID Context; Pointer to hardware-specific information
|
|
*
|
|
* DESCRIPTION:
|
|
* Map the selected bank of video memory into the 64k VGA aperture.
|
|
* We don't support separate read and write banks, so we use BankWrite
|
|
* to set the read/write bank, and ignore BankRead.
|
|
*
|
|
* CALLED BY:
|
|
* This is an entry point, rather than being called
|
|
* by other miniport functions.
|
|
*
|
|
* NOTE:
|
|
* This function is called directly by the memory manager during page
|
|
* fault handling, and so cannot be made pageable.
|
|
*
|
|
* AUTHOR:
|
|
* Robert Wolff
|
|
*
|
|
* CHANGE HISTORY:
|
|
*
|
|
* TEST HISTORY:
|
|
*
|
|
***************************************************************************/
|
|
|
|
void BankMap_m(ULONG BankRead, ULONG BankWrite, PVOID Context)
|
|
{
|
|
OUTPW( reg1CE, (USHORT)(((BankWrite & 0x0f) << 9) | 0xb2));
|
|
OUTPW( reg1CE, (USHORT)(((BankWrite & 0x30) << 4) | 0xae));
|
|
|
|
return;
|
|
|
|
} /* BankMap_m() */
|