|
|
/*++
Copyright (c) 1993 Weitek Corporation
Module Name:
wtkp90vl.c
Abstract:
This module contains OEM specific functions for the Weitek P9000 VL evaluation board.
Environment:
Kernel mode
Revision History may be found at the end of this file.
--*/
#include "p9.h"
#include "p9gbl.h"
#include "p9000.h"
#include "vga.h"
//
// Default memory addresses for the P9 registers/frame buffer.
//
#define MemBase 0xC0000000
//
// Bit to write to the sequencer control register to enable/disable P9
// video output.
//
#define P9_VIDEO_ENB 0x10
//
// Define the bit in the sequencer control register which determines
// the sync polarities. For Weitek board, 1 = positive.
//
#define HSYNC_POL_MASK 0x20
//
// OEM specific static data.
//
//
// List of valid base addresses for different Weitek based designs.
//
#define NUM_WTK_ADDRS 10
ULONG ulWtkAddrRanges[] = { 0x4000000L, 0x8000000L, 0xD000000L, 0xE000000L, 0xF000000L, 0x80000000L, 0xC0000000L, 0xD0000000L, 0xE0000000L, 0xF0000000L };
//
// VLDefDACRegRange contains info about the memory/io space ranges
// used by the DAC.
//
VIDEO_ACCESS_RANGE VLDefDACRegRange[] = { { 0x03C8, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x03C9, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x03C6, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x03C7, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x43C8, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x43C9, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x43C6, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x43C7, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x83C8, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x83C9, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x83C6, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0x83C7, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0xC3C8, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0xC3C9, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0xC3C6, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
}, { 0xC3C7, // Low address
0x00000000, // Hi address
0x01, // length
1, // Is range in i/o space?
1, // Range should be visible
1 // Range should be shareable
} };
BOOLEAN VLGetBaseAddr( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
Routine Description:
Perform board detection and if present return the P9000 base address.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
TRUE - Board found, P9 and Frame buffer address info was placed in the device extension.
FALSE - Board not found.
--*/ { SHORT i;
//
// Only the viper p9000 works on the Siemens boxes
//
if_SIEMENS_VLB() { return FALSE; }
if (HwDeviceExtension->P9PhysAddr.LowPart == 0) { //
// The base address was not found in the registry, so copy the
// default address into the device extension.
//
HwDeviceExtension->P9PhysAddr.LowPart = MemBase; }
if (!VLP90CoprocDetect(HwDeviceExtension, HwDeviceExtension->P9PhysAddr.LowPart)) { //
// Scan all possible base addresses to see if the coprocessor is
// present.
//
BOOLEAN bFound;
bFound = FALSE; for (i = 0; i < NUM_WTK_ADDRS && !bFound; i++) { if (ulWtkAddrRanges[i] + HwDeviceExtension->P9CoprocInfo.CoprocRegOffset != HwDeviceExtension->CoprocPhyAddr.LowPart) { if (VLP90CoprocDetect(HwDeviceExtension, ulWtkAddrRanges[i])) { HwDeviceExtension->P9PhysAddr.LowPart = ulWtkAddrRanges[i]; bFound = TRUE; break; } } } if (!bFound) { return(FALSE); } }
//
// Copy the DAC register access ranges to the global access range
// structure.
//
VideoPortMoveMemory(&DriverAccessRanges[NUM_DRIVER_ACCESS_RANGES], VLDefDACRegRange, HwDeviceExtension->Dac.cDacRegs * sizeof(VIDEO_ACCESS_RANGE)); return(TRUE); }
BOOLEAN VLP90CoprocDetect( PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ulCoprocPhyAddr )
/*++
Routine Description:
Perform P9000 coprocessor detection.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension. ulCoprocPhyAddr - The physical base address used for detection.
Return Values:
TRUE - Coprocessor found. FALSE - Coprocessor not found.
--*/ { VIDEO_ACCESS_RANGE VLAccessRange; ULONG ulTestPat = 0xFFFFFFFF; ULONG ulTemp;
//
// Set up the access range so we can map the coprocessor address space.
//
VLAccessRange.RangeInIoSpace = FALSE; VLAccessRange.RangeVisible = TRUE; VLAccessRange.RangeShareable = TRUE; VLAccessRange.RangeStart.LowPart = ulCoprocPhyAddr + HwDeviceExtension->P9CoprocInfo.CoprocRegOffset; VLAccessRange.RangeStart.HighPart = 0; VLAccessRange.RangeLength = HwDeviceExtension->P9CoprocInfo.CoprocLength;
//
//
// Check to see if another miniport driver has allocated any of the
// coprocessor's address space.
//
if (VideoPortVerifyAccessRanges(HwDeviceExtension, 1L, &VLAccessRange) != NO_ERROR) { return(FALSE); }
//
// Get a virtual address for the coprocessor's address space.
//
if ((HwDeviceExtension->Coproc = VideoPortGetDeviceBase(HwDeviceExtension, VLAccessRange.RangeStart, VLAccessRange.RangeLength, VLAccessRange.RangeInIoSpace)) == 0) { return(FALSE); }
//
// Write a test value to the location of the coprocessor's clipping
// window min register and attempt to read it back.
//
P9_WR_REG(WMIN, ulTestPat); ulTemp = P9_RD_REG(WMIN); VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->Coproc);
//
// The value read back from the clipping window min reg will have the
// high order 3 bits of each word clear.
//
if (ulTemp == (ulTestPat & P9_COORD_MASK)) { //
// Coprocessor is present.
//
return(TRUE); } else { //
// Coprocessor is absent.
//
return(FALSE); } }
VOID VLSetMode( 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.
--*/
{ //
// Set the dot clock.
//
DevSetClock(HwDeviceExtension, (USHORT) HwDeviceExtension->VideoData.dotfreq1, FALSE, TRUE);
//
// 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); }
//
// Save the value in the VGA's Misc Output register.
//
HwDeviceExtension->MiscRegState = VGA_RD_REG(MISCIN);
//
// Initialize the DAC.
//
HwDeviceExtension->Dac.DACInit(HwDeviceExtension);
//
// Enable P9 video.
//
HwDeviceExtension->AdapterDesc.P9EnableVideo(HwDeviceExtension);
}
VOID VLEnableP9( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
Routine Description:
Perform the OEM specific tasks necessary to enable P9000 Video. These include memory mapping, setting the sync polarities, and enabling the P9000 video output.
Arguments:
HwDeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
None.
--*/
{
USHORT holdit;
//
// Select external frequency.
//
VGA_WR_REG(MISCOUT, VGA_RD_REG(MISCIN) | (MISCD | MISCC));
//
// If this is a Weitek VGA, unlock it.
//
if (HwDeviceExtension->AdapterDesc.bWtk5x86) { UnlockVGARegs(HwDeviceExtension); }
VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX); holdit = VGA_RD_REG(SEQ_DATA_PORT);
//
// Set the sync polarity. First clear the sync polarity bits.
//
holdit &= ~HSYNC_POL_MASK;
if (HwDeviceExtension->VideoData.hp == POSITIVE) { holdit |= HSYNC_POL_MASK; }
holdit |= P9_VIDEO_ENB; VGA_WR_REG(SEQ_DATA_PORT, holdit);
//
// If this is a Weitek VGA, lock it.
//
if (HwDeviceExtension->AdapterDesc.bWtk5x86) { LockVGARegs(HwDeviceExtension); }
return; }
BOOLEAN VLDisableP9( PHW_DEVICE_EXTENSION HwDeviceExtension )
/*++
Routine Description:
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:
TRUE, indicating *no* int10 is needed to complete the switch
--*/
{ USHORT holdit;
//
// If this is a Weitek VGA, unlock it.
//
if (HwDeviceExtension->AdapterDesc.bWtk5x86) { UnlockVGARegs(HwDeviceExtension); }
VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX); holdit = VGA_RD_REG(SEQ_DATA_PORT);
//
// Disable P9000 video output.
//
holdit &= ~P9_VIDEO_ENB; VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX); VGA_WR_REG(SEQ_DATA_PORT, holdit);
//
// Restore clock select bits.
//
VGA_WR_REG(MISCOUT, HwDeviceExtension->MiscRegState);
//
// If this is a Weitek VGA, lock it.
//
if (HwDeviceExtension->AdapterDesc.bWtk5x86) { LockVGARegs(HwDeviceExtension); }
return TRUE; }
|