Hello,
I have tried to make a MGA driver for MGA Mystique and MGA G series, but I
can't finish it, because I run out of time. If there is someone, who want
to continue, I send you my files.
What does work:
-detection
-mode selections (640x480 on Mystique, <=800x600 G200, <= 1024x768 G400)
What does'n work:
-memory organization
-return to text mode
good luck
bye,
Bear
P.S.-Some comments will be in Slovak, so if someone want to continue, just
ask me, and I will translate it to you.
/* This library is free software; you can redistribute it and/or */
/* modify it without any restrictions. This library is distributed */
/* in the hope that it will be useful, but without any warranty. */
/*
* Matrox Driver - Michal Lindner
*/
#define DEBUG 1
#define MEMORY_SIZE 4 // size of card memory
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include "vga.h"
#include "libvga.h"
#include "driver.h"
#include "timing.h"
#include "vgaregs.h"
#include "interface.h"
#include "accel.h"
#include "vgapci.h"
#include "matrox_reg.h"
#define PCI_VENDOR_MATROX 0x102b
#define PCI_CHIP_MGA_MILLENIUM 0x519
#define PCI_CHIP_MGA1064 0x51a // mystique
#define PCI_CHIP_MGA_MILLENIUM_2 0x51b
#define PCI_CHIP_MGA_MILLENIUM_2_AGP 0x51f
#define PCI_CHIP_MGAG100_MM 0x1000
#define PCI_CHIP_MGAG100_AGP 0x1001
#define PCI_CHIP_MGAG200_PCI 0x520
#define PCI_CHIP_MGAG200_AGP 0x521
#define PCI_CHIP_MGAG400 0x525
#define MGAREG_SAVE(i) (VGA_TOTAL_REGS+i)
#define MGA_TOTAL_REGS (VGA_TOTAL_REGS + 100)
/*
* Read/write to the DAC via MMIO
*/
/*
* These were functions. Use macros instead to avoid the need to
* pass pMga to them.
*/
#define INREG8(addr) *(volatile unsigned char*)(MMIO_POINTER + (addr))
#define OUTREG8(addr,val) *(volatile unsigned char*)(MMIO_POINTER + (addr))=(val)
#define inMGAdreg(reg) INREG8(RAMDAC_OFFSET + (reg))
#define outMGAdreg(reg, val) OUTREG8(RAMDAC_OFFSET + (reg), val)
#define inMGAdac(reg) \
(outMGAdreg(MGA1064_INDEX, reg), inMGAdreg(MGA1064_DATA))
#define outMGAdac(reg, val) \
(outMGAdreg(MGA1064_INDEX, reg), outMGAdreg(MGA1064_DATA, val))
#define outMGAdacmsk(reg, mask, val) \
do { /* note: mask and reg may get evaluated twice */ \
unsigned char tmp = (mask) ? (inMGAdac(reg) & (mask)) : 0; \
outMGAdreg(MGA1064_INDEX, reg); \
outMGAdreg(MGA1064_DATA, tmp | (val)); \
} while (0)
#define DACREGSIZE 0x50
/* current hardware status */
typedef struct {
u_int32_t MXoptionReg;
unsigned char DACclk[6];
unsigned char DACreg[DACREGSIZE];
unsigned char MiscOutReg;
unsigned char DACpal[768];
unsigned char CRTC[25];
unsigned char CRTCEXT[6];
unsigned char _SEQ[5];
/* unused for MGA mode, but who knows... */
unsigned char GCTL[9];
/* unused for MGA mode, but who knows... */
unsigned char ATTR[21];
}matrox_hw_state;
typedef struct {
u_int32_t DEVID;
u_int32_t DEVCTRL;
u_int32_t CLASS;
u_int32_t HEADER;
u_int32_t MGABASE2;
u_int32_t MGABASE1;
u_int32_t MGABASE3;
u_int32_t reserved_1[4];
u_int32_t SUBSYSID_READ;
u_int32_t ROMBASE;
u_int32_t CAP_PTR;
u_int32_t reserved_2;
u_int32_t INTCRTL;
u_int32_t OPTION;
u_int32_t MGA_INDEX;
u_int32_t MGA_DATA;
u_int32_t SUBSYSID_WRITE;
u_int32_t OPTION2;
u_int32_t OPTION3;
u_int32_t reserved_3[33];
u_int32_t PM_IDENT;
u_int32_t PM_CSR;
u_int32_t reserved_4[3];
u_int32_t AGP_IDENT;
u_int32_t AGP_STS;
u_int32_t AGP_CMD;
u_int32_t reserved_5;
}matrox_pci_configuration_space;
static int matrox_init(int, int, int);
static void matrox_unlock(void);
static void matrox_lock(void);
static void matrox_soft_reset(void);
void __svgalib_skaccel_init(AccelSpecs * accelspecs, int bpp, int width_in_pixels);
static int matrox_chipset;
static int matrox_memory;
static int matrox_is_linear, matrox_linear_base, matrox_control_base,
matrox_ILOAD_base, matrox_chiptype;
static int matrox_hasSDRAM;
static CardSpecs *cardspecs;
//static struct pci_dev *matrox_pci_dev;
static void matrox_setpage(int page)
{
}
static int __svgalib_matrox_inlinearmode(void)
{
return matrox_is_linear;
}
/* Fill in chipset specific mode information */
static void matrox_getmodeinfo(int mode, vga_modeinfo *modeinfo)
{
if(modeinfo->colors==16)return;
modeinfo->maxpixels = matrox_memory*1024/modeinfo->bytesperpixel;
modeinfo->maxlogicalwidth = 4088;
modeinfo->startaddressrange = matrox_memory * 1024 - 1;
modeinfo->haveblit = 0;
modeinfo->flags &= ~HAVE_RWPAGE;
if (modeinfo->bytesperpixel >= 1) {
if(matrox_linear_base)modeinfo->flags |= CAPABLE_LINEAR;
if (__svgalib_matrox_inlinearmode())
modeinfo->flags |= IS_LINEAR;
}
}
/* Read and save chipset-specific registers */
static int matrox_saveregs(unsigned char regs[])
{
// int i;
matrox_unlock();
return MGA_TOTAL_REGS - VGA_TOTAL_REGS;
}
/* Set chipset-specific registers */
static void matrox_setregs(const unsigned char regs[], int mode)
{
// int i;
matrox_unlock();
}
/* Return nonzero if mode is available */
static int matrox_modeavailable(int mode)
{
struct info *info;
ModeTiming *modetiming;
ModeInfo *modeinfo;
modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
if ((mode < G640x480x256 ) || mode == G720x348x2)
return __svgalib_vga_driverspecs.modeavailable(mode);
info = &__svgalib_infotable[mode];
if (matrox_memory * 1024 < info->ydim * info->xbytes)
return 0;
modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
modetiming = malloc(sizeof(ModeTiming));
if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
free(modetiming);
free(modeinfo);
return 0;
}
free(modetiming);
free(modeinfo);
return SVGADRV;
}
/* The following values are in kHz */
#define MGA_MIN_VCO_FREQ 50000
#define MGA_MAX_VCO_FREQ 310000
static double MGAGCalcClock (long f_out, int *best_m, int *best_n, int *p, int *s )
{
int m, n;
double f_pll, f_vco;
double m_err, calc_f;
double ref_freq;
int feed_div_min, feed_div_max;
int in_div_min, in_div_max;
int post_div_max;
switch( matrox_chipset )
{
case PCI_CHIP_MGA1064:
ref_freq = 14318.18;
feed_div_min = 100;
feed_div_max = 127;
in_div_min = 1;
in_div_max = 31;
post_div_max = 7;
break;
case PCI_CHIP_MGAG400:
ref_freq = 27050.5;
feed_div_min = 7;
feed_div_max = 127;
in_div_min = 1;
in_div_max = 31;
post_div_max = 7;
break;
case PCI_CHIP_MGAG100_MM:
case PCI_CHIP_MGAG100_AGP:
case PCI_CHIP_MGAG200_AGP:
case PCI_CHIP_MGAG200_PCI:
default:
/*
if (pMga->Bios2.PinID && (pMga->Bios2.VidCtrl & 0x20))
ref_freq = 14318.18;
else
*/ ref_freq = 27050.5;
feed_div_min = 7;
feed_div_max = 127;
in_div_min = 1;
in_div_max = 6;
post_div_max = 7;
break;
}
/* Make sure that f_min <= f_out */
if ( f_out < ( MGA_MIN_VCO_FREQ / 8))
f_out = MGA_MIN_VCO_FREQ / 8;
/*
* f_pll = f_vco / (p+1)
* Choose p so that MGA_MIN_VCO_FREQ <= f_vco <= MGA_MAX_VCO_FREQ
* we don't have to bother checking for this maximum limit.
*/
f_vco = ( double ) f_out;
for ( *p = 0; *p <= post_div_max && f_vco < MGA_MIN_VCO_FREQ;
*p = *p * 2 + 1, f_vco *= 2.0);
/* Initial amount of error for frequency maximum */
m_err = f_out;
/* Search for the different values of ( m ) */
for ( m = in_div_min ; m <= in_div_max ; m++ )
{
/* see values of ( n ) which we can't use */
for ( n = feed_div_min; n <= feed_div_max; n++ )
{
calc_f = ref_freq * (n + 1) / (m + 1) ;
/*
* Pick the closest frequency.
*/
if ( abs(calc_f - f_vco) < m_err ) {
m_err = abs(calc_f - f_vco);
*best_m = m;
*best_n = n;
}
}
}
/* Now all the calculations can be completed */
f_vco = ref_freq * (*best_n + 1) / (*best_m + 1);
/* Adjustments for filtering pll feed back */
if ( (50000.0 <= f_vco)
&& (f_vco < 100000.0) )
*s = 0;
if ( (100000.0 <= f_vco)
&& (f_vco < 140000.0) )
*s = 1;
if ( (140000.0 <= f_vco)
&& (f_vco < 180000.0) )
*s = 2;
if ( (180000.0 <= f_vco) )
*s = 3;
f_pll = f_vco / ( *p + 1 );
#if 0
//#ifdef DEBUG
ErrorF( "f_out_requ =%ld f_pll_real=%.1f f_vco=%.1f n=0x%x m=0x%x p=0x%x
s=0x%x\n",
f_out, f_pll, f_vco, *best_n, *best_m, *p, *s );
#endif
return f_pll;
}
/*
* MGAGSetPCLK - Set the pixel (PCLK) clock.
MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out )
*/
static void
MGAGSetPCLK( matrox_hw_state *state, long f_out )
{
/*
MGAPtr pMga = MGAPTR(pScrn);
MGARegPtr pReg = &pMga->ModeReg;
*/
/* Pixel clock values */
int m, n, p, s;
/* The actual frequency output by the clock */
double f_pll;
/* Do the calculations for m, n, p and s */
f_pll = MGAGCalcClock( f_out, &m, &n, &p, &s );
/* Values for the pixel clock PLL registers */
state->DACreg[ MGA1064_PIX_PLLC_M ] = m & 0x1F;
state->DACreg[ MGA1064_PIX_PLLC_N ] = n & 0x7F;
state->DACreg[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | ((s & 0x03) << 3);
}
/*
* MGASoftReset -- reset drawing engine
*/
void matrox_soft_reset()
{
(unsigned long)MMIO_POINTER[ MGAREG_Reset ]=1;
usleep(200);
(unsigned long)MMIO_POINTER[ MGAREG_Reset ]=0;
(unsigned long)MMIO_POINTER[ MGAREG_MACCESS ]=1<<15;
usleep(10);
}
/* Local, called by matrox_setmode(). */
static void matrox_initializemode(unsigned char *moderegs,
ModeTiming * modetiming, ModeInfo * modeinfo, int
mode)
{
int i,hd,hs,he,ht,vd,vs,ve,vt,wd;
int maccess,mopmode;
int BppShift;
matrox_hw_state state;
/*
* initial values of the DAC registers
*/
const static unsigned char initDAC[] = {
/* 0x00: */ 0, 0, 0, 0, 0, 0, 0x00, 0,
/* 0x08: */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x10: */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x18: */ 0x00, 0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
/* 0x20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x28: */ 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0x40,
/* 0x30: */ 0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
/* 0x38: */ 0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
/* 0x40: */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0
};
__svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo);
for(i=0;i<sizeof(initDAC);i++)
state.DACreg[i] = initDAC[i];
state.MiscOutReg = INREG8(0x1fcc); // MISC READ
#if 1
switch(matrox_chipset)
{
case PCI_CHIP_MGA1064:
state.DACreg[ MGA1064_SYS_PLL_M ] = 0x04;
state.DACreg[ MGA1064_SYS_PLL_N ] = 0x44;
state.DACreg[ MGA1064_SYS_PLL_P ] = 0x18;
proc_pci_write_dword(VGAPCI_CS_OPTION,0x5F094F21);
proc_pci_write_dword(VGAPCI_CS_OPTION2,0x00000000);
break;
case PCI_CHIP_MGAG100_MM:
case PCI_CHIP_MGAG100_AGP:
state.DACreg[ MGAGDAC_XVREFCTRL ] = 0x03;
if(matrox_hasSDRAM) {
// if(pMga->OverclockMem) {
/* 220 Mhz */
// state.DACreg[ MGA1064_SYS_PLL_M ] = 0x06;
// state.DACreg[ MGA1064_SYS_PLL_N ] = 0x38;
// state.DACreg[ MGA1064_SYS_PLL_P ] = 0x18;
// } else {
/* 203 Mhz */
state.DACreg[ MGA1064_SYS_PLL_M ] = 0x01;
state.DACreg[ MGA1064_SYS_PLL_N ] = 0x0E;
state.DACreg[ MGA1064_SYS_PLL_P ] = 0x18;
// }
proc_pci_write_dword(VGAPCI_CS_OPTION,0x404991a9);
// pReg->Option = 0x404991a9;
} else {
// if(pMga->OverclockMem) {
/* 143 Mhz */
// state.DACreg[ MGA1064_SYS_PLL_M ] = 0x06;
// state.DACreg[ MGA1064_SYS_PLL_N ] = 0x24;
// state.DACreg[ MGA1064_SYS_PLL_P ] = 0x10;
// } else {
/* 124 Mhz */
state.DACreg[ MGA1064_SYS_PLL_M ] = 0x04;
state.DACreg[ MGA1064_SYS_PLL_N ] = 0x16;
state.DACreg[ MGA1064_SYS_PLL_P ] = 0x08;
// }
proc_pci_write_dword(VGAPCI_CS_OPTION,0x4049d121);
}
proc_pci_write_dword(VGAPCI_CS_OPTION2,0x0000007);
break;
case PCI_CHIP_MGAG400:
/* we don't have a good overclock value yet */
/* 165 Mhz */
state.DACreg[ MGA1064_SYS_PLL_M ] = 0x09;
state.DACreg[ MGA1064_SYS_PLL_N ] = 0x3C;
state.DACreg[ MGA1064_SYS_PLL_P ] = 0x10;
proc_pci_write_dword(VGAPCI_CS_OPTION2,0x01003000);
proc_pci_write_dword(VGAPCI_CS_OPTION3,0x0190a419);
if(matrox_hasSDRAM)
proc_pci_write_dword(VGAPCI_CS_OPTION,0x50040120);
else
proc_pci_write_dword(VGAPCI_CS_OPTION,0x50044120);
break;
case PCI_CHIP_MGAG200_AGP:
case PCI_CHIP_MGAG200_PCI:
default:
state.MiscOutReg = 0xEF;
// if(pMga->OverclockMem) {
/* 143 Mhz */
// state.DACreg[ MGA1064_SYS_PLL_M ] = 0x06;
// state.DACreg[ MGA1064_SYS_PLL_N ] = 0x24;
// state.DACreg[ MGA1064_SYS_PLL_P ] = 0x10;
// } else {
/* 124 Mhz */
state.DACreg[ MGA1064_SYS_PLL_M ] = 0x04;
state.DACreg[ MGA1064_SYS_PLL_N ] = 0x2D;
state.DACreg[ MGA1064_SYS_PLL_P ] = 0x19;
// }
proc_pci_write_dword(VGAPCI_CS_OPTION2,0x00008000);
if(matrox_hasSDRAM)
proc_pci_write_dword(VGAPCI_CS_OPTION,0x40499121);
else
proc_pci_write_dword(VGAPCI_CS_OPTION,0x4049cd21);
break;
}
if(modeinfo->height>400){
state.MiscOutReg &= ~0x40;
}else{
state.MiscOutReg &= ~0x80;
}
// if(pMga->UsePCIRetry)
// pReg->Option &= ~0x20000000;
// else
// pReg->Option |= 0x20000000;
#endif
mopmode=MGAOPM_DMA_BLIT;
switch(modeinfo->bitsPerPixel)
{
case 8:
BppShift=0;
/* set pwidth bits 0,1 to 00 - 8 bits per pixel*/
maccess=0x00000000;
state.DACreg[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_8bits;
break;
case 15:
BppShift=1;
/* set pwidth bits 0,1 to 01 - 16 bits per pixel*/
maccess=0xC0000001;
state.DACreg[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_15bits;
break;
case 16:
BppShift=1;
/* set pwidth bits 0,1 to 01 - 16 bits per pixel*/
/* dit555 mode - bit 31 - 0 - 5:6:5 dithering mode */
maccess=0x40000001;
state.DACreg[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_16bits;
break;
case 24:
BppShift=0;
/* set pwidth bits 0,1 to 11 - 24 bits per pixel*/
maccess=0x00000003;
state.DACreg[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_24bits;
break;
case 32:
BppShift=2;
/* set pwidth bits 0,1 to 01 - 16 bits per pixel*/
maccess=0x00000002;
// if(pMga->Overlay8Plus24) { // alpha canal
// state.DACreg[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_32bits;
// state.DACreg[ MGA1064_COL_KEY_MSK_LSB ] = 0xFF;
// state.DACreg[ MGA1064_COL_KEY_LSB ] = pMga->colorKey;
// } else
state.DACreg[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_32_24bits;
break;
default:
BppShift=0;
maccess=0x00000000;
mopmode=0;
// FatalError("MGA: unsupported depth\n");
}
matrox_soft_reset();
(unsigned long)MMIO_POINTER[ MGAREG_PITCH ] = modeinfo->lineWidth;
(unsigned long)MMIO_POINTER[ MGAREG_YDSTORG ] = 0;
// if (ACCESS_FBINFO(capable.plnwt))
(unsigned long)MMIO_POINTER[ MGAREG_PLNWT ] = 0xFFFFFFFF;
// MMIO_POINTER[ MGAREG_CXBNDRY ] = 0xFFFF0000; // !!!! overit!
(unsigned long)MMIO_POINTER[ MGAREG_CXBNDRY ] = 0x0FFF0000;
(unsigned long)MMIO_POINTER[ MGAREG_OPMODE ]=mopmode;
(unsigned long)MMIO_POINTER[ MGAREG_YTOP ] = 0x007FFFFF;
(unsigned long)MMIO_POINTER[ MGAREG_YBOT ] = 0x00000000;
(unsigned long)MMIO_POINTER[ MGAREG_MACCESS ]=maccess;
/* set zwidth bits 0,1 to 00 - 16bit Z buffer - no stencil bufer */
// MMIO_POINTER[ MGAREG_MACCESS ]&=0xFFFFFFF3;
/* disable dithering */
// MMIO_POINTER[ MGAREG_MACCESS ]|=1<<30;
/* reset memory */
// MMIO_POINTER[ MGAREG_MACCESS ]|=1<<15;
// matrox_soft_reset();
/*
* Here all of the MGA registers get filled in.
*/
hd = (modetiming->CrtcHDisplay >> 3) - 1;
hs = (modetiming->CrtcHSyncStart>> 3) - 1;
he = (modetiming->CrtcHSyncEnd >> 3) - 1;
ht = (modetiming->CrtcHTotal >> 3) - 1;
vd = modetiming->CrtcVDisplay - 1;
vs = modetiming->CrtcVSyncStart - 1;
ve = modetiming->CrtcVSyncEnd - 1;
vt = modetiming->CrtcVTotal - 2;
/* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange
* vertical stripes
*/
if((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04)
ht++;
if(modeinfo->bitsPerPixel==24)
wd = (modeinfo->lineWidth * 3) >> BppShift;
else
wd = modeinfo->lineWidth >> BppShift;
state.CRTCEXT[0] = 0;
state.CRTCEXT[5] = 0;
if (modetiming->flags & INTERLACED)
{
state.CRTCEXT[0] = 0x80;
state.CRTCEXT[5] = (hs + he - ht) >> 1;
wd <<= 1;
vt &= 0xFFFE;
}
state.CRTCEXT[0] |= (wd & 0x300) >> 4;
state.CRTCEXT[1] = (((ht - 4) & 0x100) >> 8) |
((hd & 0x100) >> 7) |
((hs & 0x100) >> 6) |
(ht & 0x40);
state.CRTCEXT[2] = ((vt & 0xc00) >> 10) |
((vd & 0x400) >> 8) |
((vd & 0xc00) >> 7) |
((vs & 0xc00) >> 5);
if(modeinfo->bitsPerPixel==24)
state.CRTCEXT[3] = (((1 << BppShift)*3 ) - 1) | 0x80;
else
state.CRTCEXT[3] = ((1 << BppShift) - 1) | 0x80;
#if 0
// !!!! - nastavit CRTCEXT[3] na 0x80 !
/* Set viddelay (CRTCEXT3 Bits 3-4). */
pReg->ExtVga[3] |= (pScrn->videoRam == 8192 ? 0x10
: pScrn->videoRam == 2048 ? 0x08 : 0x00);
#endif
// state.CRTCEXT[3] = 0x80;
state.CRTCEXT[4] = 0;
for(i=0;i<sizeof(state.CRTC);i++)
state.CRTC[i]=0;
state.CRTC[0] = ht - 4;
state.CRTC[1] = hd;
state.CRTC[2] = hd;
state.CRTC[3] = (ht & 0x1F) | 0x80;
state.CRTC[4] = hs;
state.CRTC[5] = ((ht & 0x20) << 2) | (he & 0x1F);
state.CRTC[6] = vt & 0xFF;
state.CRTC[7] = ((vt & 0x100) >> 8 ) |
((vd & 0x100) >> 7 ) |
((vs & 0x100) >> 6 ) |
((vd & 0x100) >> 5 ) |
0x10 |
((vt & 0x200) >> 4 ) |
((vd & 0x200) >> 3 ) |
((vs & 0x200) >> 2 );
state.CRTC[9] = ((vd & 0x200) >> 4) | 0x40;
state.CRTC[16] = vs & 0xFF;
state.CRTC[13] = (modeinfo->lineWidth*modeinfo->bitsPerPixel)/128;
state.CRTC[17] = (ve & 0x0F) | 0x20;
state.CRTC[18] = vd & 0xFF;
state.CRTC[19] = wd & 0xFF;
state.CRTC[21] = vd & 0xFF;
state.CRTC[22] = (vt + 1) & 0xFF;
if (modetiming->flags & DOUBLESCAN)
state.CRTC[9] |= 0x80;
for(i=0;i<sizeof(state.CRTC);i++){
MMIO_POINTER[ MGAREG_CRTC_INDEX ]=i;
MMIO_POINTER[ MGAREG_CRTC_DATA ]=state.CRTC[i];
}
for(i=0;i<sizeof(state.CRTCEXT);i++)
if(state.CRTCEXT[i]){
MMIO_POINTER[ MGAREG_CRTCEXT_INDEX ]=i;
MMIO_POINTER[ MGAREG_CRTCEXT_DATA ]=state.CRTCEXT[i];
}
#if 0
state.DacReg[ MGA1064_CURSOR_BASE_ADR_LOW ] = pMga->FbCursorOffset >> 10;
state.DacReg[ MGA1064_CURSOR_BASE_ADR_HI ] = pMga->FbCursorOffset >> 18;
#endif
#if 0
if (pMga->SyncOnGreen) {
pReg->DacRegs[ MGA1064_GEN_CTL ] &= ~0x20;
pReg->ExtVga[3] |= 0x40;
}
#endif
/* select external clock */
state.MiscOutReg |= 0x0C;
MGAGSetPCLK(&state, modetiming->pixelClock );
/* This disables the VGA memory aperture */
state.MiscOutReg &= ~0x02;
/* restore DAC registers
* according to the docs we shouldn't write to reserved regs*/
for (i = 0; i < DACREGSIZE; i++) {
if( (i <= 0x03) ||
(i == 0x07) ||
(i == 0x0b) ||
(i == 0x0f) ||
((i >= 0x13) && (i <= 0x17)) ||
(i == 0x1b) ||
(i == 0x1c) ||
((i >= 0x1f) && (i <= 0x29)) ||
((i >= 0x30) && (i <= 0x37)) )
continue;
outMGAdac(i, state.DACreg[i]);
}
OUTREG8(0x1fcc,state.MiscOutReg); // MISC WRITE
return ;
}
static int matrox_setmode(int mode, int prv_mode)
{
unsigned char *moderegs;
ModeTiming *modetiming;
ModeInfo *modeinfo;
int i;
if ((mode < G640x480x256)||(mode==G720x348x2)) {
return __svgalib_vga_driverspecs.setmode(mode, prv_mode);
}
if (!matrox_modeavailable(mode))
return 1;
modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
modetiming = malloc(sizeof(ModeTiming));
if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
free(modetiming);
free(modeinfo);
return 1;
}
moderegs = malloc(MGA_TOTAL_REGS);
matrox_initializemode(moderegs, modetiming, modeinfo, mode);
free(modetiming);
__svgalib_setregs(moderegs); /* Set standard regs. */
matrox_setregs(moderegs, mode); /* Set extended regs. */
free(moderegs);
__svgalib_InitializeAcceleratorInterface(modeinfo);
free(modeinfo);
// memset(LINEAR_MEM_POINTER,0x3f,__svgalib_linear_mem_size);
for(i=0;i<__svgalib_linear_mem_size;i++)
LINEAR_MEM_POINTER[i]=(i&0xc0)+((i&0x3f)*((i>>8)&0xfc)>>8);
// LINEAR_MEM_POINTER[i]=(i%640)&0xff;
return 0;
}
/* Unlock chipset-specific registers */
static void matrox_unlock(void)
{
int vgaIOBase, temp;
vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
outb(vgaIOBase + 4, 0x11);
temp = inb(vgaIOBase + 5);
outb(vgaIOBase + 5, temp & 0x7F);
}
static void matrox_lock(void)
{
int vgaIOBase, temp;
vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
outb(vgaIOBase + 4, 0x11);
temp = inb(vgaIOBase + 5);
outb(vgaIOBase + 5, temp & 0x7F);
}
/* Indentify chipset, initialize and return non-zero if detected */
static int matrox_test(void)
{
int _ioperm=0,found;
matrox_pci_configuration_space buf;
#ifdef DEBUG
printf("svgalib: probing matrox driver\n");
#endif
if (getenv("IOPERM") == NULL) {
_ioperm=1;
if (iopl(3) < 0) {
printf("svgalib: cannot get I/O permissions\n");
exit(1);
}
}
found=__svgalib_pci_find_vendor_vga(PCI_VENDOR_MATROX,(long*)&buf,0);
if (_ioperm) iopl(0);
if(found){// I don't know why, but in vgapci.c 0 in on success
#ifdef DEBUG
printf("svgalib: fatal error (no matrox card found)\n");
#endif
return(0);
}
matrox_chipset=(buf.DEVID>>16)&0xffff;
switch(matrox_chipset){
case PCI_CHIP_MGA_MILLENIUM:
printf("svgalib: Matrox millenium card found\n");
break;
case PCI_CHIP_MGA1064:
printf("svgalib: Matrox mystique card found\n");
break;
case PCI_CHIP_MGA_MILLENIUM_2:
printf("svgalib: Matrox MIL2PCI card found\n");
break;
case PCI_CHIP_MGA_MILLENIUM_2_AGP:
printf("svgalib: Matrox MIL2AGP card found\n");
break;
case PCI_CHIP_MGAG100_MM:
printf("svgalib: Matrox G100_MM card found\n");
break;
case PCI_CHIP_MGAG100_AGP:
printf("svgalib: Matrox G100AGP card found\n");
break;
case PCI_CHIP_MGAG200_PCI:
printf("svgalib: Matrox G200PCI card found\n");
break;
case PCI_CHIP_MGAG200_AGP:
printf("svgalib: Matrox G200AGP card found\n");
break;
case PCI_CHIP_MGAG400:
printf("svgalib: Matrox G400AGP card found\n");
break;
default:
printf("svgalib: unsupported Matrox card\n");
return 0;
}
matrox_hasSDRAM = buf.OPTION&0x4000;
matrox_init(0,0,(buf.DEVID>>16)&0xffff);
return 1;
}
/* Set display start address (not for 16 color modes) */
/* Cirrus supports any address in video memory (up to 2Mb) */
static void matrox_setdisplaystart(int address)
{
address=address >> 2;
outw(CRT_IC, (address & 0x00FF00) | 0x0C);
outw(CRT_IC, ((address & 0x00FF) << 8) | 0x0D);
}
/* Set logical scanline length (usually multiple of 8) */
/* Cirrus supports multiples of 8, up to 4088 */
static void matrox_setlogicalwidth(int width)
{
int offset = width >> 3;
__svgalib_outCR(0x13,offset&0xff);
}
static int matrox_linear(int op, int param)
{
if (op==LINEAR_ENABLE){matrox_is_linear=1; return 0;};
if (op==LINEAR_DISABLE){matrox_is_linear=0; return 0;};
if (op==LINEAR_QUERY_BASE) return matrox_linear_base;
if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0;
/* No granularity or range. */
else return -1; /* Unknown function. */
}
static int matrox_match_programmable_clock(int clock)
{
return clock ;
}
static int matrox_map_clock(int bpp, int clock)
{
return clock ;
}
static int matrox_map_horizontal_crtc(int bpp, int pixelclock, int htiming)
{
return htiming;
}
/* Function table (exported) */
DriverSpecs __svgalib_matrox_driverspecs =
{
matrox_saveregs, // ulozenie obsahu registrov karty - pri prepinani n
ainu konzolu a pod
matrox_setregs, // obnovenie stavu registrov "zo zalohy"
matrox_unlock, // odomknutie karty - malo by fungovat
matrox_lock, // zamknutie karty - malo by fungovat
matrox_test, // detakcia karty - funguje
matrox_init, // inicializacia karty - mozno funguje
matrox_setpage, // prepnutie stranky - zatial nie je, ale malo by to
byt jednoduche
NULL,
NULL,
matrox_setmode, // nastavenie grafickeho rezimu
matrox_modeavailable, // zistenie, ci je tento graficky mod na tejto karte
pristupny
matrox_setdisplaystart,
matrox_setlogicalwidth,
matrox_getmodeinfo, // ??? - mozno funguje
0, /* old blit funcs */
0,
0,
0,
0,
0, /* ext_set */
0, /* accel */
matrox_linear,
0, /* accelspecs, filled in during init. */
NULL, /* Emulation */
};
/* Initialize chipset (called after detection) */
static int matrox_init(int force, int par1, int par2)
{
matrox_pci_configuration_space buf;
int found=0;
int _ioperm=0;
matrox_unlock();
if (force) {
matrox_memory = par1;
matrox_chiptype = par2;
} else {
};
matrox_memory=MEMORY_SIZE*1024; /* hard limit - detection must be done */
matrox_is_linear=1; // let's be linear
if (getenv("IOPERM") == NULL) {
_ioperm=1;
if (iopl(3) < 0) {
printf("svgalib: cannot get I/O permissions\n");
exit(1);
}
}
found=__svgalib_pci_find_vendor_vga(PCI_VENDOR_MATROX,(long*)&buf,0);
//
matrox_pci_dev=pci_find_device(PCI_VENDOR_MATROX,(buf.DEVID>>16)&0xffff,pci_devices);
if (_ioperm) iopl(0);
matrox_linear_base=0;
if (!found){
matrox_linear_base=buf.MGABASE2&0xffffff00;
matrox_control_base=buf.MGABASE1&0xffffff00;
matrox_ILOAD_base=buf.MGABASE3&0xffffff00;
if(__svgalib_mem_fd<0){
printf("svgalib: __svgalib_mem_fd is not opened\n");
exit(1);
}
};
if (__svgalib_driver_report) {
printf("Using MGA driver, %iKB. ",matrox_memory);
};
cardspecs = malloc(sizeof(CardSpecs));
cardspecs->videoMemory = matrox_memory;
cardspecs->maxPixelClock4bpp = 75000;
cardspecs->maxPixelClock8bpp = 160000;
cardspecs->maxPixelClock16bpp = 160000;
cardspecs->maxPixelClock24bpp = 160000;
cardspecs->maxPixelClock32bpp = 160000;
cardspecs->flags = INTERLACE_DIVIDE_VERT | CLOCK_PROGRAMMABLE;
cardspecs->maxHorizontalCrtc = 2040;
cardspecs->maxPixelClock4bpp = 0;
cardspecs->nClocks =0;
cardspecs->mapClock = matrox_map_clock;
cardspecs->mapHorizontalCrtc = matrox_map_horizontal_crtc;
cardspecs->matchProgrammableClock=matrox_match_programmable_clock;
__svgalib_driverspecs = &__svgalib_matrox_driverspecs;
__svgalib_banked_mem_base=0xa0000;
__svgalib_banked_mem_size=0x10000;
__svgalib_linear_mem_base=matrox_linear_base;
__svgalib_linear_mem_size=matrox_memory*1024;
__svgalib_mmio_base=buf.MGABASE1;
__svgalib_mmio_size=0x4000;
return 0;
}
/*
Bear's motes:
valid mode check - xfree 3.9.15 mga_driver.c
lace = 1 + ((mode->Flags&V_INTERLACE)!=0)
HDisplay <= 2048 - rozlisenie x
HSyncStart <= 4096 - start sync impulzu (HDisplay < HSyncStart)
HSyncEnd <= 4096 - koniec sync impulzu (HsyncStart < HSyncEnd < HTotal)
HTotal <= 4096 - sirka
VDisplay <= 2048*lace - detto
VSyncStart <= 4096*lace
HSyncEnd <= 4096*lace
HTotal <= 4096*lace
*/
/* $XConsortium: mgareg.h /main/2 1996/10/25 10:33:21 kaleb $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h,v 1.9 1999/06/06
08:48:51 dawes Exp $ */
/*
* MGA Millennium (MGA2064W) functions
* MGA Mystique (MGA1064SG) functions
*
* Copyright 1996 The XFree86 Project, Inc.
*
* Authors
* Dirk Hohndel
* [EMAIL PROTECTED]
* David Dawes
* [EMAIL PROTECTED]
* Contributors:
* Guy DESBIEF, Aix-en-provence, France
* [EMAIL PROTECTED]
* MGA1064SG Mystique register file
*/
#ifndef _MGA_REG_H_
#define _MGA_REG_H_
#define MGAREG_DWGCTL 0x1c00
#define MGAREG_MACCESS 0x1c04
/* the following is a mystique only register */
#define MGAREG_MCTLWTST 0x1c08
#define MGAREG_ZORG 0x1c0c
#define MGAREG_PAT0 0x1c10
#define MGAREG_PAT1 0x1c14
#define MGAREG_PLNWT 0x1c1c
#define MGAREG_BCOL 0x1c20
#define MGAREG_FCOL 0x1c24
#define MGAREG_SRC0 0x1c30
#define MGAREG_SRC1 0x1c34
#define MGAREG_SRC2 0x1c38
#define MGAREG_SRC3 0x1c3c
#define MGAREG_XYSTRT 0x1c40
#define MGAREG_XYEND 0x1c44
#define MGAREG_SHIFT 0x1c50
/* the following is a mystique only register */
#define MGAREG_DMAPAD 0x1c54
#define MGAREG_SGN 0x1c58
#define MGAREG_LEN 0x1c5c
#define MGAREG_AR0 0x1c60
#define MGAREG_AR1 0x1c64
#define MGAREG_AR2 0x1c68
#define MGAREG_AR3 0x1c6c
#define MGAREG_AR4 0x1c70
#define MGAREG_AR5 0x1c74
#define MGAREG_AR6 0x1c78
#define MGAREG_CXBNDRY 0x1c80
#define MGAREG_FXBNDRY 0x1c84
#define MGAREG_YDSTLEN 0x1c88
#define MGAREG_PITCH 0x1c8c
#define MGAREG_YDST 0x1c90
#define MGAREG_YDSTORG 0x1c94
#define MGAREG_YTOP 0x1c98
#define MGAREG_YBOT 0x1c9c
#define MGAREG_CXLEFT 0x1ca0
#define MGAREG_CXRIGHT 0x1ca4
#define MGAREG_FXLEFT 0x1ca8
#define MGAREG_FXRIGHT 0x1cac
#define MGAREG_XDST 0x1cb0
#define MGAREG_DR0 0x1cc0
#define MGAREG_DR1 0x1cc4
#define MGAREG_DR2 0x1cc8
#define MGAREG_DR3 0x1ccc
#define MGAREG_DR4 0x1cd0
#define MGAREG_DR5 0x1cd4
#define MGAREG_DR6 0x1cd8
#define MGAREG_DR7 0x1cdc
#define MGAREG_DR8 0x1ce0
#define MGAREG_DR9 0x1ce4
#define MGAREG_DR10 0x1ce8
#define MGAREG_DR11 0x1cec
#define MGAREG_DR12 0x1cf0
#define MGAREG_DR13 0x1cf4
#define MGAREG_DR14 0x1cf8
#define MGAREG_DR15 0x1cfc
#define MGAREG_SRCORG 0x2cb4
#define MGAREG_DSTORG 0x2cb8
/* add or or this to one of the previous "power registers" to start
the drawing engine */
#define MGAREG_EXEC 0x0100
#define MGAREG_FIFOSTATUS 0x1e10
#define MGAREG_Status 0x1e14
#define MGAREG_ICLEAR 0x1e18
#define MGAREG_IEN 0x1e1c
#define MGAREG_VCOUNT 0x1e20
#define MGAREG_Reset 0x1e40
#define MGAREG_OPMODE 0x1e54
/* OPMODE register additives */
#define MGAOPM_DMA_GENERAL (0x00 << 2)
#define MGAOPM_DMA_BLIT (0x01 << 2)
#define MGAOPM_DMA_VECTOR (0x10 << 2)
/* DWGCTL register additives */
/* Lines */
#define MGADWG_LINE_OPEN 0x00
#define MGADWG_AUTOLINE_OPEN 0x01
#define MGADWG_LINE_CLOSE 0x02
#define MGADWG_AUTOLINE_CLOSE 0x03
/* Trapezoids */
#define MGADWG_TRAP 0x04
#define MGADWG_TEXTURE_TRAP 0x05
/* BitBlts */
#define MGADWG_BITBLT 0x08
#define MGADWG_FBITBLT 0x0c
#define MGADWG_ILOAD 0x09
#define MGADWG_ILOAD_SCALE 0x0d
#define MGADWG_ILOAD_FILTER 0x0f
#define MGADWG_IDUMP 0x0a
/* atype access to WRAM */
#define MGADWG_RPL ( 0x00 << 4 )
#define MGADWG_RSTR ( 0x01 << 4 )
#define MGADWG_ZI ( 0x03 << 4 )
#define MGADWG_BLK ( 0x04 << 4 )
#define MGADWG_I ( 0x07 << 4 )
/* specifies whether bit blits are linear or xy */
#define MGADWG_LINEAR ( 0x01 << 7 )
/* z drawing mode. use MGADWG_NOZCMP for always */
#define MGADWG_NOZCMP ( 0x00 << 8 )
#define MGADWG_ZE ( 0x02 << 8 )
#define MGADWG_ZNE ( 0x03 << 8 )
#define MGADWG_ZLT ( 0x04 << 8 )
#define MGADWG_ZLTE ( 0x05 << 8 )
#define MGADWG_GT ( 0x06 << 8 )
#define MGADWG_GTE ( 0x07 << 8 )
/* use this to force colour expansion circuitry to do its stuff */
#define MGADWG_SOLID ( 0x01 << 11 )
/* ar register at zero */
#define MGADWG_ARZERO ( 0x01 << 12 )
#define MGADWG_SGNZERO ( 0x01 << 13 )
#define MGADWG_SHIFTZERO ( 0x01 << 14 )
/* See table on 4-43 for bop ALU operations */
/* See table on 4-44 for translucidity masks */
#define MGADWG_BMONOLEF ( 0x00 << 25 )
#define MGADWG_BMONOWF ( 0x04 << 25 )
#define MGADWG_BPLAN ( 0x01 << 25 )
/* note that if bfcol is specified and you're doing a bitblt, it causes
a fbitblt to be performed, so check that you obey the fbitblt rules */
#define MGADWG_BFCOL ( 0x02 << 25 )
#define MGADWG_BUYUV ( 0x0e << 25 )
#define MGADWG_BU32BGR ( 0x03 << 25 )
#define MGADWG_BU32RGB ( 0x07 << 25 )
#define MGADWG_BU24BGR ( 0x0b << 25 )
#define MGADWG_BU24RGB ( 0x0f << 25 )
#define MGADWG_PATTERN ( 0x01 << 29 )
#define MGADWG_TRANSC ( 0x01 << 30 )
#define MGAREG_MISC_WRITE 0x3c2
#define MGAREG_MISC_READ 0x3cc
#define MGAREG_MISC_IOADSEL (0x1 << 0)
#define MGAREG_MISC_RAMMAPEN (0x1 << 1)
#define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2)
#define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2)
#define MGAREG_MISC_CLK_SEL_MGA_PIX (0x2 << 2)
#define MGAREG_MISC_CLK_SEL_MGA_MSK (0x3 << 2)
#define MGAREG_MISC_VIDEO_DIS (0x1 << 4)
#define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5)
/* MMIO VGA registers */
#define MGAREG_CRTC_INDEX 0x1fd4
#define MGAREG_CRTC_DATA 0x1fd5
#define MGAREG_CRTCEXT_INDEX 0x1fde
#define MGAREG_CRTCEXT_DATA 0x1fdf
/* MGA bits for registers PCI_OPTION_REG */
#define MGA1064_OPT_SYS_CLK_PCI ( 0x00 << 0 )
#define MGA1064_OPT_SYS_CLK_PLL ( 0x01 << 0 )
#define MGA1064_OPT_SYS_CLK_EXT ( 0x02 << 0 )
#define MGA1064_OPT_SYS_CLK_MSK ( 0x03 << 0 )
#define MGA1064_OPT_SYS_CLK_DIS ( 0x01 << 2 )
#define MGA1064_OPT_G_CLK_DIV_1 ( 0x01 << 3 )
#define MGA1064_OPT_M_CLK_DIV_1 ( 0x01 << 4 )
#define MGA1064_OPT_SYS_PLL_PDN ( 0x01 << 5 )
#define MGA1064_OPT_VGA_ION ( 0x01 << 8 )
/* MGA registers in PCI config space */
#define PCI_MGA_INDEX 0x44
#define PCI_MGA_DATA 0x48
#define PCI_MGA_OPTION2 0x50
#define PCI_MGA_OPTION3 0x54
#define RAMDAC_OFFSET 0x3c00
/* TVP3026 direct registers */
#define TVP3026_INDEX 0x00
#define TVP3026_WADR_PAL 0x00
#define TVP3026_COL_PAL 0x01
#define TVP3026_PIX_RD_MSK 0x02
#define TVP3026_RADR_PAL 0x03
#define TVP3026_CUR_COL_ADDR 0x04
#define TVP3026_CUR_COL_DATA 0x05
#define TVP3026_DATA 0x0a
#define TVP3026_CUR_RAM 0x0b
#define TVP3026_CUR_XLOW 0x0c
#define TVP3026_CUR_XHI 0x0d
#define TVP3026_CUR_YLOW 0x0e
#define TVP3026_CUR_YHI 0x0f
/* TVP3026 indirect registers */
#define TVP3026_SILICON_REV 0x01
#define TVP3026_CURSOR_CTL 0x06
#define TVP3026_LATCH_CTL 0x0f
#define TVP3026_TRUE_COLOR_CTL 0x18
#define TVP3026_MUX_CTL 0x19
#define TVP3026_CLK_SEL 0x1a
#define TVP3026_PAL_PAGE 0x1c
#define TVP3026_GEN_CTL 0x1d
#define TVP3026_MISC_CTL 0x1e
#define TVP3026_GEN_IO_CTL 0x2a
#define TVP3026_GEN_IO_DATA 0x2b
#define TVP3026_PLL_ADDR 0x2c
#define TVP3026_PIX_CLK_DATA 0x2d
#define TVP3026_MEM_CLK_DATA 0x2e
#define TVP3026_LOAD_CLK_DATA 0x2f
#define TVP3026_KEY_RED_LOW 0x32
#define TVP3026_KEY_RED_HI 0x33
#define TVP3026_KEY_GREEN_LOW 0x34
#define TVP3026_KEY_GREEN_HI 0x35
#define TVP3026_KEY_BLUE_LOW 0x36
#define TVP3026_KEY_BLUE_HI 0x37
#define TVP3026_KEY_CTL 0x38
#define TVP3026_MCLK_CTL 0x39
#define TVP3026_SENSE_TEST 0x3a
#define TVP3026_TEST_DATA 0x3b
#define TVP3026_CRC_LSB 0x3c
#define TVP3026_CRC_MSB 0x3d
#define TVP3026_CRC_CTL 0x3e
#define TVP3026_ID 0x3f
#define TVP3026_RESET 0xff
/* MGA1064 DAC Register file */
/* MGA1064 direct registers */
#define MGA1064_INDEX 0x00
#define MGA1064_WADR_PAL 0x00
#define MGA1064_COL_PAL 0x01
#define MGA1064_PIX_RD_MSK 0x02
#define MGA1064_RADR_PAL 0x03
#define MGA1064_DATA 0x0a
#define MGA1064_CUR_XLOW 0x0c
#define MGA1064_CUR_XHI 0x0d
#define MGA1064_CUR_YLOW 0x0e
#define MGA1064_CUR_YHI 0x0f
/* MGA1064 indirect registers */
#define MGA1064_CURSOR_BASE_ADR_LOW 0x04
#define MGA1064_CURSOR_BASE_ADR_HI 0x05
#define MGA1064_CURSOR_CTL 0x06
#define MGA1064_CURSOR_COL0_RED 0x08
#define MGA1064_CURSOR_COL0_GREEN 0x09
#define MGA1064_CURSOR_COL0_BLUE 0x0a
#define MGA1064_CURSOR_COL1_RED 0x0c
#define MGA1064_CURSOR_COL1_GREEN 0x0d
#define MGA1064_CURSOR_COL1_BLUE 0x0e
#define MGA1064_CURSOR_COL2_RED 0x010
#define MGA1064_CURSOR_COL2_GREEN 0x011
#define MGA1064_CURSOR_COL2_BLUE 0x012
#define MGA1064_VREF_CTL 0x018
#define MGA1064_MUL_CTL 0x19
#define MGA1064_MUL_CTL_8bits 0x0
#define MGA1064_MUL_CTL_15bits 0x01
#define MGA1064_MUL_CTL_16bits 0x02
#define MGA1064_MUL_CTL_24bits 0x03
#define MGA1064_MUL_CTL_32bits 0x04
#define MGA1064_MUL_CTL_2G8V16bits 0x05
#define MGA1064_MUL_CTL_G16V16bits 0x06
#define MGA1064_MUL_CTL_32_24bits 0x07
#define MGAGDAC_XVREFCTRL 0x18
#define MGA1064_PIX_CLK_CTL 0x1a
#define MGA1064_PIX_CLK_CTL_CLK_DIS ( 0x01 << 2 )
#define MGA1064_PIX_CLK_CTL_CLK_POW_DOWN ( 0x01 << 3 )
#define MGA1064_PIX_CLK_CTL_SEL_PCI ( 0x00 << 0 )
#define MGA1064_PIX_CLK_CTL_SEL_PLL ( 0x01 << 0 )
#define MGA1064_PIX_CLK_CTL_SEL_EXT ( 0x02 << 0 )
#define MGA1064_PIX_CLK_CTL_SEL_MSK ( 0x03 << 0 )
#define MGA1064_GEN_CTL 0x1d
#define MGA1064_MISC_CTL 0x1e
#define MGA1064_MISC_CTL_DAC_POW_DN ( 0x01 << 0 )
#define MGA1064_MISC_CTL_VGA ( 0x01 << 1 )
#define MGA1064_MISC_CTL_DIS_CON ( 0x03 << 1 )
#define MGA1064_MISC_CTL_MAFC ( 0x02 << 1 )
#define MGA1064_MISC_CTL_VGA8 ( 0x01 << 3 )
#define MGA1064_MISC_CTL_DAC_RAM_CS ( 0x01 << 4 )
#define MGA1064_GEN_IO_CTL 0x2a
#define MGA1064_GEN_IO_DATA 0x2b
#define MGA1064_SYS_PLL_M 0x2c
#define MGA1064_SYS_PLL_N 0x2d
#define MGA1064_SYS_PLL_P 0x2e
#define MGA1064_SYS_PLL_STAT 0x2f
#define MGA1064_ZOOM_CTL 0x38
#define MGA1064_SENSE_TST 0x3a
#define MGA1064_CRC_LSB 0x3c
#define MGA1064_CRC_MSB 0x3d
#define MGA1064_CRC_CTL 0x3e
#define MGA1064_COL_KEY_MSK_LSB 0x40
#define MGA1064_COL_KEY_MSK_MSB 0x41
#define MGA1064_COL_KEY_LSB 0x42
#define MGA1064_COL_KEY_MSB 0x43
#define MGA1064_PIX_PLLA_M 0x44
#define MGA1064_PIX_PLLA_N 0x45
#define MGA1064_PIX_PLLA_P 0x46
#define MGA1064_PIX_PLLB_M 0x48
#define MGA1064_PIX_PLLB_N 0x49
#define MGA1064_PIX_PLLB_P 0x4a
#define MGA1064_PIX_PLLC_M 0x4c
#define MGA1064_PIX_PLLC_N 0x4d
#define MGA1064_PIX_PLLC_P 0x4e
#define MGA1064_PIX_PLL_STAT 0x4f
#endif