292 lines
7.8 KiB
C
292 lines
7.8 KiB
C
/*++
|
||
|
||
Copyright (c) 1993 Weitek Corporation
|
||
|
||
Module Name:
|
||
|
||
p9000.c
|
||
|
||
Abstract:
|
||
|
||
This module contains the code specific to the Weitek P9000.
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History may be found at the end of this file.
|
||
|
||
--*/
|
||
|
||
#include "p9.h"
|
||
#include "p9gbl.h"
|
||
#include "p9000.h"
|
||
|
||
//
|
||
// Static data for the P9000 specific support routines.
|
||
//
|
||
|
||
//
|
||
// This table is used to compute the qsfselect value for the P9000 Srctl
|
||
// register. This value is dependent upon a particular adapter's dot clock
|
||
// divisor and its memory configuration. See p. 64 of the P9000 manual for
|
||
// details.
|
||
//
|
||
|
||
ULONG qsfSelect[2][5] =
|
||
{
|
||
{4, 4, 5, 5, 6},
|
||
{3, 3, 4, 4, 5},
|
||
};
|
||
|
||
|
||
VOID
|
||
Init8720(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initialize the P9000.
|
||
|
||
Arguments:
|
||
|
||
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
|
||
P9_WR_REG(0x0000CL, 0x00000080L); //INTERRUPT-EN = disabled
|
||
P9_WR_REG(0x00118L, 0x00000000L); //PREHRZC = 0
|
||
P9_WR_REG(0x00130L, 0x00000000L); //PREVRTC = 0
|
||
|
||
//
|
||
// Initialize the P9 registers whose values are dependent upon a
|
||
// particular OEM implementation.
|
||
//
|
||
|
||
P9_WR_REG(MEMCONF, HwDeviceExtension->AdapterDesc.ulMemConfVal);
|
||
P9_WR_REG(SRCTL,
|
||
HwDeviceExtension->AdapterDesc.ulSrctlVal |
|
||
qsfSelect[(HwDeviceExtension->AdapterDesc.iClkDiv >> 2) - 1]
|
||
[HwDeviceExtension->AdapterDesc.ulMemConfVal]);
|
||
|
||
//
|
||
// Initialize non-implementation specific registers.
|
||
//
|
||
|
||
P9_WR_REG(0x00188L, 0x00000186L); //RFPERIOD =
|
||
P9_WR_REG(0x00190L, 0x000000FAL); //RLMAX =
|
||
P9_WR_REG(0x80208L, 0x000000FFL); //allow writing in all 8 planes
|
||
P9_WR_REG(0x8020CL, 0x0000000AL); //drawmode=buffer 0, write inside window
|
||
P9_WR_REG(0x80190L, 0x00000000L); //disable any co-ord offset
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
WriteTiming(
|
||
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:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
int div;
|
||
|
||
div = (HwDeviceExtension->AdapterDesc.iClkDiv)/(HwDeviceExtension->usBitsPixel / 8);
|
||
|
||
P9_WR_REG(0x010CL, HwDeviceExtension->VideoData.hsyncp/div - 1 ); // HRZSR
|
||
P9_WR_REG(0x0110L, (HwDeviceExtension->VideoData.hsyncp + HwDeviceExtension->VideoData.hbp) / div - 1 ); //HRZBR
|
||
P9_WR_REG(0x0114L, (HwDeviceExtension->VideoData.hsyncp + HwDeviceExtension->VideoData.hbp + HwDeviceExtension->VideoData.XSize)/div -1 ); //HRZBF
|
||
P9_WR_REG(0x0108L, (HwDeviceExtension->VideoData.hsyncp + HwDeviceExtension->VideoData.hbp + HwDeviceExtension->VideoData.XSize + HwDeviceExtension->VideoData.hfp)/div - 1 ); //HRZT
|
||
P9_WR_REG(0x0124L, HwDeviceExtension->VideoData.vsp); //VRTSR
|
||
P9_WR_REG(0x0128L, HwDeviceExtension->VideoData.vsp + HwDeviceExtension->VideoData.vbp ); //VRTBR
|
||
P9_WR_REG(0x012CL, HwDeviceExtension->VideoData.vsp + HwDeviceExtension->VideoData.vbp + HwDeviceExtension->VideoData.YSize ); //VRTBF
|
||
P9_WR_REG(0x0120L, HwDeviceExtension->VideoData.vsp + HwDeviceExtension->VideoData.vbp + HwDeviceExtension->VideoData.YSize+HwDeviceExtension->VideoData.vfp ); //VRTT
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
VOID
|
||
SysConf(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
int i,j; // loop counters
|
||
long sysval = 0x3000L; // swap bytes and words for little endian PC
|
||
|
||
int xtem = HwDeviceExtension->VideoData.XSize * (HwDeviceExtension->usBitsPixel / 8); //save a copy for clearing bits in
|
||
long ClipMax; // clipping register value for NotBusy to restore
|
||
|
||
if (xtem & 0xf80) // each field in the sysconreg can only set
|
||
{ // a limited range of bits in the size
|
||
j = 7; // each field is 3 bits wide
|
||
for (i = 2048; i >= 128;i >>= 1) // look at all the bits field 3 can effect
|
||
{
|
||
if (i & xtem) // if this bit is on,
|
||
{
|
||
sysval |= ((long) j) << 20; // use this field to set it
|
||
xtem &= ~i; // and remove the bit from the size
|
||
break; // each field can only set one bit
|
||
}
|
||
j -= 1;
|
||
}
|
||
}
|
||
|
||
if (xtem & 0x7C0) // do the same thing for field 2
|
||
{
|
||
j = 6; // each field is 3 bits wide
|
||
for (i = 1024; i >= 64; i >>= 1) // look at all the bits field 2 can effect
|
||
{
|
||
if (i & xtem) // if this bit is on,
|
||
{
|
||
sysval |= ((long)j)<<17; // use this field to set it
|
||
xtem &= ~i; // and remove the bit from the size
|
||
break; // each field can only set one bit
|
||
}
|
||
j -= 1;
|
||
}
|
||
}
|
||
|
||
if (xtem & 0x3E0) // do the same thing for field 1
|
||
{
|
||
j = 5; // each field is 3 bits wide
|
||
for (i = 512; i >= 32;i >>= 1) // look at all the bits field 1 can effect
|
||
{
|
||
if (i & xtem) // if this bit is on,
|
||
{
|
||
sysval |= ((long) j) << 14; // use this field to set it
|
||
xtem &= ~i; // and remove the bit from the size
|
||
break; // each field can only set one bit
|
||
}
|
||
j -= 1;
|
||
}
|
||
}
|
||
|
||
if (xtem != 0) // if there are bits left, it is an
|
||
return; // illegal x size.
|
||
|
||
P9_WR_REG(SYSCONFIG, sysval); // send data to the register
|
||
P9_WR_REG(WMIN, 0); // minimum clipping register
|
||
|
||
// calc and set max
|
||
|
||
ClipMax=((long) HwDeviceExtension->VideoData.XSize - 1) << 16 |
|
||
(div32(HwDeviceExtension->FrameLength, (SHORT) HwDeviceExtension->VideoData.XSize) - 1);
|
||
|
||
// clipping to allow access to all of the extra memory.
|
||
|
||
P9_WR_REG(WMAX, ClipMax);
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
P9000SizeMem(
|
||
PHW_DEVICE_EXTENSION HwDeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Determines the amount of video memory installed, as well as the P9000
|
||
memory configuration, and stores them in the device extension.
|
||
|
||
Arguments:
|
||
|
||
HwDeviceExtension - Pointer to the miniport driver's device extension.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PULONG pulFrameBufAddr = (PULONG) HwDeviceExtension->FrameAddress;
|
||
ULONG i;
|
||
|
||
//
|
||
// Assume 2 M of VRAM is installed.
|
||
//
|
||
|
||
HwDeviceExtension->AdapterDesc.ulMemConfVal = P90_MEM_CFG_3;
|
||
HwDeviceExtension->FrameLength = 0x200000;
|
||
|
||
//
|
||
// Initialize the P9000 to memory configuration 3 (2M), so frame buffer
|
||
// memory can be accessed.
|
||
//
|
||
|
||
P9_WR_REG(MEMCONF, P90_MEM_CFG_3);
|
||
|
||
//
|
||
// Write a series of test values to the frame buffer.
|
||
//
|
||
|
||
for (i = 0; i < 32; i++)
|
||
{
|
||
pulFrameBufAddr[i] = i;
|
||
}
|
||
|
||
//
|
||
// Read back the test values. If any errors occur, this is not a valid
|
||
// memory configuration.
|
||
//
|
||
|
||
for (i = 0; i < 32; i++)
|
||
{
|
||
if (pulFrameBufAddr[i] != i)
|
||
{
|
||
HwDeviceExtension->AdapterDesc.ulMemConfVal = P90_MEM_CFG_1;
|
||
HwDeviceExtension->FrameLength = 0x100000;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|