600 lines
15 KiB
C
600 lines
15 KiB
C
|
/*++
|
|||
|
|
|||
|
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;
|
|||
|
}
|