986 lines
26 KiB
C
986 lines
26 KiB
C
/*++
|
||
|
||
Copyright (c) 1993, 1994 Weitek Corporation
|
||
|
||
Module Name:
|
||
|
||
wtkp91vl.c
|
||
|
||
Abstract:
|
||
|
||
This module contains OEM specific functions for the Weitek P9100
|
||
VL evaluation board.
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History may be found at the end of this file.
|
||
|
||
--*/
|
||
|
||
|
||
#include "p9.h"
|
||
#include "p9gbl.h"
|
||
#include "wtkp9xvl.h"
|
||
#include "bt485.h"
|
||
#include "vga.h"
|
||
#include "p91regs.h"
|
||
#include "p91dac.h"
|
||
#include "pci.h"
|
||
#include "p9000.h"
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
**********************************************************************/
|
||
VOID vDumpPCIConfig(PHW_DEVICE_EXTENSION HwDeviceExtension,
|
||
PUCHAR psz)
|
||
{
|
||
ULONG i, j;
|
||
ULONG ulPciData[64];
|
||
|
||
VideoDebugPrint((1, "\n%s\n", psz));
|
||
|
||
|
||
VideoPortGetBusData(HwDeviceExtension,
|
||
PCIConfiguration,
|
||
HwDeviceExtension->PciSlotNum,
|
||
(PVOID) ulPciData,
|
||
0,
|
||
sizeof(ulPciData));
|
||
|
||
for (i = 0, j = 0; i < (64 / 4); i++)
|
||
{
|
||
VideoDebugPrint((1,
|
||
"0x%04.4x\t %08.8x, %08.8x, %08.8x, %08.8x\n",
|
||
j * sizeof(ULONG),
|
||
ulPciData[j], ulPciData[j+1],
|
||
ulPciData[j+2], ulPciData[j+3]));
|
||
|
||
j += 4;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
BOOLEAN
|
||
VLGetBaseAddrP91(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Perform board detection and if present return the P9100 base address.
|
||
|
||
Arguments:
|
||
|
||
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
||
|
||
Return Value:
|
||
|
||
TRUE - Board found, P9100 and Frame buffer address info was placed in
|
||
the device extension.
|
||
|
||
FALSE - Board not found.
|
||
|
||
--*/
|
||
{
|
||
VP_STATUS status;
|
||
VIDEO_ACCESS_RANGE VLAccessRange;
|
||
USHORT usTemp;
|
||
|
||
|
||
VideoDebugPrint((1, "VLGetBaseAddrP91 - Entry\n"));
|
||
|
||
//
|
||
// Only the viper p9000 works on the Siemens boxes
|
||
//
|
||
|
||
if (HwDeviceExtension->MachineType == SIEMENS)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Always use the defined address for the p9100
|
||
//
|
||
|
||
if (HwDeviceExtension->MachineType != SIEMENS_P9100_VLB)
|
||
{
|
||
HwDeviceExtension->P9PhysAddr.LowPart = MemBase;
|
||
}
|
||
|
||
//
|
||
// Set the bus-type for accessing the VLB configuration space...
|
||
//
|
||
|
||
HwDeviceExtension->usBusType = VESA;
|
||
|
||
//
|
||
// Now, detect the board
|
||
//
|
||
|
||
//
|
||
//
|
||
// OEM Notice:
|
||
//
|
||
// Here we assume that the configuration space will always
|
||
// be mapped to 0x9100 for VL cards. Since this is determined
|
||
// by pull-down resistors on the VL cards this is probably
|
||
// a safe assumption. If anyone decides to use a different
|
||
// address then we should scan for the P9100 chip. The danger
|
||
// with scanning is that it is potentially destructive.
|
||
//
|
||
// Note that we cannot read the power-up configuration register
|
||
// until we setup addressability for the VESA local bus adapter.
|
||
//
|
||
// Also, on VESA LB you must read the VL configuration registers
|
||
// using byte port reads.
|
||
//
|
||
|
||
VLAccessRange.RangeInIoSpace = TRUE;
|
||
VLAccessRange.RangeVisible = TRUE;
|
||
VLAccessRange.RangeShareable = TRUE;
|
||
VLAccessRange.RangeStart.LowPart = P91_CONFIG_INDEX;
|
||
|
||
if (HwDeviceExtension->MachineType == SIEMENS_P9100_VLB)
|
||
{
|
||
VLAccessRange.RangeStart.LowPart |=
|
||
((DriverAccessRanges[1].RangeStart.LowPart & 0xff000000)) ;
|
||
}
|
||
|
||
VLAccessRange.RangeStart.HighPart = 0;
|
||
VLAccessRange.RangeLength = P91_CONFIG_CKSEL+1;
|
||
|
||
|
||
if (VideoPortVerifyAccessRanges(HwDeviceExtension,
|
||
1,
|
||
&VLAccessRange) != NO_ERROR)
|
||
{
|
||
return(FALSE);
|
||
}
|
||
|
||
VideoDebugPrint((1, "VLGetBaseAddrP91: RangeStart = %lx\n",
|
||
VLAccessRange.RangeStart));
|
||
|
||
VideoDebugPrint((1, "VLGetBaseAddrP91: RangeLength = %lx\n",
|
||
VLAccessRange.RangeLength));
|
||
|
||
if ((HwDeviceExtension->ConfigAddr =
|
||
VideoPortGetDeviceBase(HwDeviceExtension,
|
||
VLAccessRange.RangeStart,
|
||
VLAccessRange.RangeLength,
|
||
VLAccessRange.RangeInIoSpace)) == 0)
|
||
{
|
||
|
||
return(FALSE);
|
||
|
||
}
|
||
|
||
// Verify that we can write to the index registers...
|
||
//
|
||
|
||
VideoPortWritePortUchar(
|
||
(PUCHAR) HwDeviceExtension->ConfigAddr, 0x55);
|
||
|
||
if (VideoPortReadPortUchar(
|
||
(PUCHAR) HwDeviceExtension->ConfigAddr) != 0x55)
|
||
{
|
||
VideoDebugPrint((1, "VLGetBaseAddrP91: Could not access VESA LB Config space!\n"));
|
||
VideoDebugPrint((1, "VLGetBaseAddrP91: Wrote: 0x55, Read: %lx\n",
|
||
VideoPortReadPortUchar((PUCHAR) HwDeviceExtension->ConfigAddr)));
|
||
return(FALSE);
|
||
}
|
||
|
||
//
|
||
// Verify Vendor ID...
|
||
//
|
||
|
||
usTemp = ReadP9ConfigRegister(HwDeviceExtension,
|
||
P91_CONFIG_VENDOR_HIGH) << 8;
|
||
|
||
usTemp |= ReadP9ConfigRegister(HwDeviceExtension,
|
||
P91_CONFIG_VENDOR_LOW);
|
||
|
||
if (usTemp != WTK_VENDOR_ID)
|
||
{
|
||
VideoDebugPrint((1, "Invalid Vendor ID: %x\n", usTemp));
|
||
return(FALSE);
|
||
}
|
||
|
||
//
|
||
// Verify Device ID...
|
||
//
|
||
|
||
usTemp = ReadP9ConfigRegister(HwDeviceExtension,
|
||
P91_CONFIG_DEVICE_HIGH) << 8;
|
||
usTemp |= ReadP9ConfigRegister(HwDeviceExtension,
|
||
P91_CONFIG_DEVICE_LOW);
|
||
|
||
if (usTemp != WTK_9100_ID)
|
||
{
|
||
VideoDebugPrint((1, "Invalid Device ID: %x\n", usTemp));
|
||
return(FALSE);
|
||
}
|
||
|
||
//
|
||
// Now program the P9100 to respond to the requested physical address...
|
||
//
|
||
|
||
if (HwDeviceExtension->MachineType != SIEMENS_P9100_VLB)
|
||
{
|
||
WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_WBASE,
|
||
(UCHAR)(((HwDeviceExtension->P9PhysAddr.LowPart >> 24) & 0xFF)));
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// The physical address base put on the VL-bus (in its memory space)
|
||
// is always set to zero by the FirmWare (in the MapVLBase register).
|
||
//
|
||
|
||
WriteP9ConfigRegister (HwDeviceExtension ,P91_CONFIG_WBASE ,0) ;
|
||
|
||
}
|
||
|
||
|
||
VideoDebugPrint((1, "VLGetBaseAddrP91: Found a P9100 VLB Adapter!\n"));
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
VOID
|
||
VLSetModeP91(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine sets the video mode. Different OEM adapter implementations
|
||
require that initialization operations be performed in a certain
|
||
order. This routine uses the standard order which addresses most
|
||
implementations (VL, Ajax, Weitek PCI, Tulip).
|
||
|
||
Arguments:
|
||
|
||
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
VideoDebugPrint((2, "VLSetModeP91 - Entry\n"));
|
||
|
||
//
|
||
// Enable P9100 video if not already enabled.
|
||
//
|
||
|
||
if (!HwDeviceExtension->p91State.bEnabled)
|
||
HwDeviceExtension->AdapterDesc.P9EnableVideo(HwDeviceExtension);
|
||
|
||
//
|
||
// If this mode uses the palette, clear it to all 0s.
|
||
//
|
||
|
||
if (P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.AttributeFlags
|
||
& VIDEO_MODE_PALETTE_DRIVEN)
|
||
{
|
||
HwDeviceExtension->Dac.DACClearPalette(HwDeviceExtension);
|
||
}
|
||
|
||
VideoDebugPrint((2, "VLSetModeP91 - Exit\n"));
|
||
|
||
|
||
} // End of VLSetModeP91()
|
||
|
||
|
||
VOID
|
||
VLEnableP91(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Perform the OEM specific tasks necessary to enable P9100 Video. These
|
||
include memory mapping, setting the sync polarities, and enabling the
|
||
P9100 video output.
|
||
|
||
Arguments:
|
||
|
||
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
USHORT usMemClkInUse;
|
||
|
||
VideoDebugPrint((2, "VLEnableP91 - Entry\n"));
|
||
|
||
//
|
||
// Enable native mode to: No RAMDAC shadowing, memory & I/O enabled.
|
||
//
|
||
|
||
if (HwDeviceExtension->usBusType == VESA)
|
||
{
|
||
WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_CONFIGURATION, 3);
|
||
}
|
||
|
||
WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_MODE, 0); // Native mode
|
||
|
||
//
|
||
// Only initialize the P9100 once...
|
||
//
|
||
|
||
if (!HwDeviceExtension->p91State.bInitialized)
|
||
{
|
||
|
||
HwDeviceExtension->p91State.bInitialized = TRUE;
|
||
|
||
//
|
||
// Now read the power-up configuration register to determine the actual
|
||
// board-options.
|
||
//
|
||
|
||
HwDeviceExtension->p91State.ulPuConfig = P9_RD_REG(P91_PU_CONFIG);
|
||
|
||
#if 0
|
||
vDumpPCIConfig(HwDeviceExtension, "VLEnableP91, just after reading P91_PU_CONFIG");
|
||
#endif
|
||
//
|
||
// Determine the VRAM type:
|
||
//
|
||
|
||
HwDeviceExtension->p91State.bVram256 =
|
||
(HwDeviceExtension->p91State.ulPuConfig & P91_PUC_MEMORY_DEPTH)
|
||
? FALSE : TRUE;
|
||
|
||
//
|
||
// Determine the type of Clock Synthesizer:
|
||
//
|
||
|
||
switch((HwDeviceExtension->p91State.ulPuConfig &
|
||
P91_PUC_FREQ_SYNTH_TYPE) >> P91_PUC_SYNTH_SHIFT_CNT)
|
||
{
|
||
case CLK_ID_ICD2061A:
|
||
|
||
HwDeviceExtension->p91State.usClockID = CLK_ID_ICD2061A;
|
||
break;
|
||
|
||
case CLK_ID_FIXED_MEMCLK:
|
||
|
||
HwDeviceExtension->p91State.usClockID = CLK_ID_FIXED_MEMCLK;
|
||
break;
|
||
|
||
default: // Set to ICD2061a & complain... (but continue)
|
||
|
||
HwDeviceExtension->p91State.usClockID = CLK_ID_ICD2061A;
|
||
VideoDebugPrint((1, "Unrecognized frequency synthesizer; Assuming ICD2061A.\n"));
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Determine the type of RAMDAC:
|
||
//
|
||
|
||
switch((HwDeviceExtension->p91State.ulPuConfig &
|
||
P91_PUC_RAMDAC_TYPE) >> P91_PUC_RAMDAC_SHIFT_CNT)
|
||
{
|
||
case DAC_ID_BT485:
|
||
|
||
HwDeviceExtension->Dac.usRamdacID = DAC_ID_BT485;
|
||
HwDeviceExtension->Dac.usRamdacWidth = 32;
|
||
HwDeviceExtension->Dac.bRamdacUsePLL = FALSE;
|
||
break;
|
||
|
||
case DAC_ID_BT489:
|
||
|
||
HwDeviceExtension->Dac.usRamdacID = DAC_ID_BT489;
|
||
HwDeviceExtension->Dac.usRamdacWidth = 64;
|
||
HwDeviceExtension->Dac.bRamdacUsePLL = FALSE;
|
||
break;
|
||
|
||
case DAC_ID_IBM525:
|
||
|
||
HwDeviceExtension->Dac.usRamdacID = DAC_ID_IBM525;
|
||
HwDeviceExtension->Dac.usRamdacWidth = 64;
|
||
HwDeviceExtension->Dac.bRamdacUsePLL = TRUE; // Assume PLL
|
||
break;
|
||
|
||
default: // Set to BT485 & complain... (but continue)
|
||
|
||
HwDeviceExtension->Dac.usRamdacID = DAC_ID_BT485;
|
||
HwDeviceExtension->Dac.usRamdacWidth = 32;
|
||
HwDeviceExtension->Dac.bRamdacUsePLL = FALSE;
|
||
VideoDebugPrint((1, "Unrecognized RAMDAC specified; Assuming BT485.\n"));
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Read and store P9100 revision ID for later reference...
|
||
//
|
||
|
||
P9_WR_REG(P91_SYSCONFIG, 0x00000000);
|
||
HwDeviceExtension->p91State.usRevisionID = (USHORT)
|
||
(P9_RD_REG(P91_SYSCONFIG) & 0x00000007);
|
||
|
||
}
|
||
|
||
//
|
||
// Now program the detected hardware...
|
||
//
|
||
|
||
//
|
||
// A1/A2 silicon SPLIT SHIFT TRANSFER BUG FIX
|
||
//
|
||
// This is the main logic for the split shift transfer bug software work
|
||
// around. The current assumption is that the RAMDAC will always be doing
|
||
// the dividing of the clock.
|
||
//
|
||
|
||
HwDeviceExtension->Dac.bRamdacDivides = TRUE;
|
||
|
||
HwDeviceExtension->Dac.DACRestore(HwDeviceExtension);
|
||
|
||
//
|
||
// First setup the MEMCLK frequency...
|
||
//
|
||
|
||
usMemClkInUse = (HwDeviceExtension->p91State.usRevisionID ==
|
||
WTK_9100_REV1) ? DEF_P9100_REV1_MEMCLK :
|
||
DEF_P9100_MEMCLK;
|
||
|
||
// Program MEMCLK
|
||
|
||
ProgramClockSynth(HwDeviceExtension, usMemClkInUse, TRUE, FALSE);
|
||
|
||
//
|
||
// Next setup the pixel clock frequency. We have to handle potential
|
||
// clock multiplicaiton by the RAMDAC. On the BT485 if the dotfreq
|
||
// is greater than the maximum clock freq then we will adjust the
|
||
// dot frequency to program the clock with.
|
||
//
|
||
|
||
//
|
||
// Program Pix clk
|
||
//
|
||
|
||
ProgramClockSynth(HwDeviceExtension,
|
||
(USHORT) HwDeviceExtension->VideoData.dotfreq1,
|
||
FALSE,
|
||
TRUE);
|
||
|
||
//
|
||
// Determine size of Vram (ulFrameBufferSize)...
|
||
//
|
||
|
||
if (HwDeviceExtension->p91State.bVram256)
|
||
{
|
||
if (HwDeviceExtension->p91State.ulFrameBufferSize == 0x0400000)
|
||
{
|
||
P9_WR_REG(P91_MEM_CONFIG, 0x00000007);
|
||
}
|
||
else
|
||
{
|
||
P9_WR_REG(P91_MEM_CONFIG, 0x00000005);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
P9_WR_REG(P91_MEM_CONFIG, 0x00000003);
|
||
}
|
||
|
||
#if 0
|
||
|
||
//
|
||
// Here we will attempt to attempt to free the virtual address space
|
||
// for the initial frame buffer setting, and we will attempt to re-map
|
||
// the frambuffer into system virtual address space to reflect the
|
||
// actual size of the framebuffer.
|
||
//
|
||
|
||
VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->FrameAddress);
|
||
|
||
// Set the actual size
|
||
|
||
DriverAccessRanges[2].RangeLength = HwDeviceExtension->p91State.ulFrameBufferSize;
|
||
|
||
if ( (HwDeviceExtension->FrameAddress = (PVOID)
|
||
VideoPortGetDeviceBase(HwDeviceExtension,
|
||
DriverAccessRanges[2].RangeStart,
|
||
DriverAccessRanges[2].RangeLength,
|
||
DriverAccessRanges[2].RangeInIoSpace)) == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
#endif
|
||
|
||
//
|
||
// Setup actual framebuffer length...
|
||
//
|
||
|
||
HwDeviceExtension->FrameLength =
|
||
HwDeviceExtension->p91State.ulFrameBufferSize;
|
||
|
||
//
|
||
// Init system config & clipping registers...
|
||
//
|
||
|
||
P91_SysConf(HwDeviceExtension);
|
||
|
||
//
|
||
// Calculate memconfig and srtctl register values...
|
||
//
|
||
|
||
CalcP9100MemConfig(HwDeviceExtension);
|
||
|
||
//
|
||
// Now apply the AND and OR masks specified in the mode information
|
||
// structure.
|
||
//
|
||
// Note: It is assumed that if these values are not specified in the .DAT
|
||
// file, then they will be initialized as 0xFFFFFFFF for the AND
|
||
// mask and 0x00000000 for the OR mask.
|
||
//
|
||
// Only the blank_edge (bit 19) and the blnkdly (bits 27-28) are valid
|
||
// fields for override.
|
||
//
|
||
// Apply the AND mask to clear the specified bits.
|
||
//
|
||
|
||
HwDeviceExtension->p91State.ulMemConfVal &=
|
||
((ULONG) HwDeviceExtension->VideoData.ulMemCfgClr |
|
||
~((ULONG) P91_MC_BLANK_EDGE_MSK |
|
||
(ULONG) P91_MC_BLNKDLY_MSK));
|
||
|
||
//
|
||
// Apply the OR mask to set the specified bits.
|
||
//
|
||
|
||
HwDeviceExtension->p91State.ulMemConfVal |=
|
||
((ULONG) HwDeviceExtension->VideoData.ulMemCfgSet &
|
||
((ULONG) P91_MC_BLANK_EDGE_MSK |
|
||
(ULONG) P91_MC_BLNKDLY_MSK));
|
||
|
||
//
|
||
// Load the video timing registers...
|
||
//
|
||
|
||
P91_WriteTiming(HwDeviceExtension);
|
||
|
||
//
|
||
// Setup the RAMDAC to the current mode...
|
||
//
|
||
|
||
HwDeviceExtension->Dac.DACInit(HwDeviceExtension);
|
||
|
||
//
|
||
// Setup MEMCONFIG and SRTCTL regs
|
||
//
|
||
|
||
SetupVideoBackend(HwDeviceExtension);
|
||
|
||
//
|
||
// Set the native-mode enabled flag...
|
||
//
|
||
|
||
HwDeviceExtension->p91State.bEnabled = TRUE;
|
||
|
||
#ifdef _MIPS_
|
||
if(HwDeviceExtension->MachineType == SIEMENS_P9100_VLB) {
|
||
// SNI specific
|
||
// First point:
|
||
// Od: 27-11-95 The vram_miss_adj/vram_read_adj/vram_read_sample bits
|
||
// are documented to be set to 1 by WEITECK or risk some troubles...
|
||
// anyway, on our Mips/VL architecture, it helps hardfully when
|
||
// they are cleared; otherwhise, we lost about 1 bit every 1500 Kilo bytes
|
||
// during largescreen to host transfers...
|
||
// Any Way we feel it confortable because it should speed up our graphics...
|
||
{
|
||
ULONG ulMemConfig;
|
||
|
||
// 1/ read the value programmed by CalcP9100MemConfig
|
||
ulMemConfig = P9_RD_REG(P91_MEM_CONFIG);
|
||
|
||
// 2/ clear the 3 read-delaies bits
|
||
ulMemConfig &= ~(P91_MC_MISS_ADJ_1|P91_MC_READ_ADJ_1
|
||
|P91_MC_READ_SMPL_ADJ_1);
|
||
|
||
// 3/ write it back
|
||
P9_WR_REG(P91_MEM_CONFIG, ulMemConfig);
|
||
}
|
||
|
||
// Second point:
|
||
// Od: 2/10/95B: with large resolution, the frame buffer will overlap
|
||
// with the good old ROM Bios, around xC0000 to xE0000, x=8,9,...
|
||
// since ROM relocation does NOT run on VLB systems (hard wired..)
|
||
// we relocate the frame buffer instead:
|
||
{
|
||
unsigned char * HiOrderByteReg, HiOrderByteVal;
|
||
|
||
// to achieve that goal,
|
||
|
||
// 1/ we ask the P9100 to respond to 8xxxxxxxx address rather than 0xxxxxxxx
|
||
|
||
HiOrderByteVal=0x80; // Od: why not ?
|
||
WriteP9ConfigRegister(HwDeviceExtension,P91_CONFIG_WBASE,HiOrderByteVal);
|
||
|
||
// 2/ we tell the mother board to set the high order byte for each
|
||
// related addresses
|
||
|
||
{
|
||
extern VP_STATUS GetCPUIdCallback(
|
||
PVOID HwDeviceExtension,
|
||
PVOID Context,
|
||
VIDEO_DEVICE_DATA_TYPE DeviceDataType,
|
||
PVOID Identifier,
|
||
ULONG IdentifierLength,
|
||
PVOID ConfigurationData,
|
||
ULONG ConfigurationDataLength,
|
||
PVOID ComponentInformation,
|
||
ULONG ComponentInformationLength
|
||
);
|
||
|
||
if(VideoPortIsCpu(L"RM200"))
|
||
HiOrderByteReg = (unsigned char *) 0xBFCC0000;
|
||
else
|
||
if(VideoPortIsCpu(L"RM400-MT"))
|
||
{
|
||
HiOrderByteReg = (unsigned char *) 0xBC010000;
|
||
HiOrderByteVal = ~HiOrderByteVal;
|
||
}
|
||
else
|
||
if(VideoPortIsCpu(L"RM400-T")
|
||
|| VideoPortIsCpu(L"RM400-T MP"))
|
||
{
|
||
HiOrderByteReg = (unsigned char *) 0xBC0C0000;
|
||
HiOrderByteVal = ~HiOrderByteVal;
|
||
}
|
||
}
|
||
|
||
*HiOrderByteReg = HiOrderByteVal;
|
||
|
||
// NOTE that at this point (Dll ending up init by enabling the surface),
|
||
// we will not be able to switch back to VGA;
|
||
}
|
||
}
|
||
#endif // SIEMENS_P9100_VLB
|
||
|
||
VideoDebugPrint((2, "VLEnableP91 - Exit\n"));
|
||
|
||
return;
|
||
|
||
} // End of VLEnableP91()
|
||
|
||
|
||
|
||
|
||
BOOLEAN
|
||
VLDisableP91(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Disables native mode (switches to emulation mode (VGA)) and does
|
||
an INT10 for mode 3. Note that this will also reset the DAC to
|
||
VGA mode/3.
|
||
|
||
Arguments:
|
||
|
||
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
||
pPal - Pointer to the array of pallete entries.
|
||
StartIndex - Specifies the first pallete entry provided in pPal.
|
||
Count - Number of palette entries in pPal
|
||
|
||
Return Value:
|
||
|
||
FALSE, indicating an int10 modeset needs to be done to complete the
|
||
switch.
|
||
|
||
--*/
|
||
|
||
{
|
||
VideoDebugPrint((2, "VLDisableP91 - Entry\n"));
|
||
|
||
//
|
||
// Disable native-mode (set emulation-mode) only if native-mode is
|
||
// already enabled...
|
||
//
|
||
|
||
if (!HwDeviceExtension->p91State.bEnabled)
|
||
return (HwDeviceExtension->MachineType != SIEMENS_P9100_VLB) ?
|
||
TRUE : FALSE;
|
||
|
||
//
|
||
// Set emulation-mode (VGA)...
|
||
//
|
||
|
||
WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_MODE, 0x02);
|
||
|
||
//
|
||
// Set enabled flag
|
||
//
|
||
|
||
HwDeviceExtension->p91State.bEnabled = FALSE;
|
||
|
||
|
||
VideoDebugPrint((2, "VLDisableP91 - Exit\n"));
|
||
|
||
return (HwDeviceExtension->MachineType != SIEMENS_P9100_VLB) ?
|
||
FALSE : TRUE;
|
||
|
||
} // End of VLDisableP91()
|
||
|
||
|
||
UCHAR
|
||
ReadP9ConfigRegister(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
||
UCHAR regnum
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Reads and returns value from the specified VLB or PCI configuration space.
|
||
|
||
Arguments:
|
||
|
||
regnum - register to read.
|
||
|
||
Return Value:
|
||
|
||
Returns specified registers 8-bit value.
|
||
|
||
--*/
|
||
|
||
{
|
||
ULONG ulTemp;
|
||
|
||
VideoDebugPrint((2, "ReadP9ConfigRegister - Entry\n"));
|
||
|
||
ulTemp = 0;
|
||
|
||
switch (HwDeviceExtension->usBusType)
|
||
{
|
||
case VESA:
|
||
|
||
//
|
||
// Select the register, and return the value.
|
||
//
|
||
|
||
VideoPortWritePortUchar((PUCHAR) HwDeviceExtension->ConfigAddr, regnum);
|
||
|
||
ulTemp = VideoPortReadPortUchar((PUCHAR) HwDeviceExtension->ConfigAddr + 4L);
|
||
|
||
break;
|
||
|
||
case PCI:
|
||
|
||
if (!VideoPortGetBusData(HwDeviceExtension,
|
||
PCIConfiguration,
|
||
HwDeviceExtension->PciSlotNum,
|
||
&ulTemp,
|
||
regnum,
|
||
sizeof(ulTemp)))
|
||
{
|
||
VideoDebugPrint((1, "ReadP9ConfigRegister: Cannot read from PCI Config Space!\n"));
|
||
}
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
VideoDebugPrint((1, "ReadP9ConfigRegister: Unknown bus-type!\n"));
|
||
ulTemp = 0;
|
||
break;
|
||
}
|
||
|
||
VideoDebugPrint((2, "ReadP9ConfigRegister - Exit\n"));
|
||
|
||
return ((UCHAR) ulTemp);
|
||
|
||
} // End of ReadP9ConfigRegister()
|
||
|
||
|
||
VOID
|
||
WriteP9ConfigRegister(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension,
|
||
UCHAR regnum,
|
||
UCHAR jValue
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Writes the specified value to the specified register within the VLB
|
||
or PCI configuration space.
|
||
|
||
Arguments:
|
||
|
||
regnum - desired register,
|
||
value - value to write.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
VideoDebugPrint((3, "WriteP9ConfigRegister - Entry\n"));
|
||
|
||
switch (HwDeviceExtension->usBusType)
|
||
{
|
||
case VESA:
|
||
|
||
//
|
||
// Select the register, and write the value.
|
||
//
|
||
|
||
VideoPortWritePortUchar((PUCHAR) HwDeviceExtension->ConfigAddr, regnum);
|
||
VideoPortWritePortUchar((PUCHAR) HwDeviceExtension->ConfigAddr+4L, jValue);
|
||
|
||
break;
|
||
|
||
case PCI:
|
||
|
||
if (!VideoPortSetBusData(HwDeviceExtension,
|
||
PCIConfiguration,
|
||
HwDeviceExtension->PciSlotNum,
|
||
&jValue,
|
||
regnum,
|
||
1))
|
||
{
|
||
VideoDebugPrint((1, "WriteP9ConfigRegister: Cannot write to PCI Config Space!\n"));
|
||
}
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
VideoDebugPrint((1, "ERROR: WriteP9ConfigRegister - Unknown bus-type!\n"));
|
||
break;
|
||
}
|
||
|
||
VideoDebugPrint((3, "WriteP9ConfigRegister - Exit\n"));
|
||
|
||
|
||
} // End of WriteP9ConfigRegister()
|
||
|
||
|
||
VOID
|
||
SetupVideoBackend(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Program the MEMCONFIG and SRTCTL registers (see comments). For the
|
||
Power 9100 only.
|
||
|
||
Arguments:
|
||
|
||
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
ULONG ulSRTCTL2;
|
||
|
||
VideoDebugPrint((2, "SetupVideoBackend - Entry\n"));
|
||
|
||
//
|
||
// Program the MEMCONFIG and SRTCTL registers
|
||
//
|
||
// There are two main modes in which the video backend can operate:
|
||
// One is a mode in which the P9100 gets the pixel clock (pixclk) and
|
||
// divides it to generate the RAMDAC load clock, and the other is
|
||
// a mode in which the RAMDAC divides the clock and supplies it through
|
||
// the divpixclk input.
|
||
//
|
||
// If you are using the mode where the RAMDAC provides the divided clock
|
||
// then you must make sure that the RAMDAC is generating the divided clock
|
||
// before you switch MEMCONFIG to use the divided clock. Otherwise, you
|
||
// run the risk of hanging the P9100 since certain synchronizers depend
|
||
// upon a video clock to operate. For instance: when you write to a video
|
||
// register you must have a video clock running or the P9100 will not be
|
||
// able to complete the write, and it will hang the system.
|
||
//
|
||
// Note that the Ramdac should always divide the pixclk in 24(bits)pp mode.
|
||
//
|
||
|
||
//
|
||
// The SRTCTL2 register controls the sync polarities and can also force
|
||
// the syncs high or low for the monitor power-down modes.
|
||
//
|
||
|
||
ulSRTCTL2 = 0L;
|
||
|
||
ulSRTCTL2 |= (HwDeviceExtension->VideoData.hp) ? P91_HSYNC_HIGH_TRUE :
|
||
P91_HSYNC_LOW_TRUE;
|
||
|
||
ulSRTCTL2 |= (HwDeviceExtension->VideoData.vp) ? P91_VSYNC_HIGH_TRUE :
|
||
P91_VSYNC_LOW_TRUE;
|
||
|
||
P9_WR_REG(P91_MEM_CONFIG, HwDeviceExtension->p91State.ulMemConfVal);
|
||
P9_WR_REG(P91_SRTCTL, HwDeviceExtension->p91State.ulSrctlVal);
|
||
P9_WR_REG(P91_SRTCTL2, ulSRTCTL2);
|
||
|
||
|
||
VideoDebugPrint((2, "SetupVideoBackend: ulMemConfVal = %lx\n",
|
||
HwDeviceExtension->p91State.ulMemConfVal));
|
||
VideoDebugPrint((2, "SetupVideoBackend: ulSrctlVal = %lx\n",
|
||
HwDeviceExtension->p91State.ulSrctlVal));
|
||
VideoDebugPrint((2, "SetupVideoBackend: ulSRTCTL2 = %lx\n", ulSRTCTL2));
|
||
VideoDebugPrint((2, "SetupVideoBackend: dotfreq1 = %ld\n",
|
||
HwDeviceExtension->VideoData.dotfreq1));
|
||
VideoDebugPrint((2, "SetupVideoBackend: XSize = %ld\n",
|
||
HwDeviceExtension->VideoData.XSize));
|
||
VideoDebugPrint((2, "SetupVideoBackend: YSize = %ld\n",
|
||
HwDeviceExtension->VideoData.YSize));
|
||
VideoDebugPrint((2, "SetupVideoBackend: usBitsPixel = %ld\n",
|
||
HwDeviceExtension->usBitsPixel));
|
||
VideoDebugPrint((2, "SetupVideoBackend: iClkDiv = %ld\n",
|
||
HwDeviceExtension->AdapterDesc.iClkDiv));
|
||
VideoDebugPrint((2, "SetupVideoBackend: bRamdacDivides: %d\n",
|
||
HwDeviceExtension->Dac.bRamdacDivides));
|
||
VideoDebugPrint((2, "SetupVideoBackend: bRamdacUsePLL: %d\n",
|
||
HwDeviceExtension->Dac.bRamdacUsePLL));
|
||
VideoDebugPrint((2, "SetupVideoBackend: usRevisionID: %d\n",
|
||
HwDeviceExtension->p91State.usRevisionID));
|
||
VideoDebugPrint((2, "SetupVideoBackend: usBlnkDlyAdj: %d\n",
|
||
HwDeviceExtension->p91State.ulBlnkDlyAdj));
|
||
|
||
|
||
VideoDebugPrint((2, "SetupVideoBackend - Exit\n"));
|
||
|
||
return;
|
||
|
||
} // End of SetupVideoBackend()
|