2081 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			2081 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
	
	
 | 
						|
/*
 | 
						|
 *
 | 
						|
 * Copyright 1991-1999 by The XFree86 Project, Inc.
 | 
						|
 *
 | 
						|
 * Loosely based on code bearing the following copyright:
 | 
						|
 *
 | 
						|
 *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#define _NEED_SYSI86
 | 
						|
 | 
						|
#ifdef HAVE_XORG_CONFIG_H
 | 
						|
#include <xorg-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <unistd.h>
 | 
						|
 | 
						|
#include <X11/X.h>
 | 
						|
#include "misc.h"
 | 
						|
 | 
						|
#include "xf86.h"
 | 
						|
#include "xf86_OSproc.h"
 | 
						|
#include "vgaHW.h"
 | 
						|
 | 
						|
#include "compiler.h"
 | 
						|
 | 
						|
#include "xf86cmap.h"
 | 
						|
 | 
						|
#include "Pci.h"
 | 
						|
 | 
						|
#ifndef SAVE_FONT1
 | 
						|
#define SAVE_FONT1 1
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * These used to be OS-specific, which made this module have an undesirable
 | 
						|
 * OS dependency.  Define them by default for all platforms.
 | 
						|
 */
 | 
						|
#ifndef NEED_SAVED_CMAP
 | 
						|
#define NEED_SAVED_CMAP
 | 
						|
#endif
 | 
						|
#ifndef SAVE_TEXT
 | 
						|
#define SAVE_TEXT 1
 | 
						|
#endif
 | 
						|
#ifndef SAVE_FONT2
 | 
						|
#define SAVE_FONT2 1
 | 
						|
#endif
 | 
						|
 | 
						|
/* bytes per plane to save for text */
 | 
						|
#define TEXT_AMOUNT 16384
 | 
						|
 | 
						|
/* bytes per plane to save for font data */
 | 
						|
#define FONT_AMOUNT (8*8192)
 | 
						|
 | 
						|
#if 0
 | 
						|
/* Override all of these for now */
 | 
						|
#undef SAVE_FONT1
 | 
						|
#define SAVE_FONT1 1
 | 
						|
#undef SAVE_FONT2
 | 
						|
#define SAVE_FONT2 1
 | 
						|
#undef SAVE_TEST
 | 
						|
#define SAVE_TEST 1
 | 
						|
#undef FONT_AMOUNT
 | 
						|
#define FONT_AMOUNT 65536
 | 
						|
#undef TEXT_AMOUNT
 | 
						|
#define TEXT_AMOUNT 65536
 | 
						|
#endif
 | 
						|
 | 
						|
/* DAC indices for white and black */
 | 
						|
#define WHITE_VALUE 0x3F
 | 
						|
#define BLACK_VALUE 0x00
 | 
						|
#define OVERSCAN_VALUE 0x01
 | 
						|
 | 
						|
 | 
						|
/* Use a private definition of this here */
 | 
						|
#undef VGAHWPTR
 | 
						|
#define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr
 | 
						|
#define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p)))
 | 
						|
 | 
						|
static int vgaHWPrivateIndex = -1;
 | 
						|
 | 
						|
#define DAC_TEST_MASK 0x3F
 | 
						|
 | 
						|
#ifdef NEED_SAVED_CMAP
 | 
						|
/* This default colourmap is used only when it can't be read from the VGA */
 | 
						|
 | 
						|
static CARD8 defaultDAC[768] =
 | 
						|
{
 | 
						|
     0,  0,  0,    0,  0, 42,    0, 42,  0,    0, 42, 42,
 | 
						|
    42,  0,  0,   42,  0, 42,   42, 21,  0,   42, 42, 42,
 | 
						|
    21, 21, 21,   21, 21, 63,   21, 63, 21,   21, 63, 63,
 | 
						|
    63, 21, 21,   63, 21, 63,   63, 63, 21,   63, 63, 63,
 | 
						|
     0,  0,  0,    5,  5,  5,    8,  8,  8,   11, 11, 11,
 | 
						|
    14, 14, 14,   17, 17, 17,   20, 20, 20,   24, 24, 24,
 | 
						|
    28, 28, 28,   32, 32, 32,   36, 36, 36,   40, 40, 40,
 | 
						|
    45, 45, 45,   50, 50, 50,   56, 56, 56,   63, 63, 63,
 | 
						|
     0,  0, 63,   16,  0, 63,   31,  0, 63,   47,  0, 63,
 | 
						|
    63,  0, 63,   63,  0, 47,   63,  0, 31,   63,  0, 16,
 | 
						|
    63,  0,  0,   63, 16,  0,   63, 31,  0,   63, 47,  0,
 | 
						|
    63, 63,  0,   47, 63,  0,   31, 63,  0,   16, 63,  0,
 | 
						|
     0, 63,  0,    0, 63, 16,    0, 63, 31,    0, 63, 47,
 | 
						|
     0, 63, 63,    0, 47, 63,    0, 31, 63,    0, 16, 63,
 | 
						|
    31, 31, 63,   39, 31, 63,   47, 31, 63,   55, 31, 63,
 | 
						|
    63, 31, 63,   63, 31, 55,   63, 31, 47,   63, 31, 39,
 | 
						|
    63, 31, 31,   63, 39, 31,   63, 47, 31,   63, 55, 31,
 | 
						|
    63, 63, 31,   55, 63, 31,   47, 63, 31,   39, 63, 31,
 | 
						|
    31, 63, 31,   31, 63, 39,   31, 63, 47,   31, 63, 55,
 | 
						|
    31, 63, 63,   31, 55, 63,   31, 47, 63,   31, 39, 63,
 | 
						|
    45, 45, 63,   49, 45, 63,   54, 45, 63,   58, 45, 63,
 | 
						|
    63, 45, 63,   63, 45, 58,   63, 45, 54,   63, 45, 49,
 | 
						|
    63, 45, 45,   63, 49, 45,   63, 54, 45,   63, 58, 45,
 | 
						|
    63, 63, 45,   58, 63, 45,   54, 63, 45,   49, 63, 45,
 | 
						|
    45, 63, 45,   45, 63, 49,   45, 63, 54,   45, 63, 58,
 | 
						|
    45, 63, 63,   45, 58, 63,   45, 54, 63,   45, 49, 63,
 | 
						|
     0,  0, 28,    7,  0, 28,   14,  0, 28,   21,  0, 28,
 | 
						|
    28,  0, 28,   28,  0, 21,   28,  0, 14,   28,  0,  7,
 | 
						|
    28,  0,  0,   28,  7,  0,   28, 14,  0,   28, 21,  0,
 | 
						|
    28, 28,  0,   21, 28,  0,   14, 28,  0,    7, 28,  0,
 | 
						|
     0, 28,  0,    0, 28,  7,    0, 28, 14,    0, 28, 21,
 | 
						|
     0, 28, 28,    0, 21, 28,    0, 14, 28,    0,  7, 28,
 | 
						|
    14, 14, 28,   17, 14, 28,   21, 14, 28,   24, 14, 28,
 | 
						|
    28, 14, 28,   28, 14, 24,   28, 14, 21,   28, 14, 17,
 | 
						|
    28, 14, 14,   28, 17, 14,   28, 21, 14,   28, 24, 14,
 | 
						|
    28, 28, 14,   24, 28, 14,   21, 28, 14,   17, 28, 14,
 | 
						|
    14, 28, 14,   14, 28, 17,   14, 28, 21,   14, 28, 24,
 | 
						|
    14, 28, 28,   14, 24, 28,   14, 21, 28,   14, 17, 28,
 | 
						|
    20, 20, 28,   22, 20, 28,   24, 20, 28,   26, 20, 28,
 | 
						|
    28, 20, 28,   28, 20, 26,   28, 20, 24,   28, 20, 22,
 | 
						|
    28, 20, 20,   28, 22, 20,   28, 24, 20,   28, 26, 20,
 | 
						|
    28, 28, 20,   26, 28, 20,   24, 28, 20,   22, 28, 20,
 | 
						|
    20, 28, 20,   20, 28, 22,   20, 28, 24,   20, 28, 26,
 | 
						|
    20, 28, 28,   20, 26, 28,   20, 24, 28,   20, 22, 28,
 | 
						|
     0,  0, 16,    4,  0, 16,    8,  0, 16,   12,  0, 16,
 | 
						|
    16,  0, 16,   16,  0, 12,   16,  0,  8,   16,  0,  4,
 | 
						|
    16,  0,  0,   16,  4,  0,   16,  8,  0,   16, 12,  0,
 | 
						|
    16, 16,  0,   12, 16,  0,    8, 16,  0,    4, 16,  0,
 | 
						|
     0, 16,  0,    0, 16,  4,    0, 16,  8,    0, 16, 12,
 | 
						|
     0, 16, 16,    0, 12, 16,    0,  8, 16,    0,  4, 16,
 | 
						|
     8,  8, 16,   10,  8, 16,   12,  8, 16,   14,  8, 16,
 | 
						|
    16,  8, 16,   16,  8, 14,   16,  8, 12,   16,  8, 10,
 | 
						|
    16,  8,  8,   16, 10,  8,   16, 12,  8,   16, 14,  8,
 | 
						|
    16, 16,  8,   14, 16,  8,   12, 16,  8,   10, 16,  8,
 | 
						|
     8, 16,  8,    8, 16, 10,    8, 16, 12,    8, 16, 14,
 | 
						|
     8, 16, 16,    8, 14, 16,    8, 12, 16,    8, 10, 16,
 | 
						|
    11, 11, 16,   12, 11, 16,   13, 11, 16,   15, 11, 16,
 | 
						|
    16, 11, 16,   16, 11, 15,   16, 11, 13,   16, 11, 12,
 | 
						|
    16, 11, 11,   16, 12, 11,   16, 13, 11,   16, 15, 11,
 | 
						|
    16, 16, 11,   15, 16, 11,   13, 16, 11,   12, 16, 11,
 | 
						|
    11, 16, 11,   11, 16, 12,   11, 16, 13,   11, 16, 15,
 | 
						|
    11, 16, 16,   11, 15, 16,   11, 13, 16,   11, 12, 16,
 | 
						|
     0,  0,  0,    0,  0,  0,    0,  0,  0,    0,  0,  0,
 | 
						|
     0,  0,  0,    0,  0,  0,    0,  0,  0,    0,  0,  0,
 | 
						|
};
 | 
						|
#endif /* NEED_SAVED_CMAP */
 | 
						|
 | 
						|
/*
 | 
						|
 * Standard VGA versions of the register access functions.
 | 
						|
 */
 | 
						|
static void
 | 
						|
stdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
 | 
						|
    pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadCrtc(vgaHWPtr hwp, CARD8 index)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
 | 
						|
    return pci_io_read8(hwp->io, hwp->IOBase + VGA_CRTC_DATA_OFFSET);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_GRAPH_INDEX, index);
 | 
						|
    pci_io_write8(hwp->io, VGA_GRAPH_DATA, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadGr(vgaHWPtr hwp, CARD8 index)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_GRAPH_INDEX, index);
 | 
						|
    return pci_io_read8(hwp->io, VGA_GRAPH_DATA);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_SEQ_INDEX, index);
 | 
						|
    pci_io_write8(hwp->io, VGA_SEQ_DATA, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadSeq(vgaHWPtr hwp, CARD8 index)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_SEQ_INDEX, index);
 | 
						|
    return pci_io_read8(hwp->io, VGA_SEQ_DATA);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadST00(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return pci_io_read8(hwp->io, VGA_IN_STAT_0);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadST01(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadFCR(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return pci_io_read8(hwp->io, VGA_FEATURE_R);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteFCR(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, hwp->IOBase + VGA_FEATURE_W_OFFSET,value);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
 | 
						|
{
 | 
						|
    if (hwp->paletteEnabled)
 | 
						|
	index &= ~0x20;
 | 
						|
    else
 | 
						|
	index |= 0x20;
 | 
						|
 | 
						|
    (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
    pci_io_write8(hwp->io, VGA_ATTR_INDEX, index);
 | 
						|
    pci_io_write8(hwp->io, VGA_ATTR_DATA_W, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadAttr(vgaHWPtr hwp, CARD8 index)
 | 
						|
{
 | 
						|
    if (hwp->paletteEnabled)
 | 
						|
	index &= ~0x20;
 | 
						|
    else
 | 
						|
	index |= 0x20;
 | 
						|
 | 
						|
    (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
    pci_io_write8(hwp->io, VGA_ATTR_INDEX, index);
 | 
						|
    return pci_io_read8(hwp->io, VGA_ATTR_DATA_R);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteMiscOut(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_MISC_OUT_W, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadMiscOut(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return pci_io_read8(hwp->io, VGA_MISC_OUT_R);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdEnablePalette(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
    pci_io_write8(hwp->io, VGA_ATTR_INDEX, 0x00);
 | 
						|
    hwp->paletteEnabled = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdDisablePalette(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
    pci_io_write8(hwp->io, VGA_ATTR_INDEX, 0x20);
 | 
						|
    hwp->paletteEnabled = FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteDacMask(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_DAC_MASK, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadDacMask(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return pci_io_read8(hwp->io, VGA_DAC_MASK);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_DAC_READ_ADDR, value);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_DAC_WRITE_ADDR, value);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteDacData(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_DAC_DATA, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadDacData(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return pci_io_read8(hwp->io, VGA_DAC_DATA);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
stdReadEnable(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return pci_io_read8(hwp->io, VGA_ENABLE);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
stdWriteEnable(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    pci_io_write8(hwp->io, VGA_ENABLE, value);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
vgaHWSetStdFuncs(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    hwp->writeCrtc		= stdWriteCrtc;
 | 
						|
    hwp->readCrtc		= stdReadCrtc;
 | 
						|
    hwp->writeGr		= stdWriteGr;
 | 
						|
    hwp->readGr			= stdReadGr;
 | 
						|
    hwp->readST00               = stdReadST00;
 | 
						|
    hwp->readST01               = stdReadST01;
 | 
						|
    hwp->readFCR                = stdReadFCR;
 | 
						|
    hwp->writeFCR               = stdWriteFCR;
 | 
						|
    hwp->writeAttr		= stdWriteAttr;
 | 
						|
    hwp->readAttr		= stdReadAttr;
 | 
						|
    hwp->writeSeq		= stdWriteSeq;
 | 
						|
    hwp->readSeq		= stdReadSeq;
 | 
						|
    hwp->writeMiscOut		= stdWriteMiscOut;
 | 
						|
    hwp->readMiscOut		= stdReadMiscOut;
 | 
						|
    hwp->enablePalette		= stdEnablePalette;
 | 
						|
    hwp->disablePalette		= stdDisablePalette;
 | 
						|
    hwp->writeDacMask		= stdWriteDacMask;
 | 
						|
    hwp->readDacMask		= stdReadDacMask;
 | 
						|
    hwp->writeDacWriteAddr	= stdWriteDacWriteAddr;
 | 
						|
    hwp->writeDacReadAddr	= stdWriteDacReadAddr;
 | 
						|
    hwp->writeDacData		= stdWriteDacData;
 | 
						|
    hwp->readDacData		= stdReadDacData;
 | 
						|
    hwp->readEnable		= stdReadEnable;
 | 
						|
    hwp->writeEnable		= stdWriteEnable;
 | 
						|
 | 
						|
    hwp->io = pci_legacy_open_io(hwp->dev, 0, 64 * 1024);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * MMIO versions of the register access functions.  These require
 | 
						|
 * hwp->MemBase to be set in such a way that when the standard VGA port
 | 
						|
 * adderss is added the correct memory address results.
 | 
						|
 */
 | 
						|
 | 
						|
#define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p)))
 | 
						|
#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v))
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
 | 
						|
    moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadCrtc(vgaHWPtr hwp, CARD8 index)
 | 
						|
{
 | 
						|
    moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
 | 
						|
    return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(VGA_GRAPH_INDEX, index);
 | 
						|
    moutb(VGA_GRAPH_DATA, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadGr(vgaHWPtr hwp, CARD8 index)
 | 
						|
{
 | 
						|
    moutb(VGA_GRAPH_INDEX, index);
 | 
						|
    return minb(VGA_GRAPH_DATA);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(VGA_SEQ_INDEX, index);
 | 
						|
    moutb(VGA_SEQ_DATA, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadSeq(vgaHWPtr hwp, CARD8 index)
 | 
						|
{
 | 
						|
    moutb(VGA_SEQ_INDEX, index);
 | 
						|
    return minb(VGA_SEQ_DATA);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadST00(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return minb(VGA_IN_STAT_0);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadST01(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadFCR(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return minb(VGA_FEATURE_R);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteFCR(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(hwp->IOBase + VGA_FEATURE_W_OFFSET,value);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
 | 
						|
{
 | 
						|
    if (hwp->paletteEnabled)
 | 
						|
	index &= ~0x20;
 | 
						|
    else
 | 
						|
	index |= 0x20;
 | 
						|
 | 
						|
    (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
    moutb(VGA_ATTR_INDEX, index);
 | 
						|
    moutb(VGA_ATTR_DATA_W, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadAttr(vgaHWPtr hwp, CARD8 index)
 | 
						|
{
 | 
						|
    if (hwp->paletteEnabled)
 | 
						|
	index &= ~0x20;
 | 
						|
    else
 | 
						|
	index |= 0x20;
 | 
						|
 | 
						|
    (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
    moutb(VGA_ATTR_INDEX, index);
 | 
						|
    return minb(VGA_ATTR_DATA_R);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(VGA_MISC_OUT_W, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadMiscOut(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return minb(VGA_MISC_OUT_R);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioEnablePalette(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
    moutb(VGA_ATTR_INDEX, 0x00);
 | 
						|
    hwp->paletteEnabled = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioDisablePalette(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
 | 
						|
    moutb(VGA_ATTR_INDEX, 0x20);
 | 
						|
    hwp->paletteEnabled = FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(VGA_DAC_MASK, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadDacMask(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return minb(VGA_DAC_MASK);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(VGA_DAC_READ_ADDR, value);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(VGA_DAC_WRITE_ADDR, value);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteDacData(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(VGA_DAC_DATA, value);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadDacData(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return minb(VGA_DAC_DATA);
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
mmioReadEnable(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    return minb(VGA_ENABLE);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mmioWriteEnable(vgaHWPtr hwp, CARD8 value)
 | 
						|
{
 | 
						|
    moutb(VGA_ENABLE, value);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)
 | 
						|
{
 | 
						|
    hwp->writeCrtc		= mmioWriteCrtc;
 | 
						|
    hwp->readCrtc		= mmioReadCrtc;
 | 
						|
    hwp->writeGr		= mmioWriteGr;
 | 
						|
    hwp->readGr			= mmioReadGr;
 | 
						|
    hwp->readST00               = mmioReadST00;
 | 
						|
    hwp->readST01               = mmioReadST01;
 | 
						|
    hwp->readFCR                = mmioReadFCR;
 | 
						|
    hwp->writeFCR               = mmioWriteFCR;
 | 
						|
    hwp->writeAttr		= mmioWriteAttr;
 | 
						|
    hwp->readAttr		= mmioReadAttr;
 | 
						|
    hwp->writeSeq		= mmioWriteSeq;
 | 
						|
    hwp->readSeq		= mmioReadSeq;
 | 
						|
    hwp->writeMiscOut		= mmioWriteMiscOut;
 | 
						|
    hwp->readMiscOut		= mmioReadMiscOut;
 | 
						|
    hwp->enablePalette		= mmioEnablePalette;
 | 
						|
    hwp->disablePalette		= mmioDisablePalette;
 | 
						|
    hwp->writeDacMask		= mmioWriteDacMask;
 | 
						|
    hwp->readDacMask		= mmioReadDacMask;
 | 
						|
    hwp->writeDacWriteAddr	= mmioWriteDacWriteAddr;
 | 
						|
    hwp->writeDacReadAddr	= mmioWriteDacReadAddr;
 | 
						|
    hwp->writeDacData		= mmioWriteDacData;
 | 
						|
    hwp->readDacData		= mmioReadDacData;
 | 
						|
    hwp->MMIOBase		= base;
 | 
						|
    hwp->MMIOOffset		= offset;
 | 
						|
    hwp->readEnable		= mmioReadEnable;
 | 
						|
    hwp->writeEnable		= mmioWriteEnable;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * vgaHWProtect --
 | 
						|
 *	Protect VGA registers and memory from corruption during loads.
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
vgaHWProtect(ScrnInfoPtr pScrn, Bool on)
 | 
						|
{
 | 
						|
  vgaHWPtr hwp = VGAHWPTR(pScrn);
 | 
						|
  
 | 
						|
  unsigned char tmp;
 | 
						|
  
 | 
						|
  if (pScrn->vtSema) {
 | 
						|
    if (on) {
 | 
						|
      /*
 | 
						|
       * Turn off screen and disable sequencer.
 | 
						|
       */
 | 
						|
      tmp = hwp->readSeq(hwp, 0x01);
 | 
						|
 | 
						|
      vgaHWSeqReset(hwp, TRUE);			/* start synchronous reset */
 | 
						|
      hwp->writeSeq(hwp, 0x01, tmp | 0x20);	/* disable the display */
 | 
						|
 | 
						|
      hwp->enablePalette(hwp);
 | 
						|
    } else {
 | 
						|
      /*
 | 
						|
       * Reenable sequencer, then turn on screen.
 | 
						|
       */
 | 
						|
  
 | 
						|
      tmp = hwp->readSeq(hwp, 0x01);
 | 
						|
 | 
						|
      hwp->writeSeq(hwp, 0x01, tmp & ~0x20);	/* reenable display */
 | 
						|
      vgaHWSeqReset(hwp, FALSE);		/* clear synchronousreset */
 | 
						|
 | 
						|
      hwp->disablePalette(hwp);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
vgaHWProtectProc *vgaHWProtectWeak(void) {
 | 
						|
  return vgaHWProtect;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * vgaHWBlankScreen -- blank the screen.
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)
 | 
						|
{
 | 
						|
  vgaHWPtr hwp = VGAHWPTR(pScrn);
 | 
						|
  unsigned char scrn;
 | 
						|
 | 
						|
  scrn = hwp->readSeq(hwp, 0x01);
 | 
						|
 | 
						|
  if (on) {
 | 
						|
    scrn &= ~0x20;			/* enable screen */
 | 
						|
  } else {
 | 
						|
    scrn |= 0x20;			/* blank screen */
 | 
						|
  }
 | 
						|
 | 
						|
  vgaHWSeqReset(hwp, TRUE);
 | 
						|
  hwp->writeSeq(hwp, 0x01, scrn);	/* change mode */
 | 
						|
  vgaHWSeqReset(hwp, FALSE);
 | 
						|
}
 | 
						|
 | 
						|
vgaHWBlankScreenProc *vgaHWBlankScreenWeak(void) {
 | 
						|
  return vgaHWBlankScreen;
 | 
						|
}  
 | 
						|
 | 
						|
/*
 | 
						|
 * vgaHWSaveScreen -- blank the screen.
 | 
						|
 */
 | 
						|
 | 
						|
Bool
 | 
						|
vgaHWSaveScreen(ScreenPtr pScreen, int mode)
 | 
						|
{
 | 
						|
   ScrnInfoPtr pScrn = NULL;
 | 
						|
   Bool on;
 | 
						|
 | 
						|
   if (pScreen != NULL)
 | 
						|
      pScrn = xf86Screens[pScreen->myNum];
 | 
						|
 | 
						|
   on = xf86IsUnblank(mode);
 | 
						|
 | 
						|
#if 0
 | 
						|
   if (on)
 | 
						|
      SetTimeSinceLastInputEvent();
 | 
						|
#endif
 | 
						|
 | 
						|
   if ((pScrn != NULL) && pScrn->vtSema) {
 | 
						|
     vgaHWBlankScreen(pScrn, on);
 | 
						|
   }
 | 
						|
   return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode
 | 
						|
 *
 | 
						|
 * This generic VGA function can only set the Off and On modes.  If the
 | 
						|
 * Standby and Suspend modes are to be supported, a chip specific replacement
 | 
						|
 * for this function must be written.
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
vgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
 | 
						|
{
 | 
						|
  unsigned char seq1 = 0, crtc17 = 0;
 | 
						|
  vgaHWPtr hwp = VGAHWPTR(pScrn);
 | 
						|
 | 
						|
  if (!pScrn->vtSema) return;
 | 
						|
 | 
						|
  switch (PowerManagementMode) {
 | 
						|
  case DPMSModeOn:
 | 
						|
    /* Screen: On; HSync: On, VSync: On */
 | 
						|
    seq1 = 0x00;
 | 
						|
    crtc17 = 0x80;
 | 
						|
    break;
 | 
						|
  case DPMSModeStandby:
 | 
						|
    /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
 | 
						|
    seq1 = 0x20;
 | 
						|
    crtc17 = 0x80;
 | 
						|
    break;
 | 
						|
  case DPMSModeSuspend:
 | 
						|
    /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
 | 
						|
    seq1 = 0x20;
 | 
						|
    crtc17 = 0x80;
 | 
						|
    break;
 | 
						|
  case DPMSModeOff:
 | 
						|
    /* Screen: Off; HSync: Off, VSync: Off */
 | 
						|
    seq1 = 0x20;
 | 
						|
    crtc17 = 0x00;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  hwp->writeSeq(hwp, 0x00, 0x01);		/* Synchronous Reset */
 | 
						|
  seq1 |= hwp->readSeq(hwp, 0x01) & ~0x20;
 | 
						|
  hwp->writeSeq(hwp, 0x01, seq1);
 | 
						|
  crtc17 |= hwp->readCrtc(hwp, 0x17) & ~0x80;
 | 
						|
  usleep(10000);
 | 
						|
  hwp->writeCrtc(hwp, 0x17, crtc17);
 | 
						|
  hwp->writeSeq(hwp, 0x00, 0x03);		/* End Reset */
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * vgaHWSeqReset
 | 
						|
 *      perform a sequencer reset.
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
vgaHWSeqReset(vgaHWPtr hwp, Bool start)
 | 
						|
{
 | 
						|
  if (start)
 | 
						|
    hwp->writeSeq(hwp, 0x00, 0x01);		/* Synchronous Reset */
 | 
						|
  else
 | 
						|
    hwp->writeSeq(hwp, 0x00, 0x03);		/* End Reset */
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
 | 
						|
{
 | 
						|
#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(scrninfp);
 | 
						|
    int savedIOBase;
 | 
						|
    unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4;
 | 
						|
    Bool doMap = FALSE;
 | 
						|
 | 
						|
    /* If nothing to do, return now */
 | 
						|
    if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
 | 
						|
	return;
 | 
						|
 | 
						|
    if (hwp->Base == NULL) {
 | 
						|
	doMap = TRUE;
 | 
						|
	if (!vgaHWMapMem(scrninfp)) {
 | 
						|
	    xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
 | 
						|
		       "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
 | 
						|
	    return;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    /* save the registers that are needed here */
 | 
						|
    miscOut = hwp->readMiscOut(hwp);
 | 
						|
    attr10 = hwp->readAttr(hwp, 0x10);
 | 
						|
    gr1 = hwp->readGr(hwp, 0x01);
 | 
						|
    gr3 = hwp->readGr(hwp, 0x03);
 | 
						|
    gr4 = hwp->readGr(hwp, 0x04);
 | 
						|
    gr5 = hwp->readGr(hwp, 0x05);
 | 
						|
    gr6 = hwp->readGr(hwp, 0x06);
 | 
						|
    gr8 = hwp->readGr(hwp, 0x08);
 | 
						|
    seq2 = hwp->readSeq(hwp, 0x02);
 | 
						|
    seq4 = hwp->readSeq(hwp, 0x04);
 | 
						|
 | 
						|
    /* save hwp->IOBase and temporarily set it for colour mode */
 | 
						|
    savedIOBase = hwp->IOBase;
 | 
						|
    hwp->IOBase = VGA_IOBASE_COLOR;
 | 
						|
 | 
						|
    /* Force into colour mode */
 | 
						|
    hwp->writeMiscOut(hwp, miscOut | 0x01);
 | 
						|
 | 
						|
    vgaHWBlankScreen(scrninfp, FALSE);
 | 
						|
 | 
						|
    /*
 | 
						|
     * here we temporarily switch to 16 colour planar mode, to simply
 | 
						|
     * copy the font-info and saved text.
 | 
						|
     *
 | 
						|
     * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
 | 
						|
     */
 | 
						|
#if 0
 | 
						|
    hwp->writeAttr(hwp, 0x10, 0x01);	/* graphics mode */
 | 
						|
#endif
 | 
						|
 | 
						|
    hwp->writeSeq(hwp, 0x04, 0x06);	/* enable plane graphics */
 | 
						|
    hwp->writeGr(hwp, 0x05, 0x00);	/* write mode 0, read mode 0 */
 | 
						|
    hwp->writeGr(hwp, 0x06, 0x05);	/* set graphics */
 | 
						|
 | 
						|
    if (scrninfp->depth == 4) {
 | 
						|
	/* GJA */
 | 
						|
	hwp->writeGr(hwp, 0x03, 0x00);	/* don't rotate, write unmodified */
 | 
						|
	hwp->writeGr(hwp, 0x08, 0xFF);	/* write all bits in a byte */
 | 
						|
	hwp->writeGr(hwp, 0x01, 0x00);	/* all planes come from CPU */
 | 
						|
    }
 | 
						|
 | 
						|
#if SAVE_FONT1
 | 
						|
    if (hwp->FontInfo1) {
 | 
						|
	hwp->writeSeq(hwp, 0x02, 0x04);	/* write to plane 2 */
 | 
						|
	hwp->writeGr(hwp, 0x04, 0x02);	/* read plane 2 */
 | 
						|
	slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
#if SAVE_FONT2
 | 
						|
    if (hwp->FontInfo2) {
 | 
						|
	hwp->writeSeq(hwp, 0x02, 0x08);	/* write to plane 3 */
 | 
						|
	hwp->writeGr(hwp, 0x04, 0x03);	/* read plane 3 */
 | 
						|
	slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
#if SAVE_TEXT
 | 
						|
    if (hwp->TextInfo) {
 | 
						|
	hwp->writeSeq(hwp, 0x02, 0x01);	/* write to plane 0 */
 | 
						|
	hwp->writeGr(hwp, 0x04, 0x00);	/* read plane 0 */
 | 
						|
	slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT);
 | 
						|
	hwp->writeSeq(hwp, 0x02, 0x02);	/* write to plane 1 */
 | 
						|
	hwp->writeGr(hwp, 0x04, 0x01);	/* read plane 1 */
 | 
						|
	slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT,
 | 
						|
			hwp->Base, TEXT_AMOUNT);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    vgaHWBlankScreen(scrninfp, TRUE);
 | 
						|
 | 
						|
    /* restore the registers that were changed */
 | 
						|
    hwp->writeMiscOut(hwp, miscOut);
 | 
						|
    hwp->writeAttr(hwp, 0x10, attr10);
 | 
						|
    hwp->writeGr(hwp, 0x01, gr1);
 | 
						|
    hwp->writeGr(hwp, 0x03, gr3);
 | 
						|
    hwp->writeGr(hwp, 0x04, gr4);
 | 
						|
    hwp->writeGr(hwp, 0x05, gr5);
 | 
						|
    hwp->writeGr(hwp, 0x06, gr6);
 | 
						|
    hwp->writeGr(hwp, 0x08, gr8);
 | 
						|
    hwp->writeSeq(hwp, 0x02, seq2);
 | 
						|
    hwp->writeSeq(hwp, 0x04, seq4);
 | 
						|
    hwp->IOBase = savedIOBase;
 | 
						|
 | 
						|
    if (doMap)
 | 
						|
	vgaHWUnmapMem(scrninfp);
 | 
						|
 | 
						|
#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(scrninfp);
 | 
						|
    int i;
 | 
						|
 | 
						|
    if (restore->MiscOutReg & 0x01)
 | 
						|
	hwp->IOBase = VGA_IOBASE_COLOR;
 | 
						|
    else
 | 
						|
	hwp->IOBase = VGA_IOBASE_MONO;
 | 
						|
 | 
						|
    hwp->writeMiscOut(hwp, restore->MiscOutReg);
 | 
						|
 | 
						|
    for (i = 1; i < restore->numSequencer; i++)
 | 
						|
	hwp->writeSeq(hwp, i, restore->Sequencer[i]);
 | 
						|
  
 | 
						|
    /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
 | 
						|
    hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
 | 
						|
 | 
						|
    for (i = 0; i < restore->numCRTC; i++)
 | 
						|
	hwp->writeCrtc(hwp, i, restore->CRTC[i]);
 | 
						|
 | 
						|
    for (i = 0; i < restore->numGraphics; i++)
 | 
						|
	hwp->writeGr(hwp, i, restore->Graphics[i]);
 | 
						|
 | 
						|
    hwp->enablePalette(hwp);
 | 
						|
    for (i = 0; i < restore->numAttribute; i++)
 | 
						|
	hwp->writeAttr(hwp, i, restore->Attribute[i]);
 | 
						|
    hwp->disablePalette(hwp);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(scrninfp);
 | 
						|
    int i;
 | 
						|
 | 
						|
#if 0
 | 
						|
    hwp->enablePalette(hwp);
 | 
						|
#endif
 | 
						|
 | 
						|
    hwp->writeDacMask(hwp, 0xFF);
 | 
						|
    hwp->writeDacWriteAddr(hwp, 0x00);
 | 
						|
    for (i = 0; i < 768; i++) {
 | 
						|
	hwp->writeDacData(hwp, restore->DAC[i]);
 | 
						|
	DACDelay(hwp);
 | 
						|
    }
 | 
						|
 | 
						|
    hwp->disablePalette(hwp);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * vgaHWRestore --
 | 
						|
 *      restore the VGA state
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
vgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags)
 | 
						|
{
 | 
						|
    if (flags & VGA_SR_MODE)
 | 
						|
	vgaHWRestoreMode(scrninfp, restore);
 | 
						|
 | 
						|
    if (flags & VGA_SR_FONTS)
 | 
						|
	vgaHWRestoreFonts(scrninfp, restore);
 | 
						|
 | 
						|
    if (flags & VGA_SR_CMAP)
 | 
						|
	vgaHWRestoreColormap(scrninfp, restore);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
vgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
 | 
						|
{
 | 
						|
#if  SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(scrninfp);
 | 
						|
    int savedIOBase;
 | 
						|
    unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4;
 | 
						|
    Bool doMap = FALSE;
 | 
						|
 | 
						|
    if (hwp->Base == NULL) {
 | 
						|
	doMap = TRUE;
 | 
						|
	if (!vgaHWMapMem(scrninfp)) {
 | 
						|
	    xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
 | 
						|
		       "vgaHWSaveFonts: vgaHWMapMem() failed\n");
 | 
						|
	    return;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    /* If in graphics mode, don't save anything */
 | 
						|
    attr10 = hwp->readAttr(hwp, 0x10);
 | 
						|
    if (attr10 & 0x01)
 | 
						|
	return;
 | 
						|
 | 
						|
    /* save the registers that are needed here */
 | 
						|
    miscOut = hwp->readMiscOut(hwp);
 | 
						|
    gr4 = hwp->readGr(hwp, 0x04);
 | 
						|
    gr5 = hwp->readGr(hwp, 0x05);
 | 
						|
    gr6 = hwp->readGr(hwp, 0x06);
 | 
						|
    seq2 = hwp->readSeq(hwp, 0x02);
 | 
						|
    seq4 = hwp->readSeq(hwp, 0x04);
 | 
						|
 | 
						|
    /* save hwp->IOBase and temporarily set it for colour mode */
 | 
						|
    savedIOBase = hwp->IOBase;
 | 
						|
    hwp->IOBase = VGA_IOBASE_COLOR;
 | 
						|
 | 
						|
    /* Force into colour mode */
 | 
						|
    hwp->writeMiscOut(hwp, miscOut | 0x01);
 | 
						|
 | 
						|
    vgaHWBlankScreen(scrninfp, FALSE);
 | 
						|
  
 | 
						|
    /*
 | 
						|
     * get the character sets, and text screen if required
 | 
						|
     */
 | 
						|
    /*
 | 
						|
     * Here we temporarily switch to 16 colour planar mode, to simply
 | 
						|
     * copy the font-info
 | 
						|
     *
 | 
						|
     * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
 | 
						|
     */
 | 
						|
#if 0
 | 
						|
    hwp->writeAttr(hwp, 0x10, 0x01);	/* graphics mode */
 | 
						|
#endif
 | 
						|
 | 
						|
    hwp->writeSeq(hwp, 0x04, 0x06);	/* enable plane graphics */
 | 
						|
    hwp->writeGr(hwp, 0x05, 0x00);	/* write mode 0, read mode 0 */
 | 
						|
    hwp->writeGr(hwp, 0x06, 0x05);	/* set graphics */
 | 
						|
 | 
						|
#if SAVE_FONT1
 | 
						|
    if (hwp->FontInfo1 || (hwp->FontInfo1 = malloc(FONT_AMOUNT))) {
 | 
						|
	hwp->writeSeq(hwp, 0x02, 0x04);	/* write to plane 2 */
 | 
						|
	hwp->writeGr(hwp, 0x04, 0x02);	/* read plane 2 */
 | 
						|
	slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT);
 | 
						|
    }
 | 
						|
#endif /* SAVE_FONT1 */
 | 
						|
#if SAVE_FONT2
 | 
						|
    if (hwp->FontInfo2 || (hwp->FontInfo2 = malloc(FONT_AMOUNT))) {
 | 
						|
	hwp->writeSeq(hwp, 0x02, 0x08);	/* write to plane 3 */
 | 
						|
	hwp->writeGr(hwp, 0x04, 0x03);	/* read plane 3 */
 | 
						|
	slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT);
 | 
						|
    }
 | 
						|
#endif /* SAVE_FONT2 */
 | 
						|
#if SAVE_TEXT
 | 
						|
    if (hwp->TextInfo || (hwp->TextInfo = malloc(2 * TEXT_AMOUNT))) {
 | 
						|
	hwp->writeSeq(hwp, 0x02, 0x01);	/* write to plane 0 */
 | 
						|
	hwp->writeGr(hwp, 0x04, 0x00);	/* read plane 0 */
 | 
						|
	slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT);
 | 
						|
	hwp->writeSeq(hwp, 0x02, 0x02);	/* write to plane 1 */
 | 
						|
	hwp->writeGr(hwp, 0x04, 0x01);	/* read plane 1 */
 | 
						|
	slowbcopy_frombus(hwp->Base,
 | 
						|
		(unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT);
 | 
						|
    }
 | 
						|
#endif /* SAVE_TEXT */
 | 
						|
 | 
						|
    /* Restore clobbered registers */
 | 
						|
    hwp->writeAttr(hwp, 0x10, attr10);
 | 
						|
    hwp->writeSeq(hwp, 0x02, seq2);
 | 
						|
    hwp->writeSeq(hwp, 0x04, seq4);
 | 
						|
    hwp->writeGr(hwp, 0x04, gr4);
 | 
						|
    hwp->writeGr(hwp, 0x05, gr5);
 | 
						|
    hwp->writeGr(hwp, 0x06, gr6);
 | 
						|
    hwp->writeMiscOut(hwp, miscOut);
 | 
						|
    hwp->IOBase = savedIOBase;
 | 
						|
 | 
						|
    vgaHWBlankScreen(scrninfp, TRUE);
 | 
						|
 | 
						|
    if (doMap)
 | 
						|
	vgaHWUnmapMem(scrninfp);
 | 
						|
 | 
						|
#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(scrninfp);
 | 
						|
    int i;
 | 
						|
 | 
						|
    save->MiscOutReg = hwp->readMiscOut(hwp);
 | 
						|
    if (save->MiscOutReg & 0x01)
 | 
						|
	hwp->IOBase = VGA_IOBASE_COLOR;
 | 
						|
    else
 | 
						|
	hwp->IOBase = VGA_IOBASE_MONO;
 | 
						|
 | 
						|
    for (i = 0; i < save->numCRTC; i++) {
 | 
						|
	save->CRTC[i] = hwp->readCrtc(hwp, i);
 | 
						|
	DebugF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
 | 
						|
    }
 | 
						|
 | 
						|
    hwp->enablePalette(hwp);
 | 
						|
    for (i = 0; i < save->numAttribute; i++) {
 | 
						|
	save->Attribute[i] = hwp->readAttr(hwp, i);
 | 
						|
	DebugF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
 | 
						|
    }
 | 
						|
    hwp->disablePalette(hwp);
 | 
						|
 | 
						|
    for (i = 0; i < save->numGraphics; i++) {
 | 
						|
	save->Graphics[i] = hwp->readGr(hwp, i);
 | 
						|
	DebugF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
 | 
						|
    }
 | 
						|
 | 
						|
    for (i = 1; i < save->numSequencer; i++) {
 | 
						|
	save->Sequencer[i] = hwp->readSeq(hwp, i);
 | 
						|
	DebugF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(scrninfp);
 | 
						|
    Bool readError = FALSE;
 | 
						|
    int i;
 | 
						|
 | 
						|
#ifdef NEED_SAVED_CMAP
 | 
						|
    /*
 | 
						|
     * Some ET4000 chips from 1991 have a HW bug that prevents the reading
 | 
						|
     * of the color lookup table.  Mask rev 9042EAI is known to have this bug.
 | 
						|
     *
 | 
						|
     * If the colourmap is not readable, we set the saved map to a default
 | 
						|
     * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA
 | 
						|
     * Cards" 2nd ed).
 | 
						|
     */
 | 
						|
 | 
						|
    /* Only save it once */
 | 
						|
    if (hwp->cmapSaved)
 | 
						|
	return;
 | 
						|
 | 
						|
#if 0
 | 
						|
    hwp->enablePalette(hwp);
 | 
						|
#endif
 | 
						|
 | 
						|
    hwp->writeDacMask(hwp, 0xFF);
 | 
						|
 | 
						|
    /*
 | 
						|
     * check if we can read the lookup table
 | 
						|
     */
 | 
						|
    hwp->writeDacReadAddr(hwp, 0x00);
 | 
						|
    for (i = 0; i < 6; i++) {
 | 
						|
	save->DAC[i] = hwp->readDacData(hwp);
 | 
						|
	switch (i % 3) {
 | 
						|
	case 0:
 | 
						|
	    DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
 | 
						|
	    break;
 | 
						|
	case 1:
 | 
						|
	    DebugF("0x%02x, ", save->DAC[i]);
 | 
						|
	    break;
 | 
						|
	case 2:
 | 
						|
	    DebugF("0x%02x\n", save->DAC[i]);
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * Check if we can read the palette -
 | 
						|
     * use foreground color to prevent flashing.
 | 
						|
     */
 | 
						|
    hwp->writeDacWriteAddr(hwp, 0x01);
 | 
						|
    for (i = 3; i < 6; i++)
 | 
						|
	hwp->writeDacData(hwp, ~save->DAC[i] & DAC_TEST_MASK);
 | 
						|
    hwp->writeDacReadAddr(hwp, 0x01);
 | 
						|
    for (i = 3; i < 6; i++) {
 | 
						|
	if (hwp->readDacData(hwp) != (~save->DAC[i] & DAC_TEST_MASK))
 | 
						|
	    readError = TRUE;
 | 
						|
    }
 | 
						|
    hwp->writeDacWriteAddr(hwp, 0x01);
 | 
						|
    for (i = 3; i < 6; i++)
 | 
						|
	hwp->writeDacData(hwp, save->DAC[i]);
 | 
						|
 | 
						|
    if (readError) {
 | 
						|
	/*			 
 | 
						|
	 * save the default lookup table
 | 
						|
	 */
 | 
						|
	memmove(save->DAC, defaultDAC, 768);
 | 
						|
	xf86DrvMsg(scrninfp->scrnIndex, X_WARNING,
 | 
						|
	   "Cannot read colourmap from VGA.  Will restore with default\n");
 | 
						|
    } else {
 | 
						|
	/* save the colourmap */
 | 
						|
	hwp->writeDacReadAddr(hwp, 0x02);
 | 
						|
	for (i = 6; i < 768; i++) {
 | 
						|
	    save->DAC[i] = hwp->readDacData(hwp);
 | 
						|
	    DACDelay(hwp);
 | 
						|
	    switch (i % 3) {
 | 
						|
	    case 0:
 | 
						|
		DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
 | 
						|
		break;
 | 
						|
	    case 1:
 | 
						|
		DebugF("0x%02x, ", save->DAC[i]);
 | 
						|
		break;
 | 
						|
	    case 2:
 | 
						|
		DebugF("0x%02x\n", save->DAC[i]);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    hwp->disablePalette(hwp);
 | 
						|
    hwp->cmapSaved = TRUE;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * vgaHWSave --
 | 
						|
 *      save the current VGA state
 | 
						|
 */
 | 
						|
 | 
						|
void
 | 
						|
vgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags)
 | 
						|
{
 | 
						|
    if (save == NULL)
 | 
						|
	return;
 | 
						|
 | 
						|
   if (flags & VGA_SR_CMAP)
 | 
						|
	vgaHWSaveColormap(scrninfp, save);
 | 
						|
 | 
						|
   if (flags & VGA_SR_MODE)
 | 
						|
	vgaHWSaveMode(scrninfp, save);
 | 
						|
 | 
						|
   if (flags & VGA_SR_FONTS)
 | 
						|
	vgaHWSaveFonts(scrninfp, save);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * vgaHWInit --
 | 
						|
 *      Handle the initialization, etc. of a screen.
 | 
						|
 *      Return FALSE on failure.
 | 
						|
 */
 | 
						|
 | 
						|
Bool
 | 
						|
vgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode)
 | 
						|
{
 | 
						|
    unsigned int       i;
 | 
						|
    vgaHWPtr hwp;
 | 
						|
    vgaRegPtr regp;
 | 
						|
    int depth = scrninfp->depth;
 | 
						|
 | 
						|
    /*
 | 
						|
     * make sure the vgaHWRec is allocated
 | 
						|
     */
 | 
						|
    if (!vgaHWGetHWRec(scrninfp))
 | 
						|
	return FALSE;
 | 
						|
    hwp = VGAHWPTR(scrninfp);
 | 
						|
    regp = &hwp->ModeReg;
 | 
						|
    
 | 
						|
    /*
 | 
						|
     * compute correct Hsync & Vsync polarity 
 | 
						|
     */
 | 
						|
    if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
 | 
						|
        && (mode->Flags & (V_PVSYNC | V_NVSYNC)))
 | 
						|
    {
 | 
						|
        regp->MiscOutReg = 0x23;
 | 
						|
        if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
 | 
						|
        if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        int VDisplay = mode->VDisplay;
 | 
						|
        if (mode->Flags & V_DBLSCAN)
 | 
						|
            VDisplay *= 2;
 | 
						|
        if (mode->VScan > 1)
 | 
						|
            VDisplay *= mode->VScan;
 | 
						|
        if      (VDisplay < 400)
 | 
						|
            regp->MiscOutReg = 0xA3;		/* +hsync -vsync */
 | 
						|
        else if (VDisplay < 480)
 | 
						|
            regp->MiscOutReg = 0x63;		/* -hsync +vsync */
 | 
						|
        else if (VDisplay < 768)
 | 
						|
            regp->MiscOutReg = 0xE3;		/* -hsync -vsync */
 | 
						|
        else
 | 
						|
            regp->MiscOutReg = 0x23;		/* +hsync +vsync */
 | 
						|
    }
 | 
						|
    
 | 
						|
    regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Time Sequencer
 | 
						|
     */
 | 
						|
    if (depth == 4)
 | 
						|
        regp->Sequencer[0] = 0x02;
 | 
						|
    else
 | 
						|
        regp->Sequencer[0] = 0x00;
 | 
						|
    if (mode->Flags & V_CLKDIV2) 
 | 
						|
        regp->Sequencer[1] = 0x09;
 | 
						|
    else
 | 
						|
        regp->Sequencer[1] = 0x01;
 | 
						|
    if (depth == 1)
 | 
						|
        regp->Sequencer[2] = 1 << BIT_PLANE;
 | 
						|
    else
 | 
						|
        regp->Sequencer[2] = 0x0F;
 | 
						|
    regp->Sequencer[3] = 0x00;                             /* Font select */
 | 
						|
    if (depth < 8)
 | 
						|
        regp->Sequencer[4] = 0x06;                             /* Misc */
 | 
						|
    else
 | 
						|
        regp->Sequencer[4] = 0x0E;                             /* Misc */
 | 
						|
 | 
						|
    /*
 | 
						|
     * CRTC Controller
 | 
						|
     */
 | 
						|
    regp->CRTC[0]  = (mode->CrtcHTotal >> 3) - 5;
 | 
						|
    regp->CRTC[1]  = (mode->CrtcHDisplay >> 3) - 1;
 | 
						|
    regp->CRTC[2]  = (mode->CrtcHBlankStart >> 3) - 1;
 | 
						|
    regp->CRTC[3]  = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
 | 
						|
    i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F);
 | 
						|
    if (i < 0x80)
 | 
						|
	regp->CRTC[3] |= i;
 | 
						|
    regp->CRTC[4]  = (mode->CrtcHSyncStart >> 3);
 | 
						|
    regp->CRTC[5]  = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
 | 
						|
	| (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
 | 
						|
    regp->CRTC[6]  = (mode->CrtcVTotal - 2) & 0xFF;
 | 
						|
    regp->CRTC[7]  = (((mode->CrtcVTotal - 2) & 0x100) >> 8)
 | 
						|
	| (((mode->CrtcVDisplay - 1) & 0x100) >> 7)
 | 
						|
	| ((mode->CrtcVSyncStart & 0x100) >> 6)
 | 
						|
	| (((mode->CrtcVBlankStart - 1) & 0x100) >> 5)
 | 
						|
	| 0x10
 | 
						|
	| (((mode->CrtcVTotal - 2) & 0x200)   >> 4)
 | 
						|
	| (((mode->CrtcVDisplay - 1) & 0x200) >> 3)
 | 
						|
	| ((mode->CrtcVSyncStart & 0x200) >> 2);
 | 
						|
    regp->CRTC[8]  = 0x00;
 | 
						|
    regp->CRTC[9]  = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40;
 | 
						|
    if (mode->Flags & V_DBLSCAN)
 | 
						|
	regp->CRTC[9] |= 0x80;
 | 
						|
    if (mode->VScan >= 32)
 | 
						|
	regp->CRTC[9] |= 0x1F;
 | 
						|
    else if (mode->VScan > 1)
 | 
						|
	regp->CRTC[9] |= mode->VScan - 1;
 | 
						|
    regp->CRTC[10] = 0x00;
 | 
						|
    regp->CRTC[11] = 0x00;
 | 
						|
    regp->CRTC[12] = 0x00;
 | 
						|
    regp->CRTC[13] = 0x00;
 | 
						|
    regp->CRTC[14] = 0x00;
 | 
						|
    regp->CRTC[15] = 0x00;
 | 
						|
    regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF;
 | 
						|
    regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20;
 | 
						|
    regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF;
 | 
						|
    regp->CRTC[19] = scrninfp->displayWidth >> 4;  /* just a guess */
 | 
						|
    regp->CRTC[20] = 0x00;
 | 
						|
    regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF; 
 | 
						|
    regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
 | 
						|
    if (depth < 8)
 | 
						|
	regp->CRTC[23] = 0xE3;
 | 
						|
    else
 | 
						|
	regp->CRTC[23] = 0xC3;
 | 
						|
    regp->CRTC[24] = 0xFF;
 | 
						|
 | 
						|
    vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
 | 
						|
    vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Theory resumes here....
 | 
						|
     */
 | 
						|
 | 
						|
    /*
 | 
						|
     * Graphics Display Controller
 | 
						|
     */
 | 
						|
    regp->Graphics[0] = 0x00;
 | 
						|
    regp->Graphics[1] = 0x00;
 | 
						|
    regp->Graphics[2] = 0x00;
 | 
						|
    regp->Graphics[3] = 0x00;
 | 
						|
    if (depth == 1) {
 | 
						|
        regp->Graphics[4] = BIT_PLANE;
 | 
						|
        regp->Graphics[5] = 0x00;
 | 
						|
    } else {
 | 
						|
        regp->Graphics[4] = 0x00;
 | 
						|
        if (depth == 4)
 | 
						|
            regp->Graphics[5] = 0x02;
 | 
						|
        else
 | 
						|
            regp->Graphics[5] = 0x40;
 | 
						|
    }
 | 
						|
    regp->Graphics[6] = 0x05;   /* only map 64k VGA memory !!!! */
 | 
						|
    regp->Graphics[7] = 0x0F;
 | 
						|
    regp->Graphics[8] = 0xFF;
 | 
						|
  
 | 
						|
    if (depth == 1) {
 | 
						|
        /* Initialise the Mono map according to which bit-plane gets used */
 | 
						|
 | 
						|
	Bool flipPixels = xf86GetFlipPixels();
 | 
						|
 | 
						|
        for (i=0; i<16; i++)
 | 
						|
            if (((i & (1 << BIT_PLANE)) != 0) != flipPixels)
 | 
						|
                regp->Attribute[i] = WHITE_VALUE;
 | 
						|
            else
 | 
						|
                regp->Attribute[i] = BLACK_VALUE;
 | 
						|
 | 
						|
        regp->Attribute[16] = 0x01;  /* -VGA2- */ /* wrong for the ET4000 */
 | 
						|
	if (!hwp->ShowOverscan)
 | 
						|
            regp->Attribute[OVERSCAN] = OVERSCAN_VALUE;  /* -VGA2- */
 | 
						|
    } else {
 | 
						|
        regp->Attribute[0]  = 0x00; /* standard colormap translation */
 | 
						|
        regp->Attribute[1]  = 0x01;
 | 
						|
        regp->Attribute[2]  = 0x02;
 | 
						|
        regp->Attribute[3]  = 0x03;
 | 
						|
        regp->Attribute[4]  = 0x04;
 | 
						|
        regp->Attribute[5]  = 0x05;
 | 
						|
        regp->Attribute[6]  = 0x06;
 | 
						|
        regp->Attribute[7]  = 0x07;
 | 
						|
        regp->Attribute[8]  = 0x08;
 | 
						|
        regp->Attribute[9]  = 0x09;
 | 
						|
        regp->Attribute[10] = 0x0A;
 | 
						|
        regp->Attribute[11] = 0x0B;
 | 
						|
        regp->Attribute[12] = 0x0C;
 | 
						|
        regp->Attribute[13] = 0x0D;
 | 
						|
        regp->Attribute[14] = 0x0E;
 | 
						|
        regp->Attribute[15] = 0x0F;
 | 
						|
        if (depth == 4)
 | 
						|
            regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
 | 
						|
        else
 | 
						|
            regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
 | 
						|
        /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
 | 
						|
    }
 | 
						|
    regp->Attribute[18] = 0x0F;
 | 
						|
    regp->Attribute[19] = 0x00;
 | 
						|
    regp->Attribute[20] = 0x00;
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
    /*
 | 
						|
     * OK, so much for theory.  Now, let's deal with the >real< world...
 | 
						|
     *
 | 
						|
     * The above CRTC settings are precise in theory, except that many, if not
 | 
						|
     * most, VGA clones fail to reset the blanking signal when the character or
 | 
						|
     * line counter reaches [HV]Total.  In this case, the signal is only
 | 
						|
     * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as
 | 
						|
     * the case may be) at the start of the >next< scanline or frame, which
 | 
						|
     * means only part of the screen shows.  This affects how null overscans
 | 
						|
     * are to be implemented on such adapters.
 | 
						|
     *
 | 
						|
     * Henceforth, VGA cores that implement this broken, but unfortunately
 | 
						|
     * common, behaviour are to be designated as KGA's, in honour of Koen
 | 
						|
     * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion
 | 
						|
     * a series of events that led to the discovery of this problem.
 | 
						|
     *
 | 
						|
     * Some VGA's are KGA's only in the horizontal, or only in the vertical,
 | 
						|
     * some in both, others in neither.  Don't let anyone tell you there is
 | 
						|
     * such a thing as a VGA "standard"...  And, thank the Creator for the fact
 | 
						|
     * that Hilbert spaces are not yet implemented in this industry.
 | 
						|
     *
 | 
						|
     * The following implements a trick suggested by David Dawes.  This sets
 | 
						|
     * [HV]BlankEnd to zero if the blanking interval does not already contain a
 | 
						|
     * 0-point, and decrements it by one otherwise.  In the latter case, this
 | 
						|
     * will produce a left and/or top overscan which the colourmap code will
 | 
						|
     * (still) need to ensure is as close to black as possible.  This will make
 | 
						|
     * the behaviour consistent across all chipsets, while allowing all
 | 
						|
     * chipsets to display the entire screen.  Non-KGA drivers can ignore the
 | 
						|
     * following in their own copy of this code.
 | 
						|
     *
 | 
						|
     * --  TSI @ UQV,  1998.08.21
 | 
						|
     */
 | 
						|
 | 
						|
CARD32
 | 
						|
vgaHWHBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits, 
 | 
						|
	       unsigned int Flags)
 | 
						|
{
 | 
						|
    int nExtBits = (nBits < 6) ? 0 : nBits - 6;
 | 
						|
    CARD32 ExtBits;
 | 
						|
    CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6;
 | 
						|
 | 
						|
    regp->CRTC[3]  = (regp->CRTC[3] & ~0x1F) 
 | 
						|
                     | (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F);
 | 
						|
    regp->CRTC[5]  = (regp->CRTC[5] & ~0x80) 
 | 
						|
                     | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2);
 | 
						|
    ExtBits        = ((mode->CrtcHBlankEnd >> 3) - 1) & ExtBitMask;
 | 
						|
 | 
						|
    /* First the horizontal case */
 | 
						|
    if ((Flags & KGA_FIX_OVERSCAN)
 | 
						|
	&& ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3)))
 | 
						|
    {
 | 
						|
	int i = (regp->CRTC[3] & 0x1F) 
 | 
						|
	    | ((regp->CRTC[5] & 0x80) >> 2)
 | 
						|
	    | ExtBits;
 | 
						|
	if (Flags & KGA_ENABLE_ON_ZERO) {
 | 
						|
	    if ((i-- > (((mode->CrtcHBlankStart >> 3) - 1) 
 | 
						|
		       & (0x3F | ExtBitMask)))
 | 
						|
	    && (mode->CrtcHBlankEnd == mode->CrtcHTotal))
 | 
						|
	    i = 0;
 | 
						|
	} else if (Flags & KGA_BE_TOT_DEC)
 | 
						|
	    i--;
 | 
						|
	regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) | (i & 0x1F);
 | 
						|
	regp->CRTC[5] = (regp->CRTC[5] & ~0x80) | ((i << 2) & 0x80);
 | 
						|
	ExtBits = i & ExtBitMask;
 | 
						|
    }
 | 
						|
    return ExtBits >> 6;
 | 
						|
}
 | 
						|
 | 
						|
    /*
 | 
						|
     * The vertical case is a little trickier.  Some VGA's ignore bit 0x80 of
 | 
						|
     * CRTC[22].  Also, in some cases, a zero CRTC[22] will still blank the
 | 
						|
     * very first scanline in a double- or multi-scanned mode.  This last case
 | 
						|
     * needs further investigation.
 | 
						|
     */
 | 
						|
CARD32
 | 
						|
vgaHWVBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits, 
 | 
						|
	       unsigned int Flags)
 | 
						|
{
 | 
						|
    CARD32 ExtBits;
 | 
						|
    CARD32 nExtBits = (nBits < 8) ? 0 : (nBits - 8);
 | 
						|
    CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 8;
 | 
						|
    /* If width is not known nBits should be 0. In this 
 | 
						|
     * case BitMask is set to 0 so we can check for it. */
 | 
						|
    CARD32 BitMask = (nBits < 7) ? 0 : ((1 << nExtBits) - 1);
 | 
						|
    int VBlankStart = (mode->CrtcVBlankStart - 1) & 0xFF; 
 | 
						|
    regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
 | 
						|
    ExtBits        = (mode->CrtcVBlankEnd - 1) & ExtBitMask;
 | 
						|
 | 
						|
    if ((Flags & KGA_FIX_OVERSCAN) 
 | 
						|
	&& (mode->CrtcVBlankEnd == mode->CrtcVTotal))
 | 
						|
      /* Null top overscan */
 | 
						|
    {
 | 
						|
	int i = regp->CRTC[22] | ExtBits;
 | 
						|
	if (Flags & KGA_ENABLE_ON_ZERO) {
 | 
						|
	    if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask)))
 | 
						|
	     || ((i > VBlankStart)  &&  		/* 8-bit case */
 | 
						|
	    ((i & 0x7F) > (VBlankStart & 0x7F)))) &&	/* 7-bit case */
 | 
						|
	    !(regp->CRTC[9] & 0x9F))			/* 1 scanline/row */
 | 
						|
	    i = 0;
 | 
						|
	else
 | 
						|
	    i = (i - 1);
 | 
						|
	} else if (Flags & KGA_BE_TOT_DEC)
 | 
						|
	    i = (i - 1);
 | 
						|
 | 
						|
	regp->CRTC[22] = i & 0xFF;
 | 
						|
	ExtBits = i & 0xFF00;
 | 
						|
    }
 | 
						|
    return ExtBits >> 8;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * these are some more hardware specific helpers, formerly in vga.c
 | 
						|
 */
 | 
						|
static void
 | 
						|
vgaHWGetHWRecPrivate(void)
 | 
						|
{
 | 
						|
    if (vgaHWPrivateIndex < 0)
 | 
						|
	vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
vgaHWFreeRegs(vgaRegPtr regp)
 | 
						|
{
 | 
						|
    free(regp->CRTC);
 | 
						|
 | 
						|
    regp->CRTC =
 | 
						|
    regp->Sequencer =
 | 
						|
    regp->Graphics =
 | 
						|
    regp->Attribute = NULL;
 | 
						|
 | 
						|
    regp->numCRTC =
 | 
						|
    regp->numSequencer =
 | 
						|
    regp->numGraphics =
 | 
						|
    regp->numAttribute = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
static Bool
 | 
						|
vgaHWAllocRegs(vgaRegPtr regp)
 | 
						|
{
 | 
						|
    unsigned char *buf;
 | 
						|
 | 
						|
    if ((regp->numCRTC + regp->numSequencer + regp->numGraphics +
 | 
						|
         regp->numAttribute) == 0)
 | 
						|
        return FALSE;
 | 
						|
 | 
						|
    buf = calloc(regp->numCRTC +
 | 
						|
    		  regp->numSequencer +
 | 
						|
		  regp->numGraphics +
 | 
						|
		  regp->numAttribute, 1);
 | 
						|
    if (!buf)
 | 
						|
    	return FALSE;
 | 
						|
 | 
						|
    regp->CRTC = buf;
 | 
						|
    regp->Sequencer = regp->CRTC + regp->numCRTC;
 | 
						|
    regp->Graphics = regp->Sequencer + regp->numSequencer;
 | 
						|
    regp->Attribute = regp->Graphics + regp->numGraphics;
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
vgaHWAllocDefaultRegs(vgaRegPtr regp)
 | 
						|
{
 | 
						|
    regp->numCRTC = VGA_NUM_CRTC;
 | 
						|
    regp->numSequencer = VGA_NUM_SEQ;
 | 
						|
    regp->numGraphics = VGA_NUM_GFX;
 | 
						|
    regp->numAttribute = VGA_NUM_ATTR;
 | 
						|
 | 
						|
    return vgaHWAllocRegs(regp);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
vgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer,
 | 
						|
		  int numGraphics, int numAttribute)
 | 
						|
{
 | 
						|
#define VGAHWMINNUM(regtype) \
 | 
						|
	((newMode.num##regtype < regp->num##regtype) ? \
 | 
						|
	 (newMode.num##regtype) : (regp->num##regtype))
 | 
						|
#define VGAHWCOPYREGSET(regtype) \
 | 
						|
	memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype))
 | 
						|
 | 
						|
    vgaRegRec newMode, newSaved;
 | 
						|
    vgaRegPtr regp;
 | 
						|
 | 
						|
    regp = &VGAHWPTR(scrp)->ModeReg;
 | 
						|
    memcpy (&newMode, regp, sizeof(vgaRegRec));
 | 
						|
 | 
						|
    /* allocate space for new registers */
 | 
						|
 | 
						|
    regp = &newMode;
 | 
						|
    regp->numCRTC = numCRTC;
 | 
						|
    regp->numSequencer = numSequencer;
 | 
						|
    regp->numGraphics = numGraphics;
 | 
						|
    regp->numAttribute = numAttribute;
 | 
						|
    if (!vgaHWAllocRegs(regp))
 | 
						|
    	return FALSE;
 | 
						|
 | 
						|
    regp = &VGAHWPTR(scrp)->SavedReg;
 | 
						|
    memcpy (&newSaved, regp, sizeof(vgaRegRec));
 | 
						|
 | 
						|
    regp = &newSaved;
 | 
						|
    regp->numCRTC = numCRTC;
 | 
						|
    regp->numSequencer = numSequencer;
 | 
						|
    regp->numGraphics = numGraphics;
 | 
						|
    regp->numAttribute = numAttribute;
 | 
						|
    if (!vgaHWAllocRegs(regp)) {
 | 
						|
        vgaHWFreeRegs(&newMode);
 | 
						|
    	return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    /* allocations succeeded, copy register data into new space */
 | 
						|
 | 
						|
    regp = &VGAHWPTR(scrp)->ModeReg;
 | 
						|
    VGAHWCOPYREGSET(CRTC);
 | 
						|
    VGAHWCOPYREGSET(Sequencer);
 | 
						|
    VGAHWCOPYREGSET(Graphics);
 | 
						|
    VGAHWCOPYREGSET(Attribute);
 | 
						|
 | 
						|
    regp = &VGAHWPTR(scrp)->SavedReg;
 | 
						|
    VGAHWCOPYREGSET(CRTC);
 | 
						|
    VGAHWCOPYREGSET(Sequencer);
 | 
						|
    VGAHWCOPYREGSET(Graphics);
 | 
						|
    VGAHWCOPYREGSET(Attribute);
 | 
						|
 | 
						|
    /* free old register arrays */
 | 
						|
 | 
						|
    regp = &VGAHWPTR(scrp)->ModeReg;
 | 
						|
    vgaHWFreeRegs(regp);
 | 
						|
    memcpy(regp, &newMode, sizeof(vgaRegRec));
 | 
						|
 | 
						|
    regp = &VGAHWPTR(scrp)->SavedReg;
 | 
						|
    vgaHWFreeRegs(regp);
 | 
						|
    memcpy(regp, &newSaved, sizeof(vgaRegRec));
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
 | 
						|
#undef VGAHWMINNUM
 | 
						|
#undef VGAHWCOPYREGSET
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)
 | 
						|
{
 | 
						|
    vgaHWFreeRegs(dst);
 | 
						|
 | 
						|
    memcpy(dst, src, sizeof(vgaRegRec));
 | 
						|
 | 
						|
    if (!vgaHWAllocRegs(dst))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    memcpy(dst->CRTC, src->CRTC, src->numCRTC);
 | 
						|
    memcpy(dst->Sequencer, src->Sequencer, src->numSequencer);
 | 
						|
    memcpy(dst->Graphics, src->Graphics, src->numGraphics);
 | 
						|
    memcpy(dst->Attribute, src->Attribute, src->numAttribute);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
vgaHWGetHWRec(ScrnInfoPtr scrp)
 | 
						|
{
 | 
						|
    vgaRegPtr regp;
 | 
						|
    vgaHWPtr hwp;
 | 
						|
    int i;
 | 
						|
    
 | 
						|
    /*
 | 
						|
     * Let's make sure that the private exists and allocate one.
 | 
						|
     */
 | 
						|
    vgaHWGetHWRecPrivate();
 | 
						|
    /*
 | 
						|
     * New privates are always set to NULL, so we can check if the allocation
 | 
						|
     * has already been done.
 | 
						|
     */
 | 
						|
    if (VGAHWPTR(scrp))
 | 
						|
	return TRUE;
 | 
						|
    hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1);
 | 
						|
    regp = &VGAHWPTR(scrp)->ModeReg;
 | 
						|
 | 
						|
    if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) ||
 | 
						|
    	(!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) {
 | 
						|
        free(hwp);
 | 
						|
	return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (scrp->bitsPerPixel == 1) {
 | 
						|
	rgb blackColour = scrp->display->blackColour,
 | 
						|
	    whiteColour = scrp->display->whiteColour;
 | 
						|
 | 
						|
	if (blackColour.red   > 0x3F) blackColour.red   = 0x3F;
 | 
						|
	if (blackColour.green > 0x3F) blackColour.green = 0x3F;
 | 
						|
	if (blackColour.blue  > 0x3F) blackColour.blue  = 0x3F;
 | 
						|
 | 
						|
	if (whiteColour.red   > 0x3F) whiteColour.red   = 0x3F;
 | 
						|
	if (whiteColour.green > 0x3F) whiteColour.green = 0x3F;
 | 
						|
	if (whiteColour.blue  > 0x3F) whiteColour.blue  = 0x3F;
 | 
						|
 | 
						|
	if ((blackColour.red   == whiteColour.red  ) &&
 | 
						|
	    (blackColour.green == whiteColour.green) &&
 | 
						|
	    (blackColour.blue  == whiteColour.blue )) {
 | 
						|
	    blackColour.red   ^= 0x3F;
 | 
						|
	    blackColour.green ^= 0x3F;
 | 
						|
	    blackColour.blue  ^= 0x3F;
 | 
						|
	}
 | 
						|
 | 
						|
        /*
 | 
						|
         * initialize default colormap for monochrome
 | 
						|
         */
 | 
						|
        for (i=0; i<3;   i++) regp->DAC[i] = 0x00;
 | 
						|
        for (i=3; i<768; i++) regp->DAC[i] = 0x3F;
 | 
						|
        i = BLACK_VALUE * 3;
 | 
						|
        regp->DAC[i++] = blackColour.red;
 | 
						|
        regp->DAC[i++] = blackColour.green;
 | 
						|
        regp->DAC[i] = blackColour.blue;
 | 
						|
        i = WHITE_VALUE * 3;
 | 
						|
        regp->DAC[i++] = whiteColour.red;
 | 
						|
        regp->DAC[i++] = whiteColour.green;
 | 
						|
        regp->DAC[i] = whiteColour.blue;
 | 
						|
        i = OVERSCAN_VALUE * 3;
 | 
						|
        regp->DAC[i++] = 0x00;
 | 
						|
        regp->DAC[i++] = 0x00;
 | 
						|
        regp->DAC[i] = 0x00;
 | 
						|
    } else {
 | 
						|
	/* Set all colours to black */
 | 
						|
        for (i=0; i<768; i++) regp->DAC[i] = 0x00;
 | 
						|
        /* ... and the overscan */
 | 
						|
        if (scrp->depth >= 4)
 | 
						|
            regp->Attribute[OVERSCAN] = 0xFF;
 | 
						|
    }
 | 
						|
    if (xf86FindOption(scrp->confScreen->options, "ShowOverscan")) {
 | 
						|
	xf86MarkOptionUsedByName(scrp->confScreen->options, "ShowOverscan");
 | 
						|
	xf86DrvMsg(scrp->scrnIndex, X_CONFIG, "Showing overscan area\n");
 | 
						|
	regp->DAC[765] = 0x3F; 
 | 
						|
	regp->DAC[766] = 0x00; 
 | 
						|
	regp->DAC[767] = 0x3F; 
 | 
						|
	regp->Attribute[OVERSCAN] = 0xFF;
 | 
						|
	hwp->ShowOverscan = TRUE;
 | 
						|
    } else
 | 
						|
	hwp->ShowOverscan = FALSE;
 | 
						|
 | 
						|
    hwp->paletteEnabled = FALSE;
 | 
						|
    hwp->cmapSaved = FALSE;
 | 
						|
    hwp->MapSize = 0;
 | 
						|
    hwp->pScrn = scrp;
 | 
						|
 | 
						|
    hwp->dev = xf86GetPciInfoForEntity(scrp->entityList[0]);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWFreeHWRec(ScrnInfoPtr scrp)
 | 
						|
{
 | 
						|
    if (vgaHWPrivateIndex >= 0) {
 | 
						|
	vgaHWPtr hwp = VGAHWPTR(scrp);
 | 
						|
 | 
						|
	if (!hwp)
 | 
						|
            return;
 | 
						|
 | 
						|
        pci_device_close_io(hwp->dev, hwp->io);
 | 
						|
 | 
						|
	free(hwp->FontInfo1);
 | 
						|
	free(hwp->FontInfo2);
 | 
						|
	free(hwp->TextInfo);
 | 
						|
 | 
						|
	vgaHWFreeRegs (&hwp->ModeReg);
 | 
						|
	vgaHWFreeRegs (&hwp->SavedReg);
 | 
						|
 | 
						|
	free(hwp);
 | 
						|
	VGAHWPTRLVAL(scrp) = NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
vgaHWMapMem(ScrnInfoPtr scrp)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(scrp);
 | 
						|
    
 | 
						|
    if (hwp->Base)
 | 
						|
	return TRUE;
 | 
						|
 | 
						|
    /* If not set, initialise with the defaults */
 | 
						|
    if (hwp->MapSize == 0)
 | 
						|
	hwp->MapSize = VGA_DEFAULT_MEM_SIZE;
 | 
						|
    if (hwp->MapPhys == 0)
 | 
						|
	hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Map as VIDMEM_MMIO_32BIT because WC
 | 
						|
     * is bad when there is page flipping.
 | 
						|
     * XXX This is not correct but we do it
 | 
						|
     * for now.
 | 
						|
     */
 | 
						|
    DebugF("Mapping VGAMem\n");
 | 
						|
    pci_device_map_legacy(hwp->dev, hwp->MapPhys, hwp->MapSize, PCI_DEV_MAP_FLAG_WRITABLE, &hwp->Base);
 | 
						|
    return hwp->Base != NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWUnmapMem(ScrnInfoPtr scrp)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(scrp);
 | 
						|
 | 
						|
    if (hwp->Base == NULL)
 | 
						|
	return;
 | 
						|
    
 | 
						|
    DebugF("Unmapping VGAMem\n");
 | 
						|
    pci_device_unmap_legacy(hwp->dev, hwp->Base, hwp->MapSize);
 | 
						|
    hwp->Base = NULL;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
vgaHWGetIndex(void)
 | 
						|
{
 | 
						|
    return vgaHWPrivateIndex;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWGetIOBase(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    hwp->IOBase = (hwp->readMiscOut(hwp) & 0x01) ?
 | 
						|
				VGA_IOBASE_COLOR : VGA_IOBASE_MONO;
 | 
						|
    xf86DrvMsgVerb(hwp->pScrn->scrnIndex, X_INFO, 3,
 | 
						|
	"vgaHWGetIOBase: hwp->IOBase is 0x%04x\n", hwp->IOBase);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWLock(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    /* Protect CRTC[0-7] */
 | 
						|
    hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
vgaHWUnlock(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    /* Unprotect CRTC[0-7] */
 | 
						|
     hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWEnable(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    hwp->writeEnable(hwp, hwp->readEnable(hwp) | 0x01);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaHWDisable(vgaHWPtr hwp)
 | 
						|
{
 | 
						|
    hwp->writeEnable(hwp, hwp->readEnable(hwp) & ~0x01);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
vgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
 | 
						|
		 VisualPtr pVisual)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(pScrn);
 | 
						|
    int i, index;
 | 
						|
 | 
						|
    for (i = 0; i < numColors; i++) {
 | 
						|
	index = indices[i];
 | 
						|
	hwp->writeDacWriteAddr(hwp, index);
 | 
						|
	DACDelay(hwp);
 | 
						|
	hwp->writeDacData(hwp, colors[index].red);
 | 
						|
	DACDelay(hwp);
 | 
						|
	hwp->writeDacData(hwp, colors[index].green);
 | 
						|
	DACDelay(hwp);
 | 
						|
	hwp->writeDacData(hwp, colors[index].blue);
 | 
						|
	DACDelay(hwp);
 | 
						|
    }
 | 
						|
 | 
						|
    /* This shouldn't be necessary, but we'll play safe. */
 | 
						|
    hwp->disablePalette(hwp);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
vgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(pScrn);
 | 
						|
 | 
						|
    if (overscan < 0 || overscan > 255)
 | 
						|
	return;
 | 
						|
 | 
						|
    hwp->enablePalette(hwp);
 | 
						|
    hwp->writeAttr(hwp, OVERSCAN, overscan);
 | 
						|
 | 
						|
#ifdef DEBUGOVERSCAN
 | 
						|
    {
 | 
						|
	int ov = hwp->readAttr(hwp, OVERSCAN);
 | 
						|
	int red, green, blue;
 | 
						|
 | 
						|
	hwp->writeDacReadAddr(hwp, ov);
 | 
						|
	red = hwp->readDacData(hwp);
 | 
						|
	green = hwp->readDacData(hwp);
 | 
						|
	blue = hwp->readDacData(hwp);
 | 
						|
	ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n",
 | 
						|
		ov, red, green, blue);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    hwp->disablePalette(hwp);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
vgaHWHandleColormaps(ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 | 
						|
 | 
						|
    if (pScrn->depth > 1 && pScrn->depth <= 8) {
 | 
						|
	return xf86HandleColormaps(pScreen, 1 << pScrn->depth,
 | 
						|
				   pScrn->rgbBits, vgaHWLoadPalette,
 | 
						|
				   pScrn->depth > 4 ? vgaHWSetOverscan : NULL,
 | 
						|
				   CMAP_RELOAD_ON_MODE_SWITCH);
 | 
						|
    }
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/* ----------------------- DDC support ------------------------*/
 | 
						|
/* 
 | 
						|
 * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total
 | 
						|
 * to read out EDID at a faster rate. Allowed maximum is 25kHz with
 | 
						|
 * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen
 | 
						|
 * readback, enable access to cr00-cr07.
 | 
						|
 */
 | 
						|
 | 
						|
/* vertical timings */
 | 
						|
#define DISPLAY_END 0x04
 | 
						|
#define BLANK_START DISPLAY_END
 | 
						|
#define SYNC_START BLANK_START
 | 
						|
#define SYNC_END 0x09
 | 
						|
#define BLANK_END SYNC_END
 | 
						|
#define V_TOTAL BLANK_END
 | 
						|
/* this function doesn't have to be reentrant for our purposes */
 | 
						|
struct _vgaDdcSave {
 | 
						|
    unsigned char cr03;
 | 
						|
    unsigned char cr06;
 | 
						|
    unsigned char cr07;
 | 
						|
    unsigned char cr09;
 | 
						|
    unsigned char cr10;
 | 
						|
    unsigned char cr11;
 | 
						|
    unsigned char cr12;
 | 
						|
    unsigned char cr15;
 | 
						|
    unsigned char cr16;
 | 
						|
    unsigned char msr;
 | 
						|
};
 | 
						|
 | 
						|
void
 | 
						|
vgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed)
 | 
						|
{
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(pScrn);
 | 
						|
    unsigned char tmp;
 | 
						|
    struct _vgaDdcSave* save;
 | 
						|
    switch (speed) {
 | 
						|
    case DDC_FAST:
 | 
						|
        
 | 
						|
        if (hwp->ddc != NULL) break;
 | 
						|
        hwp->ddc = xnfcalloc(sizeof(struct _vgaDdcSave),1);
 | 
						|
	save = (struct _vgaDdcSave *)hwp->ddc;
 | 
						|
      /* Lightpen register disable - allow access to cr10 & 11; just in case */
 | 
						|
	save->cr03 = hwp->readCrtc(hwp, 0x03); 
 | 
						|
	hwp->writeCrtc(hwp,0x03,(save->cr03 |0x80));
 | 
						|
	save->cr12 = hwp->readCrtc(hwp, 0x12); 
 | 
						|
	hwp->writeCrtc(hwp,0x12,DISPLAY_END);
 | 
						|
	save->cr15 = hwp->readCrtc(hwp, 0x15); 
 | 
						|
	hwp->writeCrtc(hwp,0x15,BLANK_START);
 | 
						|
	save->cr10 = hwp->readCrtc(hwp, 0x10); 
 | 
						|
	hwp->writeCrtc(hwp,0x10,SYNC_START);
 | 
						|
	save->cr11 = hwp->readCrtc(hwp, 0x11); 
 | 
						|
	/* unprotect group 1 registers; just in case ...*/
 | 
						|
	hwp->writeCrtc(hwp,0x11,((save->cr11 & 0x70) | SYNC_END));
 | 
						|
	save->cr16 = hwp->readCrtc(hwp, 0x16); 
 | 
						|
	hwp->writeCrtc(hwp,0x16,BLANK_END);
 | 
						|
	save->cr06 = hwp->readCrtc(hwp, 0x06); 
 | 
						|
	hwp->writeCrtc(hwp,0x06,V_TOTAL);
 | 
						|
	/* all values have less than 8 bit - mask out 9th and 10th bits */
 | 
						|
	save->cr09 = hwp->readCrtc(hwp, 0x09); 
 | 
						|
	hwp->writeCrtc(hwp,0x09,(save->cr09 &0xDF));
 | 
						|
	save->cr07 = hwp->readCrtc(hwp, 0x07); 
 | 
						|
	hwp->writeCrtc(hwp,0x07,(save->cr07 &0x10));
 | 
						|
	/* vsync polarity negativ & ensure a 25MHz clock */
 | 
						|
	save->msr = hwp->readMiscOut(hwp); 
 | 
						|
	hwp->writeMiscOut(hwp,((save->msr & 0xF3) | 0x80));
 | 
						|
	break;
 | 
						|
    case DDC_SLOW:
 | 
						|
        if (hwp->ddc == NULL) break;
 | 
						|
	save = (struct _vgaDdcSave *)hwp->ddc;
 | 
						|
	hwp->writeMiscOut(hwp,save->msr);
 | 
						|
	hwp->writeCrtc(hwp,0x07,save->cr07);
 | 
						|
	tmp = hwp->readCrtc(hwp, 0x09);
 | 
						|
	hwp->writeCrtc(hwp,0x09,((save->cr09 & 0x20) | (tmp & 0xDF)));
 | 
						|
	hwp->writeCrtc(hwp,0x06,save->cr06);
 | 
						|
	hwp->writeCrtc(hwp,0x16,save->cr16);
 | 
						|
	hwp->writeCrtc(hwp,0x11,save->cr11);
 | 
						|
	hwp->writeCrtc(hwp,0x10,save->cr10);
 | 
						|
	hwp->writeCrtc(hwp,0x15,save->cr15);
 | 
						|
	hwp->writeCrtc(hwp,0x12,save->cr12);
 | 
						|
	hwp->writeCrtc(hwp,0x03,save->cr03);
 | 
						|
	free(save);
 | 
						|
	hwp->ddc = NULL;
 | 
						|
	break;
 | 
						|
    default:
 | 
						|
	break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
DDC1SetSpeedProc
 | 
						|
vgaHWddc1SetSpeedWeak(void)
 | 
						|
{
 | 
						|
    return vgaHWddc1SetSpeed;
 | 
						|
}
 | 
						|
 | 
						|
SaveScreenProcPtr vgaHWSaveScreenWeak(void)
 | 
						|
{
 | 
						|
    return vgaHWSaveScreen;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
 | 
						|
 */
 | 
						|
void
 | 
						|
xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
 | 
						|
	      void (*ProtectRegs)(ScrnInfoPtr, Bool),
 | 
						|
	      void (*BlankScreen)(ScrnInfoPtr, Bool), unsigned long vertsyncreg,
 | 
						|
	      int maskval, int knownclkindex, int knownclkvalue)
 | 
						|
{
 | 
						|
    register int status = vertsyncreg;
 | 
						|
    unsigned long i, cnt, rcnt, sync;
 | 
						|
    vgaHWPtr hwp = VGAHWPTR(pScrn);
 | 
						|
 | 
						|
    /* First save registers that get written on */
 | 
						|
    (*ClockFunc)(pScrn, CLK_REG_SAVE);
 | 
						|
 | 
						|
    if (num > MAXCLOCKS)
 | 
						|
	num = MAXCLOCKS;
 | 
						|
 | 
						|
    for (i = 0; i < num; i++)
 | 
						|
    {
 | 
						|
	if (ProtectRegs)
 | 
						|
	    (*ProtectRegs)(pScrn, TRUE);
 | 
						|
	if (!(*ClockFunc)(pScrn, i))
 | 
						|
	{
 | 
						|
	    pScrn->clock[i] = -1;
 | 
						|
	    continue;
 | 
						|
	}
 | 
						|
	if (ProtectRegs)
 | 
						|
	    (*ProtectRegs)(pScrn, FALSE);
 | 
						|
	if (BlankScreen)
 | 
						|
	    (*BlankScreen)(pScrn, FALSE);
 | 
						|
 | 
						|
	usleep(50000);     /* let VCO stabilise */
 | 
						|
 | 
						|
	cnt  = 0;
 | 
						|
	sync = 200000;
 | 
						|
 | 
						|
	while ((pci_io_read8(hwp->io, status) & maskval) == 0x00)
 | 
						|
	    if (sync-- == 0) goto finish;
 | 
						|
	/* Something appears to be happening, so reset sync count */
 | 
						|
	sync = 200000;
 | 
						|
	while ((pci_io_read8(hwp->io, status) & maskval) == maskval)
 | 
						|
	    if (sync-- == 0) goto finish;
 | 
						|
	/* Something appears to be happening, so reset sync count */
 | 
						|
	sync = 200000;
 | 
						|
	while ((pci_io_read8(hwp->io, status) & maskval) == 0x00)
 | 
						|
	    if (sync-- == 0) goto finish;
 | 
						|
 | 
						|
	for (rcnt = 0; rcnt < 5; rcnt++)
 | 
						|
	{
 | 
						|
	    while (!(pci_io_read8(hwp->io, status) & maskval))
 | 
						|
		cnt++;
 | 
						|
	    while ((pci_io_read8(hwp->io, status) & maskval))
 | 
						|
		cnt++;
 | 
						|
	}
 | 
						|
 | 
						|
finish:
 | 
						|
	pScrn->clock[i] = cnt ? cnt : -1;
 | 
						|
	if (BlankScreen)
 | 
						|
            (*BlankScreen)(pScrn, TRUE);
 | 
						|
    }
 | 
						|
 | 
						|
    for (i = 0; i < num; i++)
 | 
						|
    {
 | 
						|
	if (i != knownclkindex)
 | 
						|
	{
 | 
						|
	    if (pScrn->clock[i] == -1)
 | 
						|
	    {
 | 
						|
		pScrn->clock[i] = 0;
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
		pScrn->clock[i] = (int)(0.5 +
 | 
						|
                    (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
 | 
						|
	            (pScrn->clock[i]));
 | 
						|
		/* Round to nearest 10KHz */
 | 
						|
		pScrn->clock[i] += 5;
 | 
						|
		pScrn->clock[i] /= 10;
 | 
						|
		pScrn->clock[i] *= 10;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    pScrn->clock[knownclkindex] = knownclkvalue;
 | 
						|
    pScrn->numClocks = num;
 | 
						|
 | 
						|
    /* Restore registers that were written on */
 | 
						|
    (*ClockFunc)(pScrn, CLK_REG_RESTORE);
 | 
						|
}
 |