diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:17:52 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:17:52 +0000 |
commit | 6d2232c8c34f073b89dd6ffc7d3fc8271b54c1af (patch) | |
tree | a070d1b63573408fc18ecd6a579c8cddc31e18eb /driver/xf86-video-tga/src | |
parent | 116b30d877cd710a9626fd8540ea476f4ddb95a1 (diff) |
Importing xf86-video-tga 1.1.0
Diffstat (limited to 'driver/xf86-video-tga/src')
-rw-r--r-- | driver/xf86-video-tga/src/BT463ramdac.c | 143 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/BTramdac.c | 181 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/IBM561ramdac.c | 738 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/ICS1562.c | 118 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/Makefile.am | 47 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/Makefile.in | 536 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/tga.h | 219 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/tga_accel.c | 1572 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/tga_cursor.c | 188 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/tga_dac.c | 849 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/tga_driver.c | 1767 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/tga_line.c | 632 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/tga_regs.h | 216 | ||||
-rw-r--r-- | driver/xf86-video-tga/src/tga_seg.c | 2 |
14 files changed, 7208 insertions, 0 deletions
diff --git a/driver/xf86-video-tga/src/BT463ramdac.c b/driver/xf86-video-tga/src/BT463ramdac.c new file mode 100644 index 000000000..c723727d7 --- /dev/null +++ b/driver/xf86-video-tga/src/BT463ramdac.c @@ -0,0 +1,143 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "BT.h" +#include "tga_regs.h" +#include "tga.h" + + +#define BT463_LOAD_ADDR(a) \ + TGA_WRITE_REG(BT463_ADDR_LO<<2, TGA_RAMDAC_SETUP_REG); \ + TGA_WRITE_REG((BT463_ADDR_LO<<10)|((a)&0xff), TGA_RAMDAC_REG); \ + TGA_WRITE_REG(BT463_ADDR_HI<<2, TGA_RAMDAC_SETUP_REG); \ + TGA_WRITE_REG((BT463_ADDR_HI<<10)|(((a)>>8)&0xff), TGA_RAMDAC_REG); + +#define BT463_WRITE(m,a,v) \ + BT463_LOAD_ADDR((a)); \ + TGA_WRITE_REG(((m)<<2),TGA_RAMDAC_SETUP_REG); \ + TGA_WRITE_REG(((m)<<10)|((v)&0xff),TGA_RAMDAC_REG); + +/* + * useful defines for managing the BT463 on the 24-plane TGAs + */ +#define BT463_READ_BIT 0x2 + +#define BT463_ADDR_LO 0x0 +#define BT463_ADDR_HI 0x1 +#define BT463_REG_ACC 0x2 +#define BT463_PALETTE 0x3 + +#define BT463_CUR_CLR_0 0x0100 +#define BT463_CUR_CLR_1 0x0101 + +#define BT463_CMD_REG_0 0x0201 +#define BT463_CMD_REG_1 0x0202 +#define BT463_CMD_REG_2 0x0203 + +#define BT463_READ_MASK_0 0x0205 +#define BT463_READ_MASK_1 0x0206 +#define BT463_READ_MASK_2 0x0207 +#define BT463_READ_MASK_3 0x0208 + +#define BT463_BLINK_MASK_0 0x0209 +#define BT463_BLINK_MASK_1 0x020a +#define BT463_BLINK_MASK_2 0x020b +#define BT463_BLINK_MASK_3 0x020c + +#define BT463_WINDOW_TYPE_BASE 0x0300 + + +static unsigned +BT463_READ(TGAPtr pTga, unsigned m, unsigned a) +{ + unsigned val; + + BT463_LOAD_ADDR(a); + TGA_WRITE_REG((m<<2)|0x2, TGA_RAMDAC_SETUP_REG); + val = TGA_READ_REG(TGA_RAMDAC_REG); + val = (val >> 16) & 0xff; + return val; +} + + +void +BT463ramdacSave(ScrnInfoPtr pScrn, unsigned char *Bt463) +{ + TGAPtr pTga = TGAPTR(pScrn); + int i, j; + + Bt463[0] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_0); + Bt463[1] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_1); + Bt463[2] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_2); + + Bt463[3] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_0); + Bt463[4] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_1); + Bt463[5] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_2); + Bt463[6] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_3); + + Bt463[7] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_0); + Bt463[8] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_1); + Bt463[9] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_2); + Bt463[10] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_3); + + BT463_LOAD_ADDR(BT463_WINDOW_TYPE_BASE); + TGA_WRITE_REG((BT463_REG_ACC<<2)|0x2, TGA_RAMDAC_SETUP_REG); + + for (i = 0, j = 11; i < 16; i++) { + Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff; + Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff; + Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff; + } + +/* + fprintf(stderr, "BT463ramdacSave (%p)\n", Bt463); + for (i=0; i<58; i++) + fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Bt463[i]); +*/ +} + + +void +BT463ramdacRestore(ScrnInfoPtr pScrn, unsigned char *Bt463) +{ + TGAPtr pTga = TGAPTR(pScrn); + int i, j; + + BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_0, Bt463[0]); + BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_1, Bt463[1]); + BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_2, Bt463[2]); + + BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_0, Bt463[3]); + BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_1, Bt463[4]); + BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_2, Bt463[5]); + BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_3, Bt463[6]); + + BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_0, Bt463[7]); + BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_1, Bt463[8]); + BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_2, Bt463[9]); + BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_3, Bt463[10]); + + BT463_LOAD_ADDR(BT463_WINDOW_TYPE_BASE); + TGA_WRITE_REG((BT463_REG_ACC<<2), TGA_RAMDAC_SETUP_REG); + + for (i = 0, j = 11; i < 16; i++) { + TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); + TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); + TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); + } + +/* + fprintf(stderr, "BT463ramdacRestore (%p)\n", Bt463); + for (i=0; i<58; i++) + fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Bt463[i]); +*/ +} diff --git a/driver/xf86-video-tga/src/BTramdac.c b/driver/xf86-video-tga/src/BTramdac.c new file mode 100644 index 000000000..ceab49dcf --- /dev/null +++ b/driver/xf86-video-tga/src/BTramdac.c @@ -0,0 +1,181 @@ +/* + * Copyright 1998 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * tgaBTOutIndReg() and tgaBTInIndReg() are used to access + * the indirect TGA BT RAMDAC registers only. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/BTramdac.c,v 1.4 1999/02/07 11:11:14 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "tga_regs.h" +#include "BT.h" +#include "tga.h" + +void +tgaBTOutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data) +{ + TGAPtr pTga; + unsigned char tmp = 0x00; + + pTga = TGAPTR(pScrn); + + TGA_WRITE_REG(reg << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG); + + if (mask != 0x00) + tmp = (TGA_READ_REG(TGA_RAMDAC_REG)>>16) & mask; + + TGA_WRITE_REG(reg << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG); + + TGA_WRITE_REG ((tmp | data) | (reg<<9), TGA_RAMDAC_REG); +} + +unsigned char +tgaBTInIndReg (ScrnInfoPtr pScrn, CARD32 reg) +{ + TGAPtr pTga; + unsigned char ret; + + pTga = TGAPTR(pScrn); + + TGA_WRITE_REG(reg << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG); + ret = TGA_READ_REG (TGA_RAMDAC_REG)>>16; + + return (ret); +} + +void +tgaBTWriteAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + TGAPtr pTga; + + pTga = TGAPTR(pScrn); + + TGA_WRITE_REG(BT_WRITE_ADDR << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG); + TGA_WRITE_REG(index | (BT_WRITE_ADDR<<9), TGA_RAMDAC_REG); + TGA_WRITE_REG(BT_RAMDAC_DATA << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG); +} + +void +tgaBTWriteData (ScrnInfoPtr pScrn, unsigned char data) +{ + TGAPtr pTga; + + pTga = TGAPTR(pScrn); + + TGA_WRITE_REG(data | (BT_RAMDAC_DATA << 9), TGA_RAMDAC_REG); +} + +void +tgaBTReadAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + TGAPtr pTga; + + pTga = TGAPTR(pScrn); + + TGA_WRITE_REG(BT_PIXEL_MASK << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG); + TGA_WRITE_REG(0xFF | (BT_PIXEL_MASK<<9), TGA_RAMDAC_REG); + TGA_WRITE_REG(BT_READ_ADDR << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG); + TGA_WRITE_REG(index | (BT_READ_ADDR<<9), TGA_RAMDAC_REG); + TGA_WRITE_REG(BT_RAMDAC_DATA << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG); +} + +unsigned char +tgaBTReadData (ScrnInfoPtr pScrn) +{ + TGAPtr pTga; + + pTga = TGAPTR(pScrn); + + return(TGA_READ_REG(TGA_RAMDAC_REG)>>16); +} + +/********************* TGA2 stuff below here ********************/ + +void +tga2BTOutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data) +{ + TGAPtr pTga; + unsigned char tmp = 0x00; + unsigned int addr = 0xe000U | (reg << 8); + + pTga = TGAPTR(pScrn); + + if (mask != 0x00) + tmp = TGA2_READ_RAMDAC_REG(addr) & mask; + +#if 0 + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "tga2OutIndReg: reg 0x%x data 0x%x\n", + reg, tmp|data); +#endif + TGA2_WRITE_RAMDAC_REG ((tmp | data), addr); +} + +unsigned char +tga2BTInIndReg (ScrnInfoPtr pScrn, CARD32 reg) +{ + TGAPtr pTga; + unsigned char ret; + unsigned int addr = 0xe000U | (reg << 8); + + pTga = TGAPTR(pScrn); + + ret = TGA2_READ_RAMDAC_REG(addr); + + return (ret); +} + +void +tga2BTWriteAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + tga2BTOutIndReg(pScrn, BT_WRITE_ADDR, 0, index); +} + +void +tga2BTWriteData (ScrnInfoPtr pScrn, unsigned char data) +{ + tga2BTOutIndReg(pScrn, BT_RAMDAC_DATA, 0, data); +} + +void +tga2BTReadAddress (ScrnInfoPtr pScrn, CARD32 index) +{ + tga2BTOutIndReg(pScrn, BT_PIXEL_MASK, 0, 0xff); + tga2BTOutIndReg(pScrn, BT_READ_ADDR, 0, index); +} + +unsigned char +tga2BTReadData (ScrnInfoPtr pScrn) +{ + return tga2BTInIndReg(pScrn, BT_RAMDAC_DATA); +} diff --git a/driver/xf86-video-tga/src/IBM561ramdac.c b/driver/xf86-video-tga/src/IBM561ramdac.c new file mode 100644 index 000000000..f8b49317f --- /dev/null +++ b/driver/xf86-video-tga/src/IBM561ramdac.c @@ -0,0 +1,738 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/IBM561ramdac.c,v 1.3 2001/02/15 11:03:58 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "tga_regs.h" +#include "tga.h" + +/* + * useful defines for managing the IBM561 on the 24-plane TGA2s + */ + +#define IBM561_HEAD_MASK 0x01 +#define IBM561_READ 0x02 +#define IBM561_WRITE 0x00 + +#define RAMDAC_ONE_BYTE 0x0E000 +#define RAMDAC_TWO_BYTES 0x0c000 +#define RAMDAC_THREE_BYTES 0x08000 +#define RAMDAC_FOUR_BYTES 0x00000 + +#define IBM561_ADDR_LOW 0x0000 +#define IBM561_ADDR_HIGH 0x0100 +#define IBM561_CMD_REGS 0x0200 + +#define IBM561_CMD_CURS_PIX 0x0200 +#define IBM561_CMD_CURS_LUT 0x0300 +#define IBM561_CMD_FB_WAT 0x0300 +#define IBM561_CMD_AUXFB_WAT 0x0200 +#define IBM561_CMD_OL_WAT 0x0300 +#define IBM561_CMD_AUXOL_WAT 0x0200 +#define IBM561_CMD_GAMMA 0x0300 +#define IBM561_CMD_CMAP 0x0300 + +#define IBM561_ADDR_EPSR_SHIFT 0 +#define IBM561_ADDR_EPDR_SHIFT 8 + +#define IBM561_CONFIG_REG_1 0x0001 +#define IBM561_CONFIG_REG_2 0x0002 +#define IBM561_CONFIG_REG_1 0x0001 +#define IBM561_CONFIG_REG_2 0x0002 +#define IBM561_CONFIG_REG_3 0x0003 +#define IBM561_CONFIG_REG_4 0x0004 +#define IBM561_WAT_SEG_REG 0x0006 +#define IBM561_OL_SEG_REG 0x0007 +#define IBM561_CHROMA_KEY_REG0 0x0010 +#define IBM561_CHROMA_KEY_REG1 0x0011 +#define IBM561_CHROMA_MASK_REG0 0x0012 +#define IBM561_CHROMA_MASK_REG1 0x0013 +#define IBM561_SYNC_CONTROL 0x0020 +#define IBM561_PLL_VCO_DIV_REG 0x0021 +#define IBM561_PLL_REF_REG 0x0022 +#define IBM561_CURSOR_CTRL_REG 0x0030 +#define IBM561_CURSOR_HS_REG 0x0034 +#define IBM561_VRAM_MASK_REG 0x0050 +#define IBM561_DAC_CTRL 0x005f +#define IBM561_DIV_DOT_CLK_REG 0x0082 + +#define IBM561_READ_MASK 0x0205 +#define IBM561_BLINK_MASK 0x0209 +#define IBM561_FB_WINDOW_TYPE_TABLE 0x1000 +#define IBM561_AUXFB_WINDOW_TYPE_TABLE 0x0E00 +#define IBM561_OL_WINDOW_TYPE_TABLE 0x1400 +#define IBM561_AUXOL_WINDOW_TYPE_TABLE 0x0F00 +#define IBM561_RED_GAMMA_TABLE 0x3000 +#define IBM561_GREEN_GAMMA_TABLE 0x3400 +#define IBM561_BLUE_GAMMA_TABLE 0x3800 +#define IBM561_COLOR_LOOKUP_TABLE 0x4000 +#define IBM561_CURSOR_LOOKUP_TABLE 0x0a11 +#define IBM561_CURSOR_BLINK_TABLE 0x0a15 +#define IBM561_CROSS_LOOKUP_TABLE 0x0a19 +#define IBM561_CROSS_BLINK_TABLE 0x0a1d +#define IBM561_CURSOR_PIXMAP 0x2000 +#define IBM561_CURSOR_X_LOW 0x0036 +#define IBM561_CURSOR_X_HIGH 0x0037 +#define IBM561_CURSOR_Y_LOW 0x0038 +#define IBM561_CURSOR_Y_HIGH 0x0039 + +#define LO_ADDR (IBM561_ADDR_LOW | RAMDAC_ONE_BYTE) +#define HI_ADDR (IBM561_ADDR_HIGH | RAMDAC_ONE_BYTE) + +#define REGS_ADDR (IBM561_CMD_REGS | RAMDAC_ONE_BYTE) +#define FBWAT_ADDR (IBM561_CMD_FB_WAT | RAMDAC_ONE_BYTE) +#define AUXFBWAT_ADDR (IBM561_CMD_AUXFB_WAT | RAMDAC_ONE_BYTE) +#define OLWAT_ADDR (IBM561_CMD_OL_WAT | RAMDAC_ONE_BYTE) +#define AUXOLWAT_ADDR (IBM561_CMD_AUXOL_WAT | RAMDAC_ONE_BYTE) +#define CMAP_ADDR (IBM561_CMD_CMAP | RAMDAC_ONE_BYTE) +#define GAMMA_ADDR (IBM561_CMD_GAMMA | RAMDAC_ONE_BYTE) + +#define IBM561LoadAddr(reg) \ +do { \ + TGA2_WRITE_RAMDAC_REG((reg), LO_ADDR); \ + TGA2_WRITE_RAMDAC_REG((reg) >> 8, HI_ADDR); \ +} while (0) + +unsigned char +IBM561ReadReg(ScrnInfoPtr pScrn, CARD32 reg) +{ + TGAPtr pTga; + unsigned char ret; + + pTga = TGAPTR(pScrn); + + TGA2_WRITE_RAMDAC_REG(reg, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(reg >> 8, HI_ADDR); + + ret = TGA2_READ_RAMDAC_REG(REGS_ADDR); + +#if 1 + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "IBM561ReadReg: reg 0x%lx data 0x%x\n", + (unsigned long)reg, ret); +#endif + return (ret); +} + +void +IBM561WriteReg(ScrnInfoPtr pScrn, CARD32 reg, +#if 0 + unsigned char mask, unsigned char data) +#else + unsigned char data) +#endif +{ + TGAPtr pTga; + unsigned char tmp = 0x00; + + pTga = TGAPTR(pScrn); + +#if 0 + if (mask != 0x00) { + TGA2_WRITE_RAMDAC_REG(reg, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(reg >> 8, HI_ADDR); + tmp = TGA2_READ_RAMDAC_REG(REGS_ADDR) & mask; + } +#endif + +#if 1 + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "IBM561WriteReg: reg 0x%lx data 0x%x\n", + (unsigned long)reg, tmp | data); +#endif + + TGA2_WRITE_RAMDAC_REG(reg, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(reg >> 8, HI_ADDR); + TGA2_WRITE_RAMDAC_REG ((tmp | data), REGS_ADDR); +} + +void +IBM561ramdacSave(ScrnInfoPtr pScrn, unsigned char *Ibm561) +{ +#if 0 + TGAPtr pTga = TGAPTR(pScrn); + int i, j; + + /* ?? FIXME OR NOT this is from BT463ramdacSave ?? */ + Ibm561[0] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_CMD_REG_0); + Ibm561[1] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_CMD_REG_1); + Ibm561[2] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_CMD_REG_2); + + Ibm561[3] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_READ_MASK_0); + Ibm561[4] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_READ_MASK_1); + Ibm561[5] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_READ_MASK_2); + Ibm561[6] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_READ_MASK_3); + + Ibm561[7] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_BLINK_MASK_0); + Ibm561[8] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_BLINK_MASK_1); + Ibm561[9] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_BLINK_MASK_2); + Ibm561[10] = IBM561_READ(pTga, IBM561_REG_ACC, IBM561_BLINK_MASK_3); + + IBM561_LOAD_ADDR(IBM561_WINDOW_TYPE_BASE); + TGA_WRITE_REG((IBM561_REG_ACC<<2)|0x2, TGA_RAMDAC_SETUP_REG); + + for (i = 0, j = 11; i < 16; i++) { + Ibm561[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff; + Ibm561[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff; + Ibm561[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff; + } +#endif + +/* + fprintf(stderr, "IBM561ramdacSave (%p)\n", Ibm561); + for (i=0; i<58; i++) + fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Ibm561[i]); +*/ +} + +static void +IBM561WindowTagsInit(ScrnInfoPtr pScrn) +{ + TGAPtr pTga = TGAPTR(pScrn); + unsigned char low, high; + int i; + +/* + tga.h defines fb_wid_cell_t as a structure containing two bytes, + low and high in order. The 561 has 10 bit window tags so only + part of the high byte is used (actually only 2 bits). Pixel C for + 8-plane indexes uses 16bpp indexing per IBM's application notes + which describe quad bufering. Note, this array is arranged as + low byte followed by high byte which will apppear backwards + relative to the 561 spec( a value of 0x01 in the high byte + really represents a color table starting address of 256). + ex (entry 4): + {0x28, 0x01}, *4 8-plane index (PIXEL C 561 H/W screw-up) * + low byte = 0x28 + high byte = 0x01 + wat entry = 0x0128 + + from the spec: 8 in the low nibble selects buffer 1 + 2 in the next nibble selects pixformat of 16 bpp + 1 in the next nibble indicates a start addr of 256 +*/ +typedef struct { + unsigned char low_byte; + unsigned char high_byte; +}fb_wid_cell_t; + +typedef struct { + unsigned char aux_fbwat; +} aux_fb_wid_cell_t; + +typedef struct { + unsigned char low_byte; + unsigned char high_byte; +} ol_wid_cell_t; + +typedef struct { + unsigned char aux_olwat; +} aux_ol_wid_cell_t; + +/* + * There are actually 256 window tag entries in the FB and OL WAT tables. + * We will use only 16 for compatability with the BT463 and more importantly + * to implement the virtual ramdac interface. This requires us to only + * report the smallest WAT table size, in this case its the auxillary wat + * tables which are 16 entries. + */ + +#define TGA_RAMDAC_561_FB_WINDOW_TAG_COUNT 256 +#define TGA_RAMDAC_561_FB_WINDOW_TAG_MAX_COUNT 16 +#define TGA_RAMDAC_561_AUXFB_WINDOW_TAG_COUNT 16 +#define TGA_RAMDAC_561_OL_WINDOW_TAG_COUNT 256 +#define TGA_RAMDAC_561_OL_WINDOW_TAG_MAX_COUNT 16 +#define TGA_RAMDAC_561_AUXOL_WINDOW_TAG_COUNT 16 +#define TGA_RAMDAC_561_CMAP_ENTRY_COUNT 1024 +#define TGA_RAMDAC_561_GAM_ENTRY_COUNT 256 + + static fb_wid_cell_t + fb_wids_561[TGA_RAMDAC_561_FB_WINDOW_TAG_COUNT] = { +#if 0 + {0x28, 0x00}, /*0 8-plane index (PIXEL C 561 H/W screw-up) */ +#else + {0x36, 0x00}, /*c 24-plane true */ +#endif + {0x08, 0x00}, /*1 8-plane index (PIXEL B) */ + {0x00, 0x00}, /*2 8-plane index (PIXEL A) */ + {0x34, 0x00}, /*3 24-plane direct, cmap 0 */ + {0x28, 0x01}, /*4 8-plane index (PIXEL C 561 H/W screw-up) */ + {0x08, 0x01}, /*5 8-plane index (PIXEL B) */ + {0x00, 0x01}, /*6 8-plane index (PIXLE A) */ + {0x34, 0x01}, /*7 24-plane direct, cmap 1 */ + {0x1e, 0x00}, /*8 12-plane true */ + /*{0x16, 0x00}, 9 12-plane true */ + {0x14, 0x00}, /*9 12-plane true(direct) */ + {0x1e, 0x01}, /*a 12-plane true */ + {0x16, 0x01}, /*b 12-plane true */ + {0x36, 0x00}, /*c 24-plane true */ + {0x36, 0x00}, /*d 24-plane true */ + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0} + }; + + static aux_fb_wid_cell_t + auxfb_wids_561[TGA_RAMDAC_561_AUXFB_WINDOW_TAG_COUNT] = { + {0x04}, /*0 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*1 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*2 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*3 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*4 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*5 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*6 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*7 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*8 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*9 GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*a GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*b GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*c GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*d GMA=bypass, XH=disable, PT=dc */ + {0x04}, /*e old cursor colors for 463 don't use*/ + {0x04}, /*f old cursor colors for 463 don't use*/ + }; + + static ol_wid_cell_t + ol_wids_561[TGA_RAMDAC_561_OL_WINDOW_TAG_COUNT] = { + {0x31, 0x02}, /*0 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*1 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*2 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*3 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*4 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*5 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*6 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*7 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*8 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*9 PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*a PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*b PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*c PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*d PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*e PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0x31, 0x02}, /*f PX=4bpp, BS=0, MODE=index, TR=OPAQ */ + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + + static aux_ol_wid_cell_t + auxol_wids_561[TGA_RAMDAC_561_AUXOL_WINDOW_TAG_COUNT] = { + {0x0c}, /*0 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */ + {0x0c}, /*1 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */ + {0x0c}, /*2 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */ + {0x0c}, /*3 CK/OT=dc, UL=disabled, OL=enabled, GB=use */ + {0x0c}, /*4 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */ + {0x0c}, /*5 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */ + {0x0c}, /*6 CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */ + {0x0c}, /*7 CK/OT=dc, UL=disabled, OL=enabled, GB=use */ + {0x0c}, /*8 CK/OT=dc, UL=disabled, OL=disabled, GB=use */ + {0x0c}, /*9 CK/OT=dc, UL=disabled, OL=enabled, GB=use */ + {0x0c}, /*a CK/OT=dc, UL=disabled, OL=enabled, GB=use */ + {0x0c}, /*b CK/OT=dc, UL=disabled, OL=enabled, GB=use */ + {0x0c}, /*c CK/OT=dc, UL=disabled, OL=enabled, GB=bypass */ + {0x0c}, /*d CK/OT=dc, UL=disabled, OL=disabled, GB=bypass */ + {0x0c}, /*e old cursor color for 463, don't use */ + {0x0c}, /*f old cursor color for 463, don't use */ + }; + + /* ibm561 so init the window tags's via interrupt. It must be + * done either during the vsync interrupt or by blanking, We will + * actually do both. ??????? + */ + + IBM561LoadAddr(IBM561_FB_WINDOW_TYPE_TABLE); + for ( i = 0; i < TGA_RAMDAC_561_FB_WINDOW_TAG_COUNT; i++ ) { + low = ((fb_wids_561[i].low_byte & 0xfc) >> 2); + high =((fb_wids_561[i].high_byte & 0x03) << 6) & 0xff; + TGA2_WRITE_RAMDAC_REG (low | high, FBWAT_ADDR); + + low = (fb_wids_561[i].low_byte & 0x03) << 6; + TGA2_WRITE_RAMDAC_REG (low, FBWAT_ADDR); + } + + IBM561LoadAddr(IBM561_AUXFB_WINDOW_TYPE_TABLE); + for ( i = 0; i < TGA_RAMDAC_561_AUXFB_WINDOW_TAG_COUNT; i++ ) { + TGA2_WRITE_RAMDAC_REG (auxfb_wids_561[i].aux_fbwat, AUXFBWAT_ADDR); + } + + + IBM561LoadAddr(IBM561_OL_WINDOW_TYPE_TABLE); + for ( i = 0; i < TGA_RAMDAC_561_OL_WINDOW_TAG_COUNT; i++ ) { + low = ((ol_wids_561[i].low_byte & 0xfc) >> 2); + high =((ol_wids_561[i].high_byte & 0x03) << 6) & 0xff; + TGA2_WRITE_RAMDAC_REG (low | high, OLWAT_ADDR); + + low = (ol_wids_561[i].low_byte & 0x03) << 6; + TGA2_WRITE_RAMDAC_REG (low, OLWAT_ADDR); + } + + + IBM561LoadAddr(IBM561_AUXOL_WINDOW_TYPE_TABLE); + for ( i = 0; i < TGA_RAMDAC_561_AUXOL_WINDOW_TAG_COUNT; i++ ) { + TGA2_WRITE_RAMDAC_REG (auxol_wids_561[i].aux_olwat, AUXOLWAT_ADDR); + } +} + +/* + * ibm561_init_color_map + * + * Initialize color map in 561. Note the entire + * color map is initialized, both the 8-bit and the 24-bit + * portions. + */ +static int +IBM561InitColormap(ScrnInfoPtr pScrn) +{ + TGAPtr pTga = TGAPTR(pScrn); +#if 0 + tga_ibm561_info_t *bti = (tga_ibm561_info_t *) closure; + tga_info_t *tgap = tga_softc[bti->unit]; +#endif + int i; + + TGA2_WRITE_RAMDAC_REG(IBM561_COLOR_LOOKUP_TABLE, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(IBM561_COLOR_LOOKUP_TABLE >> 8, HI_ADDR); + + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + + for ( i = 1; i <256; i++ ) { + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + } + + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + + for ( i = 1; i <256; i++ ) { + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + } + + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + + for ( i = 1; i <256; i++ ) { + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + } + + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, CMAP_ADDR); + + for ( i = 1; i <256; i++ ) { + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + TGA2_WRITE_RAMDAC_REG (i, CMAP_ADDR); + } + + /* + * The ddx layer views the gamma table as an extension of the + * color pallettes, therefore the gamma table is initialized here. + * Note, each entry in the table is 10 bits, requiring two writes + * per entry!! The table are initialized the same way as color tables, + * a zero entry followed by mulitple ff's. NOTE, the gamma tables are + * loaded in a strange manner, DO NOT use this code as a guide (we are + * writing all zero's or all ones). See the tga_ibm561_load_color_map + * _entry code above. + */ + + TGA2_WRITE_RAMDAC_REG(IBM561_RED_GAMMA_TABLE, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(IBM561_RED_GAMMA_TABLE >> 8, HI_ADDR); + + TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR); + + for ( i = 1; i <256; i++ ) { + TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR); + TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR); + } + + TGA2_WRITE_RAMDAC_REG(IBM561_GREEN_GAMMA_TABLE, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(IBM561_GREEN_GAMMA_TABLE >> 8, HI_ADDR); + + TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR); + + for ( i = 1; i <256; i++ ) { + TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR); + TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR); + } + + TGA2_WRITE_RAMDAC_REG(IBM561_BLUE_GAMMA_TABLE, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(IBM561_BLUE_GAMMA_TABLE >> 8, HI_ADDR); + + TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR); + TGA2_WRITE_RAMDAC_REG (0x00, GAMMA_ADDR); + + for ( i = 1; i <256; i++ ) { + TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR); + TGA2_WRITE_RAMDAC_REG (0xff, GAMMA_ADDR); + } + + +#if 0 + /* ?? no cursor support yet */ + bti->cursor_fg.red = bti->cursor_fg.green = bti->cursor_fg.blue + = 0xffff; + bti->cursor_bg.red = bti->cursor_bg.green = bti->cursor_bg.blue + = 0x0000; + tga_ibm561_restore_cursor_color( closure, 0 ); +#endif + + return 0; +} + +void +IBM561ramdacHWInit(ScrnInfoPtr pScrn) +{ + TGAPtr pTga = TGAPTR(pScrn); + + unsigned int temp1[6] = {0,0,0,0,0,0}; + + /* + * Set-up av9110 to 14.3 Mhz as reference for 561's PLL + */ + temp1[0] = 0x00000101; + temp1[1] = 0x01000000; + temp1[2] = 0x00000001; + temp1[3] = 0x00010000; + temp1[4] = 0x01010100; + temp1[5] = 0x01000000; + + write_av9110(pScrn, temp1); + + /* + * Initialize IBM561 RAMDAC + */ + IBM561WriteReg(pScrn, IBM561_CONFIG_REG_1, 0x2a ); + IBM561WriteReg(pScrn, IBM561_CONFIG_REG_3, 0x41 ); + IBM561WriteReg(pScrn, IBM561_CONFIG_REG_4, 0x20 ); + +/* IBM561WriteReg(pScrn, IBM561_PLL_VCO_DIV_REG, 0xc8 ); */ + IBM561WriteReg(pScrn, IBM561_PLL_VCO_DIV_REG, tga_c_table->ibm561_vco_div); + +/* IBM561WriteReg(pScrn, IBM561_PLL_REF_REG, 0x08 ); */ + IBM561WriteReg(pScrn, IBM561_PLL_REF_REG, tga_c_table->ibm561_ref ); + + IBM561WriteReg(pScrn, IBM561_DIV_DOT_CLK_REG, 0xb0 ); + + IBM561WriteReg(pScrn, IBM561_SYNC_CONTROL, 0x01 ); + + IBM561WriteReg(pScrn, IBM561_CONFIG_REG_2, 0x19 ); + + TGA_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + + /* Configure the RAMDAC, note registers not set either depend on the + * previous setting (ie what firmaware programmed to be) or what the + * X-server will set them to + */ + + + /* + * Config Register 1: MUX=4:1 BASIC, OVLY=8 bits, WID=8 bits (bits 4-7 of the + * overlay and window ID's are tied to ground in the hardware). + */ + IBM561WriteReg(pScrn, IBM561_CONFIG_REG_1, 0x2a ); + + /* SKIP Config Register 2-3 (use Diag settings at least for now) */ + + /* + * Config Register 4: FB_WID=4 bits, SWE=Common, AOW=LSB, AFW=LSB + */ + IBM561WriteReg(pScrn, IBM561_CONFIG_REG_4, 0x20 ); + + /* + * SKIP Interleave Register (use Diag settings at least for now) + */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* + * WAT/OL Segement Registers + */ + /* ?? we setup the address registers first, then stream the data out ?? */ + TGA2_WRITE_RAMDAC_REG(IBM561_WAT_SEG_REG, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(IBM561_WAT_SEG_REG >> 8, HI_ADDR); + + /* WAT Segment Register */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* OL Segment Register */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* AUX WAT Segment Register */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* AUX OL Segment Register */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* + * Chroma Key Registers and Masks + */ + /* ?? we setup the address registers first, then stream the data out ?? */ + TGA2_WRITE_RAMDAC_REG(IBM561_CHROMA_KEY_REG0, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(IBM561_CHROMA_KEY_REG0 >> 8, HI_ADDR); + + /* Chroma key register 0 */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* Chroma key register 1 */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* Chroma key mask register 0 */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* Chroma key mask register 1 */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* + * Cursor Control Register + */ + IBM561WriteReg(pScrn, IBM561_CURSOR_CTRL_REG, /*pScrn->cursor_on_off*/0); + + /* + * Cursor Hot Spot X/Y Registers + */ + TGA2_WRITE_RAMDAC_REG(IBM561_CURSOR_HS_REG, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(IBM561_CURSOR_HS_REG >> 8, HI_ADDR); + + /* Cursor "x" Hot Spot Register */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* Cursor "y" Hot Spot Register */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* Cursor "x" Location Register (low byte) */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* Cursor "x" Location Register (high byte) */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* Cursor "y" Location Register (low byte) */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* Cursor "y" Location Register (high byte) */ + TGA2_WRITE_RAMDAC_REG (0x00, REGS_ADDR); + + /* + * VRAM Mask regs (used for diag purposes, reset them just in case) + */ + TGA2_WRITE_RAMDAC_REG(IBM561_VRAM_MASK_REG, LO_ADDR); + TGA2_WRITE_RAMDAC_REG(IBM561_VRAM_MASK_REG >> 8, HI_ADDR); + + /* VRAM mask register 1 */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* VRAM mask register 2 */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* VRAM mask register 3 */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* VRAM mask register 4 */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* VRAM mask register 5 */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* VRAM mask register 6 */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* VRAM mask register 7 */ + TGA2_WRITE_RAMDAC_REG (0xff, REGS_ADDR); + + /* Finally, do colormaps and windowtags */ + IBM561InitColormap(pScrn); + IBM561WindowTagsInit(pScrn); +} + +void +IBM561ramdacRestore(ScrnInfoPtr pScrn, unsigned char *Ibm561) +{ +#if 0 + TGAPtr pTga = TGAPTR(pScrn); +#endif + +#if 0 + /* ?? finally the stock stuff ?? */ + int i, j; + /* ?? FIXME OR NOT this is currently copied from the BT463 */ + IBM561_WRITE(IBM561_REG_ACC, IBM561_CMD_REG_0, Ibm561[0]); + IBM561_WRITE(IBM561_REG_ACC, IBM561_CMD_REG_1, Ibm561[1]); + IBM561_WRITE(IBM561_REG_ACC, IBM561_CMD_REG_2, Ibm561[2]); + + IBM561_WRITE(IBM561_REG_ACC, IBM561_READ_MASK_0, Ibm561[3]); + IBM561_WRITE(IBM561_REG_ACC, IBM561_READ_MASK_1, Ibm561[4]); + IBM561_WRITE(IBM561_REG_ACC, IBM561_READ_MASK_2, Ibm561[5]); + IBM561_WRITE(IBM561_REG_ACC, IBM561_READ_MASK_3, Ibm561[6]); + + IBM561_WRITE(IBM561_REG_ACC, IBM561_BLINK_MASK_0, Ibm561[7]); + IBM561_WRITE(IBM561_REG_ACC, IBM561_BLINK_MASK_1, Ibm561[8]); + IBM561_WRITE(IBM561_REG_ACC, IBM561_BLINK_MASK_2, Ibm561[9]); + IBM561_WRITE(IBM561_REG_ACC, IBM561_BLINK_MASK_3, Ibm561[10]); + + IBM561_LOAD_ADDR(IBM561_WINDOW_TYPE_BASE); + TGA_WRITE_REG((IBM561_REG_ACC<<2), TGA_RAMDAC_SETUP_REG); + + for (i = 0, j = 11; i < 16; i++) { + TGA_WRITE_REG(Ibm561[j++]|(IBM561_REG_ACC<<10), TGA_RAMDAC_REG); + TGA_WRITE_REG(Ibm561[j++]|(IBM561_REG_ACC<<10), TGA_RAMDAC_REG); + TGA_WRITE_REG(Ibm561[j++]|(IBM561_REG_ACC<<10), TGA_RAMDAC_REG); + } +#endif + +/* + fprintf(stderr, "IBM561ramdacRestore (%p)\n", Ibm561); + for (i=0; i<58; i++) + fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Ibm561[i]); +*/ + +} + diff --git a/driver/xf86-video-tga/src/ICS1562.c b/driver/xf86-video-tga/src/ICS1562.c new file mode 100644 index 000000000..9c7554c24 --- /dev/null +++ b/driver/xf86-video-tga/src/ICS1562.c @@ -0,0 +1,118 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/ICS1562.c,v 1.2 1998/07/25 16:55:56 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define BASE_FREQ 14.31818 +#define MAX_FREQ 230000 + +#define reorder(a) ( \ + (a & 0x80) >> 7 | \ + (a & 0x40) >> 5 | \ + (a & 0x20) >> 3 | \ + (a & 0x10) >> 1 | \ + (a & 0x08) << 1 | \ + (a & 0x04) << 3 | \ + (a & 0x02) << 5 | \ + (a & 0x01) << 7 ) + +#define CHECK_MIN(m,a,r,n) do { \ + diff = f - (BASE_FREQ * 1e3 * (n)) / (r << p); \ + if (diff < 0) diff = -diff; \ + if (diff < min_diff) { \ + min_diff = diff; \ + best_m = m; \ + best_a = a; \ + best_r = r; \ + } \ + } while(0) + + +static void Set_1562_PLL(int f, int p, int m, int a, int r, unsigned char *bits) +{ + bits[0] = 0x80; /* N1 = 4, not used for PLL */ + bits[1] = reorder(p) >> 4; + bits[2] = 0x00; /* N2 = 1 */ + if (f <= 120000) + bits[3] = 0x20; /* V = 100 */ + else if (f <= 200000) + bits[3] = 0xa0; /* V = 101 */ + else + bits[3] = 0x60; /* V = 110 */ + bits[3] |= 0x05; /* P = 10, phase detector on */ + bits[4] = reorder(m); + bits[5] = reorder(a); + bits[6] = reorder(r); + +#ifdef DEBUG + { + int i; + for(i=0; i<7; i++) + ErrorF("%02x ", bits[i]); + ErrorF("\n"); + } +#endif +} + +void ICS1562_CalcClockBits(long f, unsigned char *bits); + +void ICS1562_CalcClockBits(long f, unsigned char *bits) +{ + int n,r, a,m, p, r0,r1,n0,n1; + int best_m=34, best_a=1, best_r=30; + double diff, min_diff; + double ff, ffp; + + if (f > MAX_FREQ) + f = MAX_FREQ; + + if (f >= MAX_FREQ/2) + p=0; + else if (f >= MAX_FREQ/4) + p=1; + else + p=2; + + ff = f / 1e3 / BASE_FREQ; + ffp = ff * (1 << p); + min_diff = 999999999; + + r0 = (int)(7/ffp); + if (r0 < 1) r0 = 1; + r1 = (int)(449/ffp); + if (r1 > 0x7f+1) r1 = 0x7f+1; + if (r1 < r0) r1 = r0; + + for (r=r0; r<r1; r++) { + n0 = (int)(ffp * r); + if (n0 < 7) n0 = 7; + n1 = (int)(ffp * (r+1)); + if (n1 > 448) n1 = 448; + for (n=n0; n<n1; n++) { + m = ((n+3)/7) - 1; + if (m <= 0x3f) CHECK_MIN(m, 0, r, (m+1)*7); + if (++m <= 0x3f) CHECK_MIN(m, 0, r, (m+1)*7); + m = (n/6) - 1; + a = n - (m+1)*6; + if (m <= 0x3f && a > 0 && a<=7) CHECK_MIN(m, a, r, (m+1)*6+a); + m++; + a = n - (m+1)*6; + if (m <= 0x3f && a > 0 && a<=7) CHECK_MIN(m, a, r, (m+1)*6+a); + } + } + + if (best_a) n = (best_m+1)*6+best_a; + else n = (best_m+1)*7; + +#ifdef DEBUG + ErrorF("%8.3f %f %f p=%d m=%d a=%d r=%d %d/%d\n" + ,f/1e3 + ,min_diff,(BASE_FREQ * (n)) / (best_r << p) + ,p ,best_m, best_a, best_r-1 + ,n,best_r + ); +#endif + + Set_1562_PLL(f, p, best_m, best_a, best_r-1, bits); +} diff --git a/driver/xf86-video-tga/src/Makefile.am b/driver/xf86-video-tga/src/Makefile.am new file mode 100644 index 000000000..1555548d7 --- /dev/null +++ b/driver/xf86-video-tga/src/Makefile.am @@ -0,0 +1,47 @@ +# Copyright 2005 Adam Jackson. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# this is obnoxious: +# -module lets us name the module exactly how we want +# -avoid-version prevents gratuitous .0.0.0 version numbers on the end +# _ladir passes a dummy rpath to libtool so the thing will actually link +# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. +AM_CFLAGS = @XORG_CFLAGS@ +tga_drv_la_LTLIBRARIES = tga_drv.la +tga_drv_la_LDFLAGS = -module -avoid-version +tga_drv_ladir = @moduledir@/drivers + +tga_drv_la_SOURCES = \ + BT463ramdac.c \ + BTramdac.c \ + IBM561ramdac.c \ + ICS1562.c \ + tga_accel.c \ + tga_cursor.c \ + tga_dac.c \ + tga_driver.c \ + tga.h \ + tga_line.c \ + tga_seg.c \ + tga_regs.h + +tga_seg.c: $(srcdir)/tga_line.c + echo "#define POLYSEGMENT" > tga_seg.c + echo "#include \"$(srcdir)/tga_line.c\"" >> tga_seg.c diff --git a/driver/xf86-video-tga/src/Makefile.in b/driver/xf86-video-tga/src/Makefile.in new file mode 100644 index 000000000..35fa93183 --- /dev/null +++ b/driver/xf86-video-tga/src/Makefile.in @@ -0,0 +1,536 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright 2005 Adam Jackson. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(tga_drv_ladir)" +tga_drv_laLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(tga_drv_la_LTLIBRARIES) +tga_drv_la_LIBADD = +am_tga_drv_la_OBJECTS = BT463ramdac.lo BTramdac.lo IBM561ramdac.lo \ + ICS1562.lo tga_accel.lo tga_cursor.lo tga_dac.lo tga_driver.lo \ + tga_line.lo tga_seg.lo +tga_drv_la_OBJECTS = $(am_tga_drv_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(tga_drv_la_SOURCES) +DIST_SOURCES = $(tga_drv_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ +ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +APP_MAN_DIR = @APP_MAN_DIR@ +APP_MAN_SUFFIX = @APP_MAN_SUFFIX@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_LINUXDOC_FALSE = @BUILD_LINUXDOC_FALSE@ +BUILD_LINUXDOC_TRUE = @BUILD_LINUXDOC_TRUE@ +BUILD_PDFDOC_FALSE = @BUILD_PDFDOC_FALSE@ +BUILD_PDFDOC_TRUE = @BUILD_PDFDOC_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ +DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ +DRIVER_NAME = @DRIVER_NAME@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FILE_MAN_DIR = @FILE_MAN_DIR@ +FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_MAN_DIR = @LIB_MAN_DIR@ +LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ +LINUXDOC = @LINUXDOC@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +MAKE_HTML = @MAKE_HTML@ +MAKE_PDF = @MAKE_PDF@ +MAKE_PS = @MAKE_PS@ +MAKE_TEXT = @MAKE_TEXT@ +MISC_MAN_DIR = @MISC_MAN_DIR@ +MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PS2PDF = @PS2PDF@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XORG_CFLAGS = @XORG_CFLAGS@ +XORG_LIBS = @XORG_LIBS@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ + +# this is obnoxious: +# -module lets us name the module exactly how we want +# -avoid-version prevents gratuitous .0.0.0 version numbers on the end +# _ladir passes a dummy rpath to libtool so the thing will actually link +# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. +AM_CFLAGS = @XORG_CFLAGS@ +tga_drv_la_LTLIBRARIES = tga_drv.la +tga_drv_la_LDFLAGS = -module -avoid-version +tga_drv_ladir = @moduledir@/drivers +tga_drv_la_SOURCES = \ + BT463ramdac.c \ + BTramdac.c \ + IBM561ramdac.c \ + ICS1562.c \ + tga_accel.c \ + tga_cursor.c \ + tga_dac.c \ + tga_driver.c \ + tga.h \ + tga_line.c \ + tga_seg.c \ + tga_regs.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-tga_drv_laLTLIBRARIES: $(tga_drv_la_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(tga_drv_ladir)" || $(mkdir_p) "$(DESTDIR)$(tga_drv_ladir)" + @list='$(tga_drv_la_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(tga_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(tga_drv_ladir)/$$f'"; \ + $(LIBTOOL) --mode=install $(tga_drv_laLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(tga_drv_ladir)/$$f"; \ + else :; fi; \ + done + +uninstall-tga_drv_laLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(tga_drv_la_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(tga_drv_ladir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(tga_drv_ladir)/$$p"; \ + done + +clean-tga_drv_laLTLIBRARIES: + -test -z "$(tga_drv_la_LTLIBRARIES)" || rm -f $(tga_drv_la_LTLIBRARIES) + @list='$(tga_drv_la_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +tga_drv.la: $(tga_drv_la_OBJECTS) $(tga_drv_la_DEPENDENCIES) + $(LINK) -rpath $(tga_drv_ladir) $(tga_drv_la_LDFLAGS) $(tga_drv_la_OBJECTS) $(tga_drv_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BT463ramdac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BTramdac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IBM561ramdac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ICS1562.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tga_accel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tga_cursor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tga_dac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tga_driver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tga_line.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tga_seg.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(tga_drv_ladir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-tga_drv_laLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-tga_drv_laLTLIBRARIES + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-tga_drv_laLTLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-tga_drv_laLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip install-tga_drv_laLTLIBRARIES installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am \ + uninstall-tga_drv_laLTLIBRARIES + + +tga_seg.c: $(srcdir)/tga_line.c + echo "#define POLYSEGMENT" > tga_seg.c + echo "#include \"$(srcdir)/tga_line.c\"" >> tga_seg.c +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/driver/xf86-video-tga/src/tga.h b/driver/xf86-video-tga/src/tga.h new file mode 100644 index 000000000..4c60606bd --- /dev/null +++ b/driver/xf86-video-tga/src/tga.h @@ -0,0 +1,219 @@ +/* + * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga.h,v 1.17 2001/05/04 19:05:47 dawes Exp $ */ + +#ifndef _TGA_H_ +#define _TGA_H_ + +#include "xaa.h" +#include "xf86RamDac.h" + +typedef struct { + unsigned long tgaRegs[0x100]; +} TGARegRec, *TGARegPtr; + + +#define TGAPTR(p) ((TGAPtr)((p)->driverPrivate)) + +typedef struct { + pciVideoPtr PciInfo; + PCITAG PciTag; + int Chipset; + RamDacHelperRecPtr RamDac; + int ChipRev; + int HwBpp; + int BppShift; + int pprod; + CARD32 CardAddress; + CARD32 IOAddress; + CARD32 FbAddress; + unsigned char * FbBase; + unsigned char * IOBase; + unsigned char * ClkBase; /* TGA2 */ + unsigned char * DACBase; /* TGA2 */ + unsigned char * HACKBase; /* TGA2 */ + long FbMapSize; + unsigned long regOffset; + Bool NoAccel; + Bool NoXaaPolySegment; + Bool Dac6Bit; + Bool SyncOnGreen; + Bool HWCursor; + Bool UsePCIRetry; + int MinClock; + int MaxClock; + TGARegRec SavedReg; + TGARegRec ModeReg; + CARD32 AccelFlags; + RamDacRecPtr RamDacRec; + XAAInfoRecPtr AccelInfoRec; + xf86CursorInfoPtr CursorInfoRec; + CloseScreenProcPtr CloseScreen; + int CardType; + unsigned char Bt463modeReg[59]; + unsigned char Bt463saveReg[59]; + unsigned char Ibm561modeReg[59]; + unsigned char Ibm561saveReg[59]; + EntityInfoPtr pEnt; + CARD32 *buffers[1]; + unsigned int current_rop; + unsigned int current_planemask; + int transparent_pattern_p; + int blitdir; + int block_or_opaque_p; + int ce_height; + int ce_width; + int ce_x; + int ce_y; + int ce_skipleft; + int line_pattern_length; + CARD16 line_pattern; /* for dashed lines */ + int Bpp; /* bytes per pixel */ + int depthflag; /* either BPP8PACKED or BPP24 */ + OptionInfoPtr Options; +} TGARec, *TGAPtr; + +/* ?? this is a hack for initial TGA2 support */ +struct monitor_data { + unsigned int max_rows; /* Monitor setup */ + unsigned int max_cols; + unsigned int pixel_freq; + unsigned int refresh_rate; + unsigned int vert_slines; + unsigned int vert_fp; + unsigned int vert_sync; + unsigned int vert_bp; + unsigned int horz_pix; + unsigned int horz_fp; + unsigned int horz_sync; + unsigned int horz_bp; + unsigned int vco_div; /* ICS setup */ + unsigned int ref_div; + unsigned int vco_pre; + unsigned int clk_div; + unsigned int vco_out_div; + unsigned int clk_out_en; + unsigned int clk_out_enX; + unsigned int res0; + unsigned int clk_sel; + unsigned int res1; + unsigned int ibm561_vco_div; /* IBM561 PLL setup */ + unsigned int ibm561_ref; +}; + +extern struct monitor_data tga_crystal_table[]; +extern int tga_crystal_table_entries; +extern struct monitor_data *tga_c_table; + +/* Prototypes */ + +/* tga_dac.c */ +void DEC21030Restore(ScrnInfoPtr pScrn,/* vgaRegPtr vgaReg,*/ + TGARegPtr tgaReg/*, Bool restoreFonts*/); +void DEC21030Save(ScrnInfoPtr pScrn, /*vgaRegPtr vgaReg,*/ TGARegPtr tgaReg/*, + Bool saveFonts*/); +Bool DEC21030Init(ScrnInfoPtr pScrn, DisplayModePtr mode); +void write_av9110(ScrnInfoPtr pScrn, unsigned int *); +void TGA2SetupMode(ScrnInfoPtr pScrn); +void Ibm561Init(TGAPtr pTga); +void Bt463Init(TGAPtr pTga); + +/* tga_accel.c */ +Bool DEC21030AccelInit(ScreenPtr pScreen); + +/* BTramdac.c */ +void tgaBTOutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data); +unsigned char tgaBTInIndReg(ScrnInfoPtr pScrn, CARD32 reg); +void tgaBTWriteAddress(ScrnInfoPtr pScrn, CARD32 index); +void tgaBTReadAddress(ScrnInfoPtr pScrn, CARD32 index); +void tgaBTWriteData(ScrnInfoPtr pScrn, unsigned char data); +unsigned char tgaBTReadData(ScrnInfoPtr pScrn); + +void tga2BTOutIndReg(ScrnInfoPtr pScrn, + CARD32 reg, unsigned char mask, unsigned char data); +unsigned char tga2BTInIndReg(ScrnInfoPtr pScrn, CARD32 reg); +void tga2BTWriteAddress(ScrnInfoPtr pScrn, CARD32 index); +void tga2BTReadAddress(ScrnInfoPtr pScrn, CARD32 index); +void tga2BTWriteData(ScrnInfoPtr pScrn, unsigned char data); +unsigned char tga2BTReadData(ScrnInfoPtr pScrn); + +/* BT463ramdac.c */ +void BT463ramdacSave(ScrnInfoPtr pScrn, unsigned char *data); +void BT463ramdacRestore(ScrnInfoPtr pScrn, unsigned char *data); + +/* IBM561ramdac.c */ +void IBM561ramdacSave(ScrnInfoPtr pScrn, unsigned char *data); +void IBM561ramdacHWInit(ScrnInfoPtr pScrn); +void IBM561ramdacRestore(ScrnInfoPtr pScrn, unsigned char *data); +unsigned char IBM561ReadReg(ScrnInfoPtr pScrn, CARD32 reg); +void IBM561WriteReg(ScrnInfoPtr pScrn, CARD32 reg, unsigned char data); + +/* tga_cursor.c */ +Bool TGAHWCursorInit(ScreenPtr pScreen); + +/* tga_line.c */ + +void TGAPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, + xSegment *pSeg); +void TGAPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit); +void TGAPolySegmentDashed(DrawablePtr pDrawable, GCPtr pGC, int nseg, + xSegment *pSeg); +void TGAPolyLinesDashed(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit); + +/* line functions */ +void +TGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +void +TGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, + int dir); +void +TGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int octant, int flags); +void +TGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int octant); +void +TGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len, + int err); + +void +TGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern); +void +TGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int octant, int flags, int phase); +void +TGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len, + int err, int phase); + + + + +#endif /* _TGA_H_ */ + diff --git a/driver/xf86-video-tga/src/tga_accel.c b/driver/xf86-video-tga/src/tga_accel.c new file mode 100644 index 000000000..76decdf49 --- /dev/null +++ b/driver/xf86-video-tga/src/tga_accel.c @@ -0,0 +1,1572 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c,v 1.15 2001/11/21 22:32:59 alanh Exp $ */ + +/* + * Copyright 1996,1997 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + * + * DEC TGA accelerated options. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fb.h" +#include "micmap.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" +#include "mipointer.h" + +#include "mibstore.h" +#include "miline.h" + +#include "tga_regs.h" +#include "BT.h" +#include "tga.h" + +/* defines */ + +#define BLIT_FORWARDS 0 +#define BLIT_BACKWARDS 1 +#define USE_BLOCK_FILL 2 +#define USE_OPAQUE_FILL 3 +#define MIX_SRC 0x03 + +#define CE_BUFSIZE 256 + +#define FB_OFFSET(x, y) (((long)(y) * pScrn->displayWidth * (pTga->Bpp)) + (long)(x) * pTga->Bpp) + +/* prototypes */ + +static void TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w); +static void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w); +extern void TGASync(ScrnInfoPtr pScrn); +static void TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +static void TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); +static void TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned int planemask, + int transparency_color); +static void TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h); +static void TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, + int fg, int bg, int rop, + unsigned int planemask); +static void TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, + int paty, int x, int y, int w, + int h); +static void TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask); + +static void +TGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, int w, + int h, int skipleft); +static void +TGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); + + +/* + * The following function sets up the supported acceleration. Call it + * from the FbInit() function in the SVGA driver. + */ +Bool +DEC21030AccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr TGA_AccelInfoRec; + BoxRec AvailFBArea; + ScrnInfoPtr pScrn; + TGAPtr pTga; + + pScrn = xf86Screens[pScreen->myNum]; + pTga = TGAPTR(pScrn); + + /* ErrorF("DEC21030AccelInit called!"); */ + + /* first, create the XAAInfoRec */ + TGA_AccelInfoRec = XAACreateInfoRec(); + + /* ErrorF("XAACreateInfoRec called"); */ + + if(pScrn->depth == 8) { + pTga->depthflag = BPP8PACKED; + pTga->Bpp = 1; + } else { + pTga->depthflag = BPP24; + pTga->Bpp = 4; + } + + TGA_AccelInfoRec->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS; + + TGA_AccelInfoRec->Sync = TGASync; + + /* solid fill */ + + TGA_AccelInfoRec->SolidFillFlags = 0; + TGA_AccelInfoRec->SetupForSolidFill = TGASetupForSolidFill; + TGA_AccelInfoRec->SubsequentSolidFillRect = TGASubsequentSolidFillRect; + + /* screen to screen copy */ + TGA_AccelInfoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + TGA_AccelInfoRec->SetupForScreenToScreenCopy = + TGASetupForScreenToScreenCopy; + TGA_AccelInfoRec->SubsequentScreenToScreenCopy = + TGASubsequentScreenToScreenCopy; + + /* mono 8x8 pattern fill */ + + TGA_AccelInfoRec->Mono8x8PatternFillFlags = + HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_LSBFIRST; + TGA_AccelInfoRec->SetupForMono8x8PatternFill = + TGASetupForMono8x8PatternFill; + TGA_AccelInfoRec->SubsequentMono8x8PatternFillRect = + TGASubsequentMono8x8PatternFillRect; + + /* color expand */ + /* does not work for 32bpp (yet) */ + TGA_AccelInfoRec->ScanlineCPUToScreenColorExpandFillFlags = + BIT_ORDER_IN_BYTE_LSBFIRST; + + TGA_AccelInfoRec->NumScanlineColorExpandBuffers = 1; + pTga->buffers[0] = (CARD32 *)xnfalloc(CE_BUFSIZE); + TGA_AccelInfoRec->ScanlineColorExpandBuffers = + (unsigned char **)pTga->buffers; + TGA_AccelInfoRec->SetupForScanlineCPUToScreenColorExpandFill = + TGASetupForScanlineCPUToScreenColorExpandFill; + TGA_AccelInfoRec->SubsequentScanlineCPUToScreenColorExpandFill = + TGASubsequentScanlineCPUToScreenColorExpandFill; + TGA_AccelInfoRec->SubsequentColorExpandScanline = + TGASubsequentColorExpandScanline; + + /* lines */ + + TGA_AccelInfoRec->PolylinesThinSolid = TGAPolyLines; + if(pTga->NoXaaPolySegment == FALSE) + TGA_AccelInfoRec->PolySegmentThinSolid = TGAPolySegment; + TGA_AccelInfoRec->PolylinesThinSolidFlags = 0x0; + TGA_AccelInfoRec->PolySegmentThinSolidFlags = 0x0; + + TGA_AccelInfoRec->PolylinesThinDashed = TGAPolyLinesDashed; + if(pTga->NoXaaPolySegment == FALSE) + TGA_AccelInfoRec->PolySegmentThinDashed = TGAPolySegmentDashed; + TGA_AccelInfoRec->PolylinesThinDashedFlags = 0x0; + TGA_AccelInfoRec->PolySegmentThinDashedFlags = 0x0; + TGA_AccelInfoRec->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED; + TGA_AccelInfoRec->DashPatternMaxLength = 16; + + /* initialize the pixmap cache */ + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; /* these gotta be 0 */ + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = (pScrn->videoRam * 1024) / (pScrn->displayWidth * + pTga->Bpp); + xf86InitFBManager(pScreen, &AvailFBArea); + + TGA_AccelInfoRec->PixmapCacheFlags = 0; + + /* initialize XAA */ + return(XAAInit(pScreen, TGA_AccelInfoRec)); +} + +static void +TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga = NULL; + unsigned int fgcolor = 0, bgcolor = 0, pmask = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + +/* ErrorF("TGASetupForScanlineCPUToScreenColorExpandFill called\n"); */ + if(pTga->depthflag == BPP8PACKED) { + fgcolor = (fg | (fg << 8) | (fg << 16) | (fg << 24)); + bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24); + pmask = planemask | (planemask << 8) | (planemask << 16) + | (planemask << 24); + } + else { + bgcolor = bg; + fgcolor = fg; + pmask = planemask; + } + pTga->current_rop = rop | pTga->depthflag; + + if(bg == -1) { + pTga->transparent_pattern_p = 1; + if(rop == MIX_SRC) { + pTga->block_or_opaque_p = USE_BLOCK_FILL; + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); + if(pTga->depthflag == BPP24) { + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); + } + } + else { + pTga->block_or_opaque_p = USE_OPAQUE_FILL; + TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); + } + } + else { + pTga->transparent_pattern_p = 0; + TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); + } + TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); /* we know when to + reset this */ + TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); + + TGA_SAVE_OFFSET(); + + return; +} + +static void +TGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, int w, + int h, int skipleft) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + +/* ErrorF("TGASubsequentScanlineCPUToScreenColorExpandFill called\n"); */ +/* ErrorF("w = %d, h = %d\n", w, h); */ + + pTga->ce_height = h; + pTga->ce_width = w; + pTga->ce_x = x; + pTga->ce_y = y; + pTga->ce_skipleft = skipleft; +/* ErrorF("skipleft is %d\n", skipleft); */ + + if(pTga->transparent_pattern_p) { + if(pTga->block_or_opaque_p == USE_BLOCK_FILL) + TGA_FAST_WRITE_REG(BLOCKSTIPPLE | X11 | pTga->depthflag, + TGA_MODE_REG); + else + TGA_FAST_WRITE_REG(TRANSPARENTSTIPPLE | X11 | pTga->depthflag, + TGA_MODE_REG); +/* ErrorF("transparent stipple with x = %d, y = %d, w = %d, h = %d\n", */ +/* x, y, w, h); */ + } + else + TGA_FAST_WRITE_REG(OPAQUESTIPPLE | X11 | pTga->depthflag, + TGA_MODE_REG); + + TGA_SAVE_OFFSET(); + return; +} + +static void +TGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga; + unsigned char *p = NULL; + int width = 0; + unsigned int addr; + unsigned int pixelmask = 0; + unsigned int stipple; + unsigned int align_mask; + int align = 0; + int skipleft; + + CARD32 c = 0, d = 0; + CARD32 *e = NULL; + int i = 0, num_dwords = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + + align_mask = (pTga->depthflag == BPP24) ? 0x0f : 0x03; + +#if 0 + ErrorF("TGASubsequentColorExpandScanline called\n"); + if(pTga->transparent_pattern_p) + ErrorF("transparent color expand\n"); +#endif + + p = (unsigned char *)pTga->buffers[0]; + addr = FB_OFFSET(pTga->ce_x, pTga->ce_y); + width = pTga->ce_width; + skipleft = pTga->ce_skipleft; + + while(width > 0) { + if(!pTga->transparent_pattern_p) + pixelmask = 0xFFFFFFFF; + + align = (addr & align_mask) / pTga->Bpp; /* no. pixels out of align */ + if (align) { + if (!pTga->transparent_pattern_p) + pixelmask <<= align; +/* ErrorF("alignment is %d\n", align); */ + addr -= align * pTga->Bpp; + width += align; + + e = (CARD32 *)p; + num_dwords = (width / 32) + 1; + if(num_dwords > (CE_BUFSIZE / 4)) { /* shouldn't happen */ + ErrorF("TGASubsequentColorExpandScanline passed scanline %d bytes long, truncating\n", num_dwords * 4); + num_dwords = CE_BUFSIZE / 4; + } + for(i = 0; i < num_dwords; i++) { + c = e[i]; + if(i == 0) + e[i] = c << align; + else + e[i] = (d >> (32 - align)) | (c << align); + d = c; + } + } + + if (!pTga->transparent_pattern_p) { + if (skipleft) { + pixelmask <<= skipleft; + skipleft = 0; + } + if (width < 32) { + pixelmask &= (0xFFFFFFFF >> (32 - width)); + } + TGA_FAST_WRITE_REG(pixelmask, TGA_PIXELMASK_REG); + } + else { + unsigned int *i = NULL; + +/* ErrorF("transparent scanline with x = %d, y = %d, w = %d, h = %d\n", pTga->ce_x, pTga->ce_y, pTga->ce_width, pTga->ce_height); */ + if (skipleft) { + i = (unsigned int *)p; + *i &= (0xFFFFFFFF << skipleft); + skipleft = 0; + } + if (width < 32) { + i = (unsigned int *)p; + *i &= (0xFFFFFFFF >> (32 - width)); + } + } + + stipple = *((unsigned int *)p); + switch (pTga->Chipset) { + case PCI_CHIP_TGA2: + *(unsigned int *)(pTga->FbBase + addr) = stipple; WMB; + break; + case PCI_CHIP_DEC21030: + TGA_FAST_WRITE_REG(addr, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(stipple, TGA_CONTINUE_REG); + } + addr += 32 * pTga->Bpp; + p += 4; + width -= 32; + } + pTga->ce_height--; + if(pTga->ce_height == 0) { + TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, + TGA_MODE_REG); + TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + } + else + pTga->ce_y += 1; + + TGA_SAVE_OFFSET(); + return; +} + +/* Block Fill mode is faster, but only works for certain rops. So we will + have to implement Opaque Fill anyway, so we will do that first, then + do Block Fill for the special cases +*/ +void +TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga; + unsigned int fgcolor = 0, pmask = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + /* ErrorF("TGASetupForSolidFill called"); */ + + if(pTga->depthflag == BPP8PACKED) { + fgcolor = color | (color << 8) | (color << 16) | (color << 24); + pmask = planemask | (planemask << 8) | (planemask << 16) | + (planemask << 24); + } + else { + fgcolor = color; + pmask = planemask; + } + + + if(rop == MIX_SRC) { /* we can just do a block copy */ + pTga->block_or_opaque_p = USE_BLOCK_FILL; + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); + if(pTga->depthflag == BPP24) { + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); + } + } + else { + pTga->block_or_opaque_p = USE_OPAQUE_FILL; + pTga->current_rop = rop | pTga->depthflag; + TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); +/* ErrorF("opaque fill called\n"); */ + } + + pTga->current_planemask = pmask; + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_DATA_REG); + TGA_SAVE_OFFSET(); + return; +} + +void +TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) +{ + unsigned int mode_reg = 0; + int i = 0; + unsigned int pixel_count = 0; /* the actual # of pixels to be written */ + unsigned int write_data = 0; /* the actual data written */ + int a1 = 0; +#ifdef PROFILE + unsigned int stop, start; +#endif + TGAPtr pTga; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + + /* ErrorF("TGASubsequentFillRectSolid called\n"); */ + + if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) { + mode_reg = OPAQUEFILL | X11 | pTga->depthflag; + TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); + /* we have to set this to GXCOPY every time before we exit */ + } + else + mode_reg = BLOCKFILL | X11 | pTga->depthflag; + + TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG); + TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); + + if(w > 2048) { + ErrorF("TGASubsequentSolidFillRect called with w = %d, truncating.\n", w); + w = 2048; + } + pixel_count = w - 1; + + for(i = 0; i < h; i++) { + a1 = FB_OFFSET(x, y + i); + if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); + write_data = pixel_count; + TGA_FAST_WRITE_REG(a1, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(write_data, TGA_CONTINUE_REG); + } + + mode_reg = SIMPLE | X11 | pTga->depthflag; + TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG); + if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) + TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, + TGA_RASTEROP_REG); /* GXCOPY */ + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + + TGA_SAVE_OFFSET(); + return; +} + +/* we only need to calculate the direction of a move once per move, + so we do it in the setup function and leave it */ + +void +TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned int planemask, + int transparency_color) + /* xdir 1 = left-to-right, -1 = right to left + ydir 1 = top-to-bottom, -1 = bottom to top + */ +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga; + unsigned int pmask = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + + /* see section 6.2.9 */ + + if (pTga->depthflag == BPP8PACKED) { + pmask = planemask | (planemask << 8) | (planemask << 16) | + (planemask << 24); + } + else + pmask = planemask; + + pTga->current_planemask = pmask; + TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); + + pTga->current_rop = rop | pTga->depthflag; + + /* do we copy a rectangle from top to bottom or bottom to top? */ + if (ydir == -1) { + pTga->blitdir = BLIT_FORWARDS; + } + else { + pTga->blitdir = BLIT_BACKWARDS; + } + TGA_SAVE_OFFSET(); + return; +} + +/* + * This is the implementation of the SubsequentForScreenToScreenCopy + * that sends commands to the coprocessor to perform a screen-to-screen + * copy of the specified areas, with the parameters from the SetUp call. + */ +void +TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w, int h) +{ + /* x1, y1 = source coords + x2, y2 = destination coords + w = width + h = height + */ + + int i = 0; + void (*copy_func)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w); +#ifdef PROFILE + unsigned int stop, start; +#endif + TGAPtr pTga; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); +#if 0 + ErrorF("TGASubsequentScreenToScreenCopy(,%d,%d,%d,%d,%d,%d):" + " COPY %s BLIT %s\n", + x1, y1, x2, y2, w, h, (x2 > x1 && (x1 + w) > x2)?"BWD":"FWD", + (pTga->blitdir == BLIT_FORWARDS)?"FWD":"BWD"); +#endif + TGASync(pScrn); /* ?? */ + + TGA_FAST_WRITE_REG(COPY | X11 | pTga->depthflag, TGA_MODE_REG); + TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); + + if(x2 > x1 && (x1 + w) > x2) + copy_func = TGACopyLineBackwards; + else + copy_func = TGACopyLineForwards; + + TGA_SAVE_OFFSET(); + if(pTga->blitdir == BLIT_FORWARDS) { + for(i = h - 1; i >= 0; i--) { /* copy from bottom to top */ + (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); + } + } + else { + for(i = 0; i < h; i++) { + (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); + } + } + + TGASync(pScrn); /* ?? */ + + TGA_GET_OFFSET(); + TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); + TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + TGA_SAVE_OFFSET(); + + return; +} + + +void +TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w) +{ + /* copy a line of width w from x1,y1 to x2,y2 using copy mode */ + int read; + unsigned long source_address, destination_address; + unsigned int mask_source, mask_destination; + int cando; + unsigned int cando_mask; + int source_align, destination_align; + int pixel_shift; +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + + cando = 32; + cando_mask = 0xFFFFFFFFU; + if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) { + cando = 16; + cando_mask = 0x0000FFFFU; + } + + source_address = FB_OFFSET(x1, y1); + destination_address = FB_OFFSET(x2, y2); +#if 0 + ErrorF("CPY-FWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx\n", + x1, y1, x2, y2, w, source_address, destination_address); +#endif + read = 0; + while (read < w) { + + mask_source = cando_mask; + if ((w - read) >= cando) + mask_destination = cando_mask; + else + mask_destination = cando_mask >> (cando - (w - read)); + + source_align = source_address & 0x07; + source_address -= source_align; + mask_source <<= source_align / pTga->Bpp; + /* mask_source &= cando_mask; */ + + destination_align = destination_address & 0x07; + destination_address -= destination_align; + mask_destination <<= destination_align / pTga->Bpp; + /* mask_destination &= cando_mask; */ + + if (destination_align >= source_align) + pixel_shift = destination_align - source_align; + else { + pixel_shift = 8 - (source_align - destination_align); + /* we need to prime the residue register in this case */ + destination_address -= 8; + mask_destination <<= 8 / pTga->Bpp; + mask_destination &= cando_mask;/* ?? */ + } + + TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); + switch (pTga->Chipset) { + case PCI_CHIP_TGA2: + *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB; + *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB; + break; + case PCI_CHIP_DEC21030: + /* use GADR and GCTR */ + TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG); + TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG); + break; + } + + source_address += (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; + destination_address += cando * pTga->Bpp; + + read += cando; + read -= destination_align / pTga->Bpp; /* "read" is perhaps better + called "written"... */ + if (destination_align < source_align) { + read -= 8 / pTga->Bpp; + } + } + + TGA_SAVE_OFFSET(); + return; +} + + +void +TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w) + /* x1, y1 = source + x2, y2 = destination + w = width + */ +{ + unsigned long a1, a2; + unsigned long source_address, destination_address; + unsigned int mask_source, mask_destination; + int cando; + unsigned int cando_mask; + int source_align, destination_align; + int pixel_shift; + int read; +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + + cando = 32; + cando_mask = 0xFFFFFFFFU; + if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) { + cando = 16; + cando_mask = 0x0000FFFFU; + } + + a1 = FB_OFFSET(x1, y1); + a2 = FB_OFFSET(x2, y2); + + source_address = FB_OFFSET((x1 + w) - cando, y1); + destination_address = FB_OFFSET((x2 + w) - cando, y2); + +#if 0 + ErrorF("CPY-BWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx" + " a1 0x%lx a2 0x%lx\n", + x1, y1, x2, y2, w, source_address, destination_address, a1, a2); +#endif + + read = 0; + while (read < w) { + mask_source = cando_mask; + if ((w - read) >= cando) + mask_destination = cando_mask; + else { + mask_destination = ((unsigned int)cando_mask) << (cando - (w - read)); + mask_destination &= cando_mask; /* esp. for cando==16 */ + } + + source_align = source_address & 0x07; + destination_align = destination_address & 0x07; + + if (read == 0 && destination_align && + (source_align > destination_align)) { + /* we want to take out all the destination_align pixels in one + little copy first, then move on to the main stuff */ + unsigned long tmp_src, tmp_dest; + unsigned int tmp_src_mask, tmp_dest_mask; + + tmp_src = a1 + (w - (source_align / pTga->Bpp)) * pTga->Bpp; + tmp_dest = a2 + (w - (destination_align / pTga->Bpp) - (8 / pTga->Bpp)) * pTga->Bpp; + tmp_src_mask = cando_mask; + tmp_dest_mask = ((unsigned int)0x000000FF) >> (8 - destination_align) / pTga->Bpp; + tmp_dest_mask <<= 8 / pTga->Bpp; + pixel_shift = (8 - source_align) + destination_align; +#if 0 + ErrorF("CPY-BWD - preliminary copy: sa = %d, da = %d, ps =%d\n", + source_align, destination_align, pixel_shift); +#endif + TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); + switch (pTga->Chipset) + { + case PCI_CHIP_TGA2: + *(unsigned int *)(pTga->FbBase + tmp_src) = tmp_src_mask; WMB; + *(unsigned int *)(pTga->FbBase + tmp_dest) = tmp_dest_mask; WMB; + break; + case PCI_CHIP_DEC21030: + /* use GADR and GCTR */ + TGA_FAST_WRITE_REG(tmp_src, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(tmp_src_mask, TGA_CONTINUE_REG); + TGA_FAST_WRITE_REG(tmp_dest, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(tmp_dest_mask, TGA_CONTINUE_REG); + break; + } + + source_address += (8 - source_align); + mask_source >>= (8 - source_align) / pTga->Bpp; + mask_source >>= destination_align / pTga->Bpp; + mask_destination >>= destination_align / pTga->Bpp; + } + else if (read == 0 && (source_align != destination_align)) { + source_address += (8 - source_align); + /* mask_source >>= (8 - source_align); */ + /* if we uncomment this, it breaks...TGA tries to + optimize away a read of our last pixels... */ + } + else if (source_align) { + source_address += (8 - source_align); + mask_source >>= (8 - source_align) / pTga->Bpp; + } + + if (destination_align) { + destination_address += (8 - destination_align); + mask_destination >>= (8 - destination_align) / pTga->Bpp; + } + + if (destination_align >= source_align) + pixel_shift = destination_align - source_align; + else { + pixel_shift = (8 - source_align) + destination_align; + if (destination_align) { + source_address += 8; + mask_source >>= 8 / pTga->Bpp; + } + } + +#if 0 + ErrorF("CPY-BWD - normal: sadr 0x%lx sm 0x%x dadr 0x%lx dm 0x%x" + " sa %d da %d ps %d read %d\n", + source_address, mask_source, + destination_address, mask_destination, + source_align, destination_align, pixel_shift, read); +#endif + TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); + switch (pTga->Chipset) { + case PCI_CHIP_TGA2: + *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB; + *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB; + break; + case PCI_CHIP_DEC21030: + /* use GADR and GCTR */ + TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG); + TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG); + break; + } + +/* if(read == 0) */ +/* ErrorF("sa = %d, da = %d, ps = %d\n", source_align, destination_align, */ +/* pixel_shift); */ + + if (destination_align > source_align) { + source_address -= cando * pTga->Bpp - 8; + destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; + if (read == 0) + read += (cando - 8 / pTga->Bpp) + source_align / pTga->Bpp; + else + read += cando - 8 / pTga->Bpp; + } + else if (destination_align == source_align) { + source_address -= cando * pTga->Bpp; + destination_address -= cando * pTga->Bpp; + if (read == 0 && destination_align) + read += (cando - (8 - destination_align) / pTga->Bpp); + else + read += cando; + } + else if (source_align > destination_align) { + source_address -= cando * pTga->Bpp - 8; + destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; + /* only happens when read == 0 */ + if (destination_align) + read += (cando - 16 / pTga->Bpp) + source_align / pTga->Bpp; + else + read += cando - pixel_shift / pTga->Bpp; + } + } + + TGA_SAVE_OFFSET(); + return; +} + +void +TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, + int fg, int bg, int rop, unsigned int planemask) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga; + unsigned int fgcolor = 0, bgcolor = 0, pmask = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + +/* ErrorF("TGASetupForMono8x8PatternFill called with patx = %d, paty = %d, fg = %d, bg = %d, rop = %d, planemask = %d\n", */ +/* patx, paty, fg, bg, rop, planemask); */ + + if(bg == -1) /* we are transparent */ + pTga->transparent_pattern_p = 1; + else + pTga->transparent_pattern_p = 0; + + if(rop == MIX_SRC) + pTga->block_or_opaque_p = USE_BLOCK_FILL; + else + pTga->block_or_opaque_p = USE_OPAQUE_FILL; + + if(pTga->depthflag == BPP8PACKED) { + fgcolor = fg | (fg << 8) | (fg << 16) | (fg << 24); + bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24); + pmask = planemask | (planemask << 8) | (planemask << 16) | + (planemask << 24); + } + else { + fgcolor = fg; + bgcolor = bg; + pmask = planemask; + } + + + if(pTga->transparent_pattern_p && + pTga->block_or_opaque_p == USE_BLOCK_FILL) { + /* we can use block fill mode to draw a transparent stipple */ + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); + if(pTga->depthflag == BPP24) { + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); + } + } + else if(pTga->transparent_pattern_p) { + TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); + } + else { + TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG); + TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); + } + pTga->current_rop = rop; + pTga->current_planemask = pmask; + TGA_SAVE_OFFSET(); + return; +} + +void +TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, + int x, int y, int w, int h) +/* patx and paty = first & second dwords of pattern to be rendered, packed */ +{ + TGAPtr pTga; + int i, j; + unsigned int stipple_mask[8], align, tmp; +#ifdef PROFILE + register unsigned int stop, start; +#endif + TGA_DECL(); + + +/* ErrorF("TGASubsequentMono8x8PatternFillRect called with x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); */ + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + + if(w > 2048) + ErrorF("TGASubsequentMono8x8PatternFillRect called with w > 2048, truncating\n"); + if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) + TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); + + TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); + if(pTga->depthflag == BPP8PACKED) + align = FB_OFFSET(x, y) % 4; + else + align = x % 4; + + for(i = 0; i < 4; i++) { + tmp = (patx >> (i * 8)) & 0xFF; + stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); + } + for(i = 4; i < 8; i++) { + tmp = (paty >> ((i - 4) * 8)) & 0xFF; + stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); + } + if(align) { /* stipples must be aligned to four bytes */ + for(i = 0; i < 8; i++) { + stipple_mask[i] = (stipple_mask[i] << align) | + ((stipple_mask[i] & 0xFF000000) >> (32 - align)); + } + } + + if((pTga->block_or_opaque_p == USE_BLOCK_FILL) && pTga->transparent_pattern_p) { + /* use block fill */ + TGA_FAST_WRITE_REG(BLOCKFILL | X11 | pTga->depthflag, TGA_MODE_REG); + + for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { + TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); + TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); + } + } + else if(pTga->transparent_pattern_p) { + /* if we can't use block fill, we'll use transparent fill */ + TGA_FAST_WRITE_REG(TRANSPARENTFILL | X11 | pTga->depthflag, TGA_MODE_REG); + for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { + TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); + TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); + } + } + else { /* use opaque fill mode */ +/* ErrorF("Using opaque fill mode\n"); */ + TGA_FAST_WRITE_REG(OPAQUEFILL | X11 | pTga->depthflag, TGA_MODE_REG); + for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { + TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); + TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); + } + } + + TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); + TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + + TGA_SAVE_OFFSET(); + + return; +} + +void +TGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga = NULL; + unsigned int fgcolor = 0, pmask = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); +/* ErrorF("TGASetupForSolidLine called\n"); */ + + if(pTga->depthflag == BPP8PACKED) { + fgcolor = color | (color << 8) | (color << 16) | (color << 24); + pmask = planemask | (planemask << 8) | (planemask << 16) | + (planemask << 24); + } + else { + fgcolor = color; + pmask = planemask; + } + + + pTga->current_rop = rop | pTga->depthflag; + TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); + pTga->current_planemask = pmask; + TGA_FAST_WRITE_REG(0xFFFF, TGA_DATA_REG); + TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG); + TGA_SAVE_OFFSET(); + + return; +} + +void +TGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, + int dir) +{ + if(dir == DEGREES_0) /* line is to the right */ + TGASubsequentSolidLine(pScrn, x, y, x + len, y, 0x0, OMIT_LAST); + else if(dir == DEGREES_270) /* line is down */ + TGASubsequentSolidLine(pScrn, x, y, x, y + len, YMAJOR, OMIT_LAST); + else + ErrorF("TGASubsequentSolidHorVertLine passed dir %d!\n", dir); + + return; +} + +void +TGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int octant, int flags) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga = NULL; + CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0; + int length = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); +/* ErrorF("TGASubsequentSolidLine called\n"); */ + + TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag | + ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), TGA_MODE_REG); + TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); + + address = FB_OFFSET(x1, y1); + TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); + abs_dx = abs(x2 - x1); + abs_dy = abs(y2 - y1); + if(octant & YMAJOR) + length = abs_dy; + else + length = abs_dx; + + if(octant & YMAJOR) { + if(octant & YDECREASING) { + if(octant & XDECREASING) + octant_reg = TGA_SLOPE0_REG; + else + octant_reg = TGA_SLOPE2_REG; + } + else { + if(octant & XDECREASING) + octant_reg = TGA_SLOPE1_REG; + else + octant_reg = TGA_SLOPE3_REG; + } + } + else { + if(octant & YDECREASING) { + if(octant & XDECREASING) + octant_reg = TGA_SLOPE4_REG; + else + octant_reg = TGA_SLOPE6_REG; + } + else { + if(octant & XDECREASING) + octant_reg = TGA_SLOPE5_REG; + else + octant_reg = TGA_SLOPE7_REG; + } + } + + TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); + if(length > 16 && length % 16) + length -= length % 16; + else + length -= 16; + + while(length > 0) { + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG); + length -= 16; + } + + TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); + TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + + TGA_SAVE_OFFSET(); + + return; +} + +void +TGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int octant) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga = NULL; + CARD32 abs_dx = 0, abs_dy = 0, octant_reg = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); +/* ErrorF("TGASetupForClippedLine called\n"); */ + +/* TGA_FAST_WRITE_REG(pTga->current_rop | BPP8PACKED, TGA_RASTEROP_REG); */ +/* TGA_FAST_WRITE_REG(OPAQUELINE | X11 | BPP8PACKED, TGA_MODE_REG); */ + + abs_dx = abs(x2 - x1); + abs_dy = abs(y2 - y1); + + if(octant & YMAJOR) { + if(octant & YDECREASING) { + if(octant & XDECREASING) + octant_reg = TGA_NOSLOPE0_REG; + else + octant_reg = TGA_NOSLOPE2_REG; + } + else { + if(octant & XDECREASING) + octant_reg = TGA_NOSLOPE1_REG; + else + octant_reg = TGA_NOSLOPE3_REG; + } + } + else { + if(octant & YDECREASING) { + if(octant & XDECREASING) + octant_reg = TGA_NOSLOPE4_REG; + else + octant_reg = TGA_NOSLOPE6_REG; + } + else { + if(octant & XDECREASING) + octant_reg = TGA_NOSLOPE5_REG; + else + octant_reg = TGA_NOSLOPE7_REG; + } + } + + TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); + + TGA_SAVE_OFFSET(); + return; +} + +void +TGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len, + int err) + /* we are already in line mode, now we need to + 1) write starting pixel address to gaddr + 2) write initial error and line length to bresenham 3 + 3) write the gctr to draw the line, and repeat for lines > 16 pixels + 4) set mode back to simple mode + */ +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga = NULL; + CARD32 address = 0; + int length = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); +/* ErrorF("TGASubsequentClippedSolidLine called\n"); */ + + address = FB_OFFSET(x1, y1); + TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); + + TGA_FAST_WRITE_REG(pTga->current_rop | pTga->depthflag, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG); + TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); + + length = len; + TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG); + + while(length > 0) { + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG); + if(length > 16 && length % 16) + length -= length % 16; + else + length -= 16; + } + + TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); + TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); + + TGA_SAVE_OFFSET(); + + return; + +} + +void +TGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern) +{ +#ifdef PROFILE + unsigned int start = 0, stop = 0; +#endif + TGAPtr pTga = NULL; + unsigned int color1 = 0, color2 = 0, pmask = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); +/* ErrorF("TGASetupForDashedLine called\n"); */ + + if(pTga->depthflag == BPP8PACKED) { + color1 = fg | (fg << 8) | (fg << 16) | (fg << 24); + color2 = bg | (bg << 8) | (bg << 16) | (bg << 24); + pmask = planemask | (planemask << 8) | (planemask << 16) + | (planemask << 24); + } + else { + color1 = fg; + color2 = fg; + pmask = planemask; + } + + pTga->current_rop = rop | pTga->depthflag; + TGA_FAST_WRITE_REG(color1, TGA_FOREGROUND_REG); + pTga->current_planemask = pmask; + if(bg == -1) /* transparent line */ + pTga->transparent_pattern_p = 1; + else { + pTga->transparent_pattern_p = 0; + TGA_FAST_WRITE_REG(color2, TGA_BACKGROUND_REG); + } + + pTga->line_pattern = pattern[0] | (pattern[1] << 8); + pTga->line_pattern_length = length; + + TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG); + TGA_SAVE_OFFSET(); + + return; +} + +void +TGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int octant, int flags, int phase) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga = NULL; + CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0; + int length = 0; + CARD16 line_mask = 0; + int pattern_overflow = 0; + int l = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); +/* ErrorF("TGASubsequentDashedLine called\n"); */ + + TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); + if(pTga->transparent_pattern_p) + TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag | + ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), + TGA_MODE_REG); + else + TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag | + ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), + TGA_MODE_REG); + + address = FB_OFFSET(x1, y1); + TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); + abs_dx = abs(x2 - x1); + abs_dy = abs(y2 - y1); + if(abs_dx > abs_dy) + length = abs_dx; + else + length = abs_dy; + + if(octant & YMAJOR) { + if(octant & YDECREASING) { + if(octant & XDECREASING) + octant_reg = TGA_SLOPE0_REG; + else + octant_reg = TGA_SLOPE2_REG; + } + else { + if(octant & XDECREASING) + octant_reg = TGA_SLOPE1_REG; + else + octant_reg = TGA_SLOPE3_REG; + } + } + else { + if(octant & YDECREASING) { + if(octant & XDECREASING) + octant_reg = TGA_SLOPE4_REG; + else + octant_reg = TGA_SLOPE6_REG; + } + else { + if(octant & XDECREASING) + octant_reg = TGA_SLOPE5_REG; + else + octant_reg = TGA_SLOPE7_REG; + } + } + /* set up our first pattern with phase. Keep track of if we overflow the + pattern by pattern_overflow, and correct on the next write */ + + if(phase) { + line_mask = pTga->line_pattern >> phase; + l = (pTga->line_pattern_length - phase); + } + else { + line_mask = pTga->line_pattern; + l = pTga->line_pattern_length; + } + + while(l < 16) { + line_mask |= pTga->line_pattern << l; + l += pTga->line_pattern_length; + } + pattern_overflow = l - 16; + + TGA_FAST_WRITE_REG(line_mask, TGA_DATA_REG); + + TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); + + if(length > 16 && length % 16) + length -= length % 16; + else + length -= 16; + + while(length > 0) { + + if(pattern_overflow) { + line_mask = pTga->line_pattern >> (pTga->line_pattern_length - + pattern_overflow); + l = pattern_overflow; + } + else { + line_mask = pTga->line_pattern; + l = pTga->line_pattern_length; + } + while(l < 16) { + line_mask |= (pTga->line_pattern << l); + l += pTga->line_pattern_length; + } + pattern_overflow = l - 16; + + TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG); + length -= 16; + } + + TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); + TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + + TGA_SAVE_OFFSET(); + + return; +} + +void +TGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len, + int err, int phase) +{ +#ifdef PROFILE + unsigned int start, stop; +#endif + TGAPtr pTga = NULL; + CARD32 address = 0; + int length = 0; + CARD16 line_mask = 0; + int pattern_overflow = 0; + int l = 0; + TGA_DECL(); + + pTga = TGAPTR(pScrn); + TGA_GET_IOBASE(); + TGA_GET_OFFSET(); + /* ErrorF("TGASubsequentClippedDashedLine called\n"); */ + + address = FB_OFFSET(x1, y1); + TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); + + TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); + + if(pTga->transparent_pattern_p) + TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag, TGA_MODE_REG); + else + TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG); + + length = len; + TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG); + + + if(phase) { + line_mask = pTga->line_pattern >> phase; + l = (pTga->line_pattern_length - phase); + } + else { + line_mask = pTga->line_pattern; + l = pTga->line_pattern_length; + } + + while(l < 16) { + line_mask |= pTga->line_pattern << l; + l += pTga->line_pattern_length; + } + pattern_overflow = l - 16; + + + while(length > 0) { + TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG); + + if(pattern_overflow) { + line_mask = pTga->line_pattern >> (pTga->line_pattern_length - + pattern_overflow); + l = pattern_overflow; + } + else { + line_mask = pTga->line_pattern; + l = pTga->line_pattern_length; + } + while(l < 16) { + line_mask |= (pTga->line_pattern << l); + l += pTga->line_pattern_length; + } + pattern_overflow = l - 16; + + if(length > 16 && length % 16) + length -= length % 16; + else + length -= 16; + } + + TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); + TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); + TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + + TGA_SAVE_OFFSET(); + + return; +} diff --git a/driver/xf86-video-tga/src/tga_cursor.c b/driver/xf86-video-tga/src/tga_cursor.c new file mode 100644 index 000000000..e61172ab6 --- /dev/null +++ b/driver/xf86-video-tga/src/tga_cursor.c @@ -0,0 +1,188 @@ +/* + * Copyright 1999 by Matthew Grossman, Seattle, USA. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of Matthew + * Grossman not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Matthew Grossman makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * MATTHEW GROSSMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL MATTHEW GROSSMAN BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Matthew Grossman, mattg@oz.net + * + * DEC TGA hardware cursor using BT485 ramdac + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c,v 1.1 1999/04/17 07:06:58 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* tga_cursor.c */ + +#include "xf86.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "BT.h" + +#include "tga.h" +#include "tga_regs.h" + +/* defines */ +/* BT485 also supports 32 bit cursor, but why use it? */ +#define CURSOR_SIZE 64 + +/* protos */ + +static void TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); +static void TGAShowCursor(ScrnInfoPtr pScrn); +static void TGAHideCursor(ScrnInfoPtr pScrn); +static void TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y); +static void TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); + +static void +TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) +{ + TGAPtr pTga = TGAPTR(pScrn); + int i; + + /* set 64 bit cursor */ + pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80); + pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); + pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04); + + /* first write address reg @ 0x0, then write 0xb with the data (for 32 bit + cursor) */ + + pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); + + for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++) + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++); + + for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++) + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++); + +/* pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); */ + + return; +} + + +static void +TGAShowCursor(ScrnInfoPtr pScrn) +{ + TGAPtr pTga = TGAPTR(pScrn); + + /* enable BT485 X11 cursor */ + pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x03); + + return; +} + + +static void +TGAHideCursor(ScrnInfoPtr pScrn) +{ + TGAPtr pTga = TGAPTR(pScrn); + + pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x00); + + return; +} + +static void +TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + TGAPtr pTga = TGAPTR(pScrn); + unsigned int tmp_x, tmp_y; + + /* translate x && y to BT485 cursor addresses */ + + tmp_x = x + CURSOR_SIZE; + tmp_x &= 0x0FFF; + + tmp_y = y + CURSOR_SIZE; + tmp_y &= 0x0FFF; + + /* write out the addresses */ + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, (tmp_x & 0xFF)); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, (tmp_x >> 8)); + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, (tmp_y & 0xFF)); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, (tmp_y >> 8)); + + return; +} + + +static void +TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) + /* set pScrn->cursor_fg and pScrn->cursor_bg */ +{ + TGAPtr pTga = TGAPTR(pScrn); + + /* first, load address register at 0x4 with 0x1, then write 3 color + octets RGB to 0x5 (background), then write three octets to 0x5 + (foreground), then write to address register 0xFC */ + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01); + + /* we don't seem to support the 6 bit DAC option as of 4.0, and why + would we? */ + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x00FF0000) >> 16); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x0000FF00) >> 8); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x000000FF)); + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x00FF0000) >> 16); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x0000FF00) >> 8); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x000000FF)); + +/* pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x00); */ + + return; +} + + +Bool +TGAHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TGAPtr pTga; + xf86CursorInfoPtr infoPtr; + + pTga = TGAPTR(pScrn); + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; + + pTga->CursorInfoRec = infoPtr; + + infoPtr->MaxWidth = CURSOR_SIZE; + infoPtr->MaxHeight = CURSOR_SIZE; + infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; + + infoPtr->SetCursorColors = TGASetCursorColors; + infoPtr->SetCursorPosition = TGASetCursorPosition; + infoPtr->LoadCursorImage = TGALoadCursorImage; + infoPtr->HideCursor = TGAHideCursor; + infoPtr->ShowCursor = TGAShowCursor; + infoPtr->UseHWCursor = NULL; + + return(xf86InitCursor(pScreen, infoPtr)); +} + diff --git a/driver/xf86-video-tga/src/tga_dac.c b/driver/xf86-video-tga/src/tga_dac.c new file mode 100644 index 000000000..81d079333 --- /dev/null +++ b/driver/xf86-video-tga/src/tga_dac.c @@ -0,0 +1,849 @@ +/* + * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_dac.c,v 1.13 2001/02/17 14:18:30 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "BT.h" +#include "tga_regs.h" +#include "tga.h" + +static void ICS1562ClockSelect(ScrnInfoPtr pScrn, int freq); +static void ICS9110ClockSelect(ScrnInfoPtr pScrn, int freq); +extern void ICS1562_CalcClockBits(long f, unsigned char *bits); + +static void +ICS1562ClockSelect(ScrnInfoPtr pScrn, int freq) +{ + TGAPtr pTga = TGAPTR(pScrn); + unsigned char pll_bits[7]; + unsigned long temp; + int i, j; + + /* There lies an ICS1562 Clock Generator. */ + ICS1562_CalcClockBits(freq, pll_bits); + + /* + * For the DEC 21030 TGA: + * This requires the 55 clock bits be written in a serial manner to + * bit 0 of the CLOCK register and on the 56th bit set the hold flag. + */ + for (i = 0;i <= 6; i++) { + for (j = 0; j <= 7; j++) { + temp = (pll_bits[i] >> (7-j)) & 1; + if (i == 6 && j == 7) + temp |= 2; + TGA_WRITE_REG(temp, TGA_CLOCK_REG); + } + } +} + +struct monitor_data tga_crystal_table[] = { +{ +/* Option 0 Monitor Info 130.8 */ +1024, /* rows */ +1280, /* columns */ +130, /* 130.8 Mhz */ +72, /* refresh rate */ +1024, /* v scanlines */ +3, /* v front porch */ +3, /* v sync */ +33, /* v back porch */ +1280, /* h pixels */ +32, /* h front porch */ +160, /* h sync */ +232, /* h back porch */ +/* AV9110 clock serial load information 130.808 */ +0x40, /* 0:6 VCO frequency divider N */ +0x7, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* IBM561 PLL setup data 130.808 */ +0xC8, /* VCO Div: PFR=0x3, M-65=49 */ +0x8 /* REF: N=0x8 */ +}, +{ +/* Option 3 Monitor Info 104.00 Mhz */ +900, /* rows */ +1152, /* columns */ +104, /* 104 Mhz */ +72, /* refresh rate */ +900, /* v scanlines */ +6, /* v front porch */ +10, /* v sync */ +44, /* v back porch */ +1152, /* h pixels */ +64, /* h front porch */ +112, /* h sync */ +176, /* h back porch */ +/* 103.994 MHz av9110 clock serial load information */ +0x6d, /* 0:6 VCO frequency divider N */ +0xf, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 104.00 MHz IBM561 PLL setup data */ +0x96, /* VCO Div: PFR=2, M=57 */ +0x6 /* REF: N=6 */ +}, +#if 1 +{ +/* Option 6 Monitor Info 74.00 Mhz */ +768, /* rows */ +1024, /* columns */ +74, /* 74 Mhz */ +72, /* refresh rate */ +768, /* v scanlines */ +1, /* v front porch */ +6, /* v sync */ +22, /* v back porch */ +1024, /* h pixels */ +16, /* h front porch */ +128, /* h sync */ +128, /* h back porch */ +/* 74.00 MHz AV9110 clock serial load information */ +0x2a, /* 0:6 VCO frequency divider N */ +0x41, /* 7:13 Reference frequency divide M */ +0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 74.00 MHz IBM561 PLL setup data */ +0x9C, /* VCO Div: PFR=2, M=0x5D*/ +0x9 /* REF: N=0x9 */ +}, +#else +{ +/* Option 5 Monitor Info 75.00 Mhz */ +768, /* rows */ +1024, /* columns */ +75, /* 74 Mhz */ +70, /* refresh rate */ +768, /* v scanlines */ +3, /* v front porch */ +6, /* v sync */ +29, /* v back porch */ +1024, /* h pixels */ +24, /* h front porch */ +136, /* h sync */ +144, /* h back porch */ +/* 75.00 MHz AV9110 clock serial load information */ +0x6e, /* 0:6 VCO frequency divider N */ +0x15, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 75.00 MHz IBM561 PLL setup data */ +0x93, /* VCO Div: PFR=2, M=0x54 */ +0x8 /* REF: N=0x8 */ +}, +#endif +{ +/* Option 9 Monitor Info 50 Mhz ergo SVGA */ +600, /* rows */ +800, /* columns */ +50, /* 50 Mhz */ +72, /* refresh rate */ +600, /* v scanlines */ +37, /*(31 tga)v front porch */ +6, /* v sync */ +23, /*(29 tga)v back porch */ +800, /* h pixels */ +56, /* h front porch */ +120, /* h sync */ +64, /* h back porch */ +/*50.00 Mhz AV9110 clock serial load information */ +0x37, /* 0:6 VCO frequency divider N */ +0x3f, /* 7:13 Reference frequency divide M */ +0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x2, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 50.00 MHz IBM561 PLL setup data */ +0x45, /* VCO Div: PFR=1, M=46*/ +0x5 /* REF: N=5 */ +}, +{ +/* Option B Monitor Info 31.5 Mhz ergo VGA */ +480, /* rows */ +640, /* columns */ +32, /* 32 Mhz */ +72, /* refresh rate */ +480, /* v scanlines */ +9, /* v front porch */ +3, /* v sync */ +28, /* v back porch */ +640, /* h pixels */ +24, /* h front porch */ +40, /* h sync */ +128, /* h back porch */ +/* 31.50 MHz AV9110 clock serial load information */ +0x16, /* 0:6 VCO frequency divider N */ +0x05, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x2, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 31.50 MHz IBM561 PLL setup data */ +0x17, /* VCO Div: PFR=0, M=0x58 */ +0x5 /* REF: N=0x5 */ +}, +#ifdef ALLOW_LT_72_HZ +{ +/* Option 1 Monitor Info 119.84 Mhz */ +1024, /* rows */ +1280, /* columns */ +119, /* 119 Mhz */ +66, /* refresh rate */ +1024, /* v scanlines */ +3, /* v front porch */ +3, /* v sync */ +33, /* v back porch */ +1280, /* h pixels */ +32, /* h front porch */ +160, /* h sync */ +232, /* h back porch */ +/* 119.84MHz AV9110 clock serial load information */ +0x2d, /* 0:6 VCO frequency divider N */ +0x2b, /* 7:13 Reference frequency divide M */ +0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) */ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* IBM561 PLL setup data 119.84 */ +0x82, /* VCO Div: PFR=0x2, M=0x43 */ +0x4 /* REF: N=0x4 */ +}, +{ +/* Option 2 Monitor Info 108.18 Mhz */ +1024, /* rows */ +1280, /* columns */ +108, /* 108 Mhz */ +60, /* refresh rate */ +1024, /* v scanlines */ +3, /* v front porch */ +3, /* v sync */ +26, /* v back porch */ +1280, /* h pixels */ +44, /* h front porch */ +184, /* h sync */ +200, /* h back porch */ +/* 108.18 MHz av9110 Clk serial load information */ +0x11, /* 0:6 VCO frequency divider N */ +0x9, /* 7:13 Reference frequency divide M */ +0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x2, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 108.18 MHz IBM561 PLL setup data */ +0xB8, /* VCO Div: PFR=2, M=79 */ +0x8 /* REF: N=0x8 */ +}, +{ +/* Option 5 Monitor Info 75.00 Mhz */ +768, /* rows */ +1024, /* columns */ +75, /* 74 Mhz */ +70, /* refresh rate */ +768, /* v scanlines */ +3, /* v front porch */ +6, /* v sync */ +29, /* v back porch */ +1024, /* h pixels */ +24, /* h front porch */ +136, /* h sync */ +144, /* h back porch */ +/* 75.00 MHz AV9110 clock serial load information */ +0x6e, /* 0:6 VCO frequency divider N */ +0x15, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 75.00 MHz IBM561 PLL setup data */ +0x93, /* VCO Div: PFR=2, M=0x54 */ +0x8 /* REF: N=0x8 */ +}, +{ +/* Option 7 Monitor Info 69 Mhz DEC 72 Hz */ +864, /* rows */ +1024, /* columns */ +69, /* 69.x Mhz */ +60, /* refresh rate */ +864, /* v scanlines */ +0, /* v front porch */ +3, /* v sync */ +34, /* v back porch */ +1024, /* h pixels */ +12, /* h front porch */ +128, /* h sync */ +116, /* h back porch */ +/* 69.00 Mhz AV9110 clock serial load information */ +0x35, /* 0:6 VCO frequency divider N */ +0xb, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 69.00 MHz IBM561 PLL setup data */ +0xA9, /* VCO Div: PFR=2, M=0x6A */ +0xB /* REF: N=0xB */ +}, +{ +/* Option 8 Monitor Info 65 Mhz */ +768, /* rows */ +1024, /* columns */ +65, /* 65 Mhz */ +60, /* refresh rate */ +768, /* v scanlines */ +7, /* v front porch */ +9, /* v sync */ +26, /* v back porch */ +1024, /* h pixels */ +56, /* h front porch */ +64, /* h sync */ +200, /* h back porch */ +/* 65.00 MHz AV9110 clock serial load information */ +0x6d, /* 0:6 VCO frequency divider N */ +0x0c, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x2, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 65.00 MHz IBM561 PLL setup data */ +0xAC, /* VCO Div: PFR=2, M=0x6D */ +0xC /* REF: N=0xC */ +}, +{ +/* Option A Monitor Info 40 Mhz SVGA */ +600, /* rows */ +800, /* columns */ +40, /* 40 Mhz */ +60, /* refresh rate */ +600, /* v scanlines */ +1, /* v front porch */ +4, /* v sync */ +23, /* v back porch */ +800, /* h pixels */ +40, /* h front porch */ +128, /* h sync */ +88, /* h back porch */ +/* 40.00 MHz AV9110 clock serial load information */ +0x5f, /* 0:6 VCO frequency divider N */ +0x11, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x2, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 40.00 MHz IBM561 PLL setup data */ +0x42, /* VCO Div: PFR=1, M=43 */ +0x6 /* REF: N=0x6 */ +}, +{ +/* Option C Monitor Info 25.175 Mhz VGA */ +480, /* rows */ +640, /* columns */ +25, /* 25.175 Mhz */ +60, /* refresh rate */ +480, /* v scanlines */ +10, /* v front porch */ +2, /* v sync */ +33, /* v back porch */ +640, /* h pixels */ +16, /* h front porch */ +96, /* h sync */ +48, /* h back porch */ +/* 25.175 MHz AV9110 clock serial load information */ +0x66, /* 0:6 VCO frequency divider N */ +0x1d, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x2, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 25.175 MHz IBM561 PLL setup data */ +0x3E, /* VCO Div: PFR=0, M=0x7F */ +0x9 /* REF: N=0x9 */ +}, +{ +/* Option E Monitor Info 110 Mhz */ +1024, /* rows */ +1280, /* columns */ +110, +60, /* refresh rate */ +1024, /* v scanlines */ +6, /* v front porch */ +7, /* v sync */ +44, /* v back porch */ +1280, /* h pixels */ +19, /* h front porch */ +163, /* h sync */ +234, /* h back porch */ +/* 110.0 MHz AV9110 clock serial load information */ +0x60, /* 0:6 VCO frequency divider N */ +0x32, /* 7:13 Reference frequency divide M */ +0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) */ +0x1, /* 15:16 CLK/X output divide X */ +0x2, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 110.0 MHz IBM561 PLL setup data */ +0xBA, /* VCO Div: PFR=0x2, M=0x7B */ +0x8 /* REF: N=0x8 */ +}, +#endif /* ALLOW_LT_72_HZ */ +#ifdef ALLOW_GT_72_HZ +{ +/* Option D Monitor Info 135 Mhz */ +1024, /* rows */ +1280, /* columns */ +135, /* 135 Mhz */ +75, /* refresh rate */ +1024, /* v scanlines */ +1, /* v front porch */ +3, /* v sync */ +38, /* v back porch */ +1280, /* h pixels */ +16, /* h front porch */ +144, /* h sync */ +248, /* h back porch */ +/* 135.0 MHz AV9110 clock serial load information */ +0x42, /* 0:6 VCO frequency divider N */ +0x07, /* 7:13 Reference frequency divide M */ +0x0, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) */ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 135.0 MHz IBM561 PLL setup data */ +0xC1, /* VCO Div: PFR=0x3, M=0x42 */ +0x7 /* REF: N=0x7 */ +}, +#ifdef ALLOW_GT_1280x1024 +{ +/* Option 4 Monitor Info 175.5 Mhz (8-plane) */ +1200, /* rows */ +1600, /* columns */ +175, /* clock */ +65, /* refresh rate */ +1200, /* v scanlines */ +1, /* v front porch */ +3, /* v sync */ +46, /* v back porch */ +1600, /* h pixels */ +32, /* h front porch */ +192, /* h sync */ +336, /* h back porch */ +/* 110.0 MHz AV9110 clock serial load information */ +0x5F, /* 0:6 VCO frequency divider N */ +0x3E, /* 7:13 Reference frequency divide M */ +0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) +*/ +0x1, /* 15:16 CLK/X output divide X */ +0x1, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 110.0 MHz IBM561 PLL setup data */ +0xE1, /* VCO Div: PFR=0x3, M-65=0x21 */ +0x8 /* REF: N=0x8 */ +}, +{ +/* Option F Monitor Info (24-plane) */ +1200, /* rows */ +1600, /* columns */ +202.5, /* 130.8 Mhz */ +75, /* refresh rate */ +1200, /* v scanlines */ +1, /* v front porch */ +3, /* v sync */ +46, /* v back porch */ +1600, /* h pixels */ +32, /* h front porch */ +192, /* h sync */ +336, /* h back porch */ +/* AV9110 clock serial load information 130.808 */ +0x60, /* 0:6 VCO frequency divider N */ +0x32, /* 7:13 Reference frequency divide M */ +0x1, /* 14 VCO pre-scale divide V (0=div.by 1,1=by 8) */ +0x1, /* 15:16 CLK/X output divide X */ +0x2, /* 17:18 VCO output divide R */ +1, /* 19 CLK Output enable. */ +1, /* 20 CLK/X Output enable */ +0, /* reserved, should be set to 0 */ +0, /* Reference clock select on CLK 1=ref */ +1, /* reserved, should be set to 1 */ +/* 110.0 MHz IBM561 PLL setup data */ +0xE2, /* bogus VCO Div: PFR=0x2, M=0x7B */ +0x7 /* bogus REF: N=0x8 */ +} +#endif /* ALLOW_GT_1280x1024 */ +#endif /* ALLOW_GT_72_HZ */ +}; + +int tga_crystal_table_entries = sizeof(tga_crystal_table)/sizeof(struct monitor_data); + +struct monitor_data *tga_c_table; + +/* ICS av9110 is only used on TGA2 */ + +void +write_av9110(ScrnInfoPtr pScrn, unsigned int *temp) +{ + TGAPtr pTga = TGAPTR(pScrn); + + /* the following is based on write_av9110() from the + TRU64 kernel TGA driver */ + + TGA2_WRITE_CLOCK_REG(0x0, 0xf800); + TGA2_WRITE_CLOCK_REG(0x0, 0xf000); + + TGA2_WRITE_CLOCK_REG(temp[0], 0x0000); + TGA2_WRITE_CLOCK_REG(temp[1], 0x0000); + TGA2_WRITE_CLOCK_REG(temp[2], 0x0000); + TGA2_WRITE_CLOCK_REG(temp[3], 0x0000); + TGA2_WRITE_CLOCK_REG(temp[4], 0x0000); + TGA2_WRITE_CLOCK_REG(temp[5], 0x0000); + + TGA2_WRITE_CLOCK_REG(0x0, 0xf800); +} + +void TGA2SetupMode(ScrnInfoPtr pScrn) +{ + int i; + + /* + * HACK HACK HACK + * + * We do not know how to generate arbitrary clocks, so we search + * the crystal_table above for a match. Sigh... + */ + tga_c_table = tga_crystal_table; + for (i = 0; i < tga_crystal_table_entries; i++, tga_c_table++) { + if ((tga_c_table->max_rows == pScrn->currentMode->VDisplay) && + (tga_c_table->max_cols == pScrn->currentMode->HDisplay)) { + ErrorF("Found a matching mode (%d)!\n", i); + break; + } + } + if (i == tga_crystal_table_entries) { +#ifdef FOR_NOW + FatalError("Unable to find a workable mode"); +#else + ErrorF("Unable to find a matching mode!\n"); + /* tga_c_table = &tga_crystal_table[4]; *//* 640x480 @ 72 */ + tga_c_table = &tga_crystal_table[2]; /* 1024x768 @ 72 */ +#endif + } + return; +} + +static void +ICS9110ClockSelect(ScrnInfoPtr pScrn, int freq) +{ + unsigned int temp, temp1[6]; + + /* There lies an ICS9110 Clock Generator. */ + /* ICS9110_CalcClockBits(freq, pll_bits); */ + + /* the following is based on munge_ics() from the + TRU64 kernel TGA driver */ + + temp = (unsigned int)(tga_c_table->vco_div | + (tga_c_table->ref_div << 7) | + (tga_c_table->vco_pre << 14) | + (tga_c_table->clk_div << 15) | + (tga_c_table->vco_out_div << 17) | + (tga_c_table->clk_out_en << 19) | + (tga_c_table->clk_out_enX << 20) | + (tga_c_table->res0 << 21) | + (tga_c_table->clk_sel << 22) | + (tga_c_table->res1 << 23)); + + temp1[0] = (temp & 0x00000001) | ((temp & 0x00000002) << 7) | + ((temp & 0x00000004) << 14) | ((temp & 0x00000008) << 21); + + temp1[1] = ((temp & 0x00000010) >> 4) | ((temp & 0x00000020) << 3) | + ((temp & 0x00000040) << 10) | ((temp & 0x00000080) << 17); + + temp1[2] = ((temp & 0x00000100) >> 8) | ((temp & 0x00000200) >> 1) | + ((temp & 0x00000400) << 6) | ((temp & 0x00000800) << 13); + + temp1[3] = ((temp & 0x00001000) >> 12) | ((temp & 0x00002000) >> 5) | + ((temp & 0x00004000) << 2) | ((temp & 0x00008000) << 9); + + temp1[4] = ((temp & 0x00010000) >> 16) | ((temp & 0x00020000) >> 9) | + ((temp & 0x00040000) >> 2) | ((temp & 0x00080000) << 5); + + temp1[5] = ((temp & 0x00100000) >> 20) | ((temp & 0x00200000) >> 13) | + ((temp & 0x00400000) >> 6) | ((temp & 0x00800000) << 1); + + write_av9110(pScrn, temp1); + +} + +void +Ibm561Init(TGAPtr pTga) +{ + unsigned char *Ibm561 = pTga->Ibm561modeReg; + int i, j; + +/* ?? FIXME FIXME FIXME FIXME */ + + /* Command registers */ + Ibm561[0] = 0x40; Ibm561[1] = 0x08; + Ibm561[2] = (pTga->SyncOnGreen ? 0x80 : 0x00); + + /* Read mask */ + Ibm561[3] = 0xff; Ibm561[4] = 0xff; Ibm561[5] = 0xff; Ibm561[6] = 0x0f; + + /* Blink mask */ + Ibm561[7] = 0x00; Ibm561[8] = 0x00; Ibm561[9] = 0x00; Ibm561[10] = 0x00; + + /* Window attributes */ + for (i = 0, j=11; i < 16; i++) { + Ibm561[j++] = 0x00; Ibm561[j++] = 0x01; Ibm561[j++] = 0x80; + } +} + +void +Bt463Init(TGAPtr pTga) +{ + unsigned char *Bt463 = pTga->Bt463modeReg; + int i, j; + + /* Command registers */ + Bt463[0] = 0x40; Bt463[1] = 0x08; + Bt463[2] = (pTga->SyncOnGreen ? 0x80 : 0x00); + + /* Read mask */ + Bt463[3] = 0xff; Bt463[4] = 0xff; Bt463[5] = 0xff; Bt463[6] = 0x0f; + + /* Blink mask */ + Bt463[7] = 0x00; Bt463[8] = 0x00; Bt463[9] = 0x00; Bt463[10] = 0x00; + + /* Window attributes */ + for (i = 0, j=11; i < 16; i++) { + Bt463[j++] = 0x00; Bt463[j++] = 0x01; Bt463[j++] = 0x80; + } +} + +Bool +DEC21030Init(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + TGAPtr pTga = TGAPTR(pScrn); + TGARegPtr pReg = &pTga->ModeReg; + + if (pTga->RamDac != NULL) { /* this really means 8-bit and BT485 */ + RamDacHWRecPtr pBT = RAMDACHWPTR(pScrn); + RamDacRegRecPtr ramdacReg = &pBT->ModeReg; + + ramdacReg->DacRegs[BT_COMMAND_REG_0] = 0xA0 | + (!pTga->Dac6Bit ? 0x2 : 0x0) | (pTga->SyncOnGreen ? 0x8 : 0x0); +#if 1 + ramdacReg->DacRegs[BT_COMMAND_REG_2] = 0x20; +#else + ramdacReg->DacRegs[BT_COMMAND_REG_2] = 0x27; /* ?? was 0x20 */ +#endif + ramdacReg->DacRegs[BT_STATUS_REG] = 0x14; + (*pTga->RamDac->SetBpp)(pScrn, ramdacReg); + + } else { + switch (pTga->Chipset) { + case PCI_CHIP_DEC21030: /* always BT463 */ + Bt463Init(pTga); + break; + case PCI_CHIP_TGA2: /* always IBM 561 */ + Ibm561Init(pTga); + break; + } + } + + pReg->tgaRegs[0x00] = mode->CrtcHDisplay; + pReg->tgaRegs[0x01] = mode->CrtcHSyncStart - mode->CrtcHDisplay; + pReg->tgaRegs[0x02] = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 4; + pReg->tgaRegs[0x03] = (mode->CrtcHTotal - mode->CrtcHSyncEnd) / 4; + pReg->tgaRegs[0x04] = mode->CrtcVDisplay; + pReg->tgaRegs[0x05] = mode->CrtcVSyncStart - mode->CrtcVDisplay; + pReg->tgaRegs[0x06] = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + pReg->tgaRegs[0x07] = mode->CrtcVTotal - mode->CrtcVSyncEnd; + + /* + * We do polarity the Step B way of the 21030 + * Tell me how I can detect a Step A, and I'll support that too. + * But I think that the Step B's are most common + */ + if (mode->Flags & V_PHSYNC) + pReg->tgaRegs[0x08] = 1; /* Horizontal Polarity */ + else + pReg->tgaRegs[0x08] = 0; + + if (mode->Flags & V_PVSYNC) + pReg->tgaRegs[0x09] = 1; /* Vertical Polarity */ + else + pReg->tgaRegs[0x09] = 0; + + pReg->tgaRegs[0x0A] = mode->Clock; + + pReg->tgaRegs[0x10] = (((pReg->tgaRegs[0x00]) / 4) & 0x1FF) | + ((((pReg->tgaRegs[0x00]) / 4) & 0x600) << 19) | + (((pReg->tgaRegs[0x01]) / 4) << 9) | + (pReg->tgaRegs[0x02] << 14) | + (pReg->tgaRegs[0x03] << 21) | +#if 0 + (1 << 31) | /* ?? */ +#endif + (pReg->tgaRegs[0x08] << 30); + pReg->tgaRegs[0x11] = pReg->tgaRegs[0x04] | + (pReg->tgaRegs[0x05] << 11) | + (pReg->tgaRegs[0x06] << 16) | + (pReg->tgaRegs[0x07] << 22) | + (pReg->tgaRegs[0x09] << 30); + + pReg->tgaRegs[0x12] = 0x01; + + pReg->tgaRegs[0x13] = 0x0000; + return TRUE; +} + +void +DEC21030Save(ScrnInfoPtr pScrn, TGARegPtr tgaReg) +{ + TGAPtr pTga = TGAPTR(pScrn); + + tgaReg->tgaRegs[0x10] = TGA_READ_REG(TGA_HORIZ_REG); + tgaReg->tgaRegs[0x11] = TGA_READ_REG(TGA_VERT_REG); + tgaReg->tgaRegs[0x12] = TGA_READ_REG(TGA_VALID_REG); + tgaReg->tgaRegs[0x13] = TGA_READ_REG(TGA_BASE_ADDR_REG); + + return; +} + +void +DEC21030Restore(ScrnInfoPtr pScrn, TGARegPtr tgaReg) +{ + TGAPtr pTga = TGAPTR(pScrn); + + TGA_WRITE_REG(0x00, TGA_VALID_REG); /* Disable Video */ + + switch (pTga->Chipset) { + case PCI_CHIP_DEC21030: + ICS1562ClockSelect(pScrn, tgaReg->tgaRegs[0x0A]); + break; + case PCI_CHIP_TGA2: + ICS9110ClockSelect(pScrn, tgaReg->tgaRegs[0x0A]); + break; + } + + TGA_WRITE_REG(tgaReg->tgaRegs[0x10], TGA_HORIZ_REG); + TGA_WRITE_REG(tgaReg->tgaRegs[0x11], TGA_VERT_REG); + TGA_WRITE_REG(tgaReg->tgaRegs[0x13], TGA_BASE_ADDR_REG); + + TGA_WRITE_REG(tgaReg->tgaRegs[0x12], TGA_VALID_REG); /* Re-enable Video */ + + return; +} diff --git a/driver/xf86-video-tga/src/tga_driver.c b/driver/xf86-video-tga/src/tga_driver.c new file mode 100644 index 000000000..5f6dc1ebc --- /dev/null +++ b/driver/xf86-video-tga/src/tga_driver.c @@ -0,0 +1,1767 @@ +/* + * Copyright 1997,1998 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * Matthew Grossman, <mattg@oz.net> - acceleration and misc fixes + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c,v 1.60tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +/* everybody includes these */ +#include "xf86.h" +#include "xf86_OSproc.h" + +/* PCI headers */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +/* module versioning */ +#include "xf86Version.h" + +/* RAC stuff */ +#include "xf86Resources.h" + +/* #include "vgaHW.h" */ + +/* software cursor */ +#include "mipointer.h" +/* backing store */ +#include "mibstore.h" + +/* #include "mibank.h" */ +/* colormap manipulation */ +#include "micmap.h" + +#include "fb.h" + +/* more RAC stuff */ +#include "xf86RAC.h" + +/* Gamma Correction? */ +#include "xf86cmap.h" + +#include "tga_regs.h" +#include "BT.h" +#include "tga.h" + +#ifdef XFreeXDGA +#define _XF86DGA_SERVER_ +#include <X11/extensions/xf86dgastr.h> +#endif + +#include "globals.h" +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "xf86xv.h" +#include <X11/extensions/Xv.h> + +static const OptionInfoRec * TGAAvailableOptions(int chipid, int busid); +static void TGAIdentify(int flags); +static Bool TGAProbe(DriverPtr drv, int flags); +static Bool TGAPreInit(ScrnInfoPtr pScrn, int flags); +static Bool TGAScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool TGAEnterVT(int scrnIndex, int flags); +static void TGALeaveVT(int scrnIndex, int flags); +static Bool TGACloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool TGASaveScreen(ScreenPtr pScreen, int mode); + +/* Required if the driver supports mode switching */ +static Bool TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +/* Required if the driver supports moving the viewport */ +static void TGAAdjustFrame(int scrnIndex, int x, int y, int flags); + +/* Optional functions */ +static void TGAFreeScreen(int scrnIndex, int flags); +static ModeStatus TGAValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flags); + +/* Internally used functions */ +static Bool TGAMapMem(ScrnInfoPtr pScrn); +static Bool TGAUnmapMem(ScrnInfoPtr pScrn); +static void TGASave(ScrnInfoPtr pScrn); +static void TGARestore(ScrnInfoPtr pScrn); +static Bool TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); + +static void TGARestoreHWCursor(ScrnInfoPtr pScrn); + +static void TGADisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, + int flags); + +void TGASync(ScrnInfoPtr pScrn); + +#define TGA_VERSION 4000 +#define TGA_NAME "TGA" +#define TGA_DRIVER_NAME "tga" +#define TGA_MAJOR_VERSION 1 +#define TGA_MINOR_VERSION 1 +#define TGA_PATCHLEVEL 0 + +/* + * This contains the functions needed by the server after loading the driver + * module. It must be supplied, and gets passed back by the SetupProc + * function in the dynamic case. In the static case, a reference to this + * is compiled in, and this requires that the name of this DriverRec be + * an upper-case version of the driver name. + */ + +_X_EXPORT DriverRec TGA = { + TGA_VERSION, + TGA_DRIVER_NAME, + TGAIdentify, + TGAProbe, + TGAAvailableOptions, + NULL, + 0 +}; + +static SymTabRec TGAChipsets[] = { + { PCI_CHIP_DEC21030, "tga" }, + { PCI_CHIP_TGA2, "tga2" }, + { -1, NULL } +}; + +static PciChipsets TGAPciChipsets[] = { + { PCI_CHIP_DEC21030, PCI_CHIP_DEC21030, NULL }, + { PCI_CHIP_TGA2, PCI_CHIP_TGA2, NULL }, + { -1, -1, RES_UNDEFINED } +}; + +typedef enum { + OPTION_SW_CURSOR, + OPTION_HW_CURSOR, + OPTION_PCI_RETRY, + OPTION_RGB_BITS, + OPTION_NOACCEL, + OPTION_SYNC_ON_GREEN, + OPTION_DAC_6_BIT, + OPTION_NOXAAPOLYSEGMENT +} TGAOpts; + +static const OptionInfoRec TGAOptions[] = { + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE }, + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_6_BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NOXAAPOLYSEGMENT, "NoXaaPolySegment",OPTV_BOOLEAN,{0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static RamDacSupportedInfoRec BTramdacs[] = { + { BT485_RAMDAC }, + { -1 } +}; + +static const char *ramdacSymbols[] = { + "BTramdacProbe", + "RamDacCreateInfoRec", + "RamDacDestroyInfoRec", + "RamDacFreeRec", + "RamDacGetHWIndex", + "RamDacHandleColormaps", + "RamDacInit", + "xf86CreateCursorInfoRec", + "xf86InitCursor", + NULL +}; + +static const char *xaaSymbols[] = { + "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAGetGCIndex", + "XAAInit", + NULL +}; + +static const char *fbSymbols[] = { + "fbPictureInit", + "fbScreenInit", + NULL +}; + +#ifdef XFree86LOADER + +static MODULESETUPPROTO(tgaSetup); + +static XF86ModuleVersionInfo tgaVersRec = +{ + "tga", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + TGA_MAJOR_VERSION, TGA_MINOR_VERSION, TGA_PATCHLEVEL, + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0,0,0,0} +}; + +_X_EXPORT XF86ModuleData tgaModuleData = { &tgaVersRec, tgaSetup, NULL }; + +pointer +tgaSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&TGA, module, 0); + + /* + * Modules that this driver always requires can be loaded here + * by calling LoadSubModule(). + */ + + LoaderRefSymLists(ramdacSymbols, fbSymbols, xaaSymbols, NULL); + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (pointer)1; + } else { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +#endif /* XFree86LOADER */ + +static unsigned int fb_offset_presets[4] = { + TGA_8PLANE_FB_OFFSET, + TGA_24PLANE_FB_OFFSET, + 0xffffffff, + TGA_24PLUSZ_FB_OFFSET +}; + +static char *tga_cardnames[4] = { + "TGA 8 Plane", + "TGA 24 Plane", + NULL, + "TGA 24 Plane 3D" +}; + +static Bool +TGAGetRec(ScrnInfoPtr pScrn) +{ + /* + * Allocate an TGARec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + if (pScrn->driverPrivate != NULL) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(TGARec), 1); + /* Initialise it */ + + + return TRUE; +} + +static void +TGAFreeRec(ScrnInfoPtr pScrn) +{ + TGAPtr pTga; + + if (pScrn->driverPrivate == NULL) + return; + + pTga = TGAPTR(pScrn); + + if(pTga->buffers[0]) + free(pTga->buffers[0]); + + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + + return; +} + +static const OptionInfoRec * +TGAAvailableOptions(int chipid, int busid) +{ + return TGAOptions; +} + +/* Mandatory */ +static void +TGAIdentify(int flags) +{ + xf86PrintChipsets(TGA_NAME, "driver for Digital chipsets", TGAChipsets); + return; +} + + +/* Mandatory */ +static Bool +TGAProbe(DriverPtr drv, int flags) +{ + int i; + GDevPtr *devSections; + int *usedChips; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + + /* + * The aim here is to find all cards that this driver can handle, + * and for the ones not already claimed by another driver, claim the + * slot, and allocate a ScrnInfoRec. + * + * This should be a minimal probe, and it should under no circumstances + * change the state of the hardware. Because a device is found, don't + * assume that it will be used. Don't do any initialisations other than + * the required ScrnInfoRec initialisations. Don't allocate any new + * data structures. + */ + + /* + * Next we check, if there has been a chipset override in the config file. + * For this we must find out if there is an active device section which + * is relevant, i.e., which has no driver specified or has THIS driver + * specified. + */ + + if ((numDevSections = xf86MatchDevice(TGA_DRIVER_NAME, + &devSections)) <= 0) { + /* + * There's no matching device section in the config file, so quit + * now. + */ + return FALSE; + } + + /* + * We need to probe the hardware first. We then need to see how this + * fits in with what is given in the config file, and allow the config + * file info to override any contradictions. + */ + + /* + * All of the cards this driver supports are PCI, so the "probing" just + * amounts to checking the PCI data that the server has already collected. + */ + if (xf86GetPciVideoInfo() == NULL) { + /* + * We won't let anything in the config file override finding no + * PCI video cards at all. This seems reasonable now, but we'll see. + */ + return FALSE; + } + + numUsed = xf86MatchPciInstances(TGA_NAME, PCI_VENDOR_DIGITAL, + TGAChipsets, TGAPciChipsets, devSections, numDevSections, + drv, &usedChips); + + xfree(devSections); + if (numUsed <= 0) + return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + /* + * Check that nothing else has claimed the slots. + */ + ScrnInfoPtr pScrn = NULL; + + /* Allocate a ScrnInfoRec and claim the slot */ + if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + TGAPciChipsets, NULL, NULL, + NULL, NULL, NULL))) { + /* Fill in what we can of the ScrnInfoRec */ + pScrn->driverVersion = TGA_VERSION; + pScrn->driverName = TGA_DRIVER_NAME; + pScrn->name = TGA_NAME; + pScrn->Probe = TGAProbe; + pScrn->PreInit = TGAPreInit; + pScrn->ScreenInit = TGAScreenInit; + pScrn->SwitchMode = TGASwitchMode; + pScrn->AdjustFrame = TGAAdjustFrame; + pScrn->EnterVT = TGAEnterVT; + pScrn->LeaveVT = TGALeaveVT; + pScrn->FreeScreen = TGAFreeScreen; + pScrn->ValidMode = TGAValidMode; + foundScreen = TRUE; + } + } + xfree(usedChips); + return foundScreen; +} + +#if 0 +/* + * GetAccelPitchValues - + * + * This function returns a list of display width (pitch) values that can + * be used in accelerated mode. + */ +static int * +GetAccelPitchValues(ScrnInfoPtr pScrn) +{ + int *linePitches = NULL; + int i, n = 0; + int *linep = NULL; + /* TGAPtr pTga = TGAPTR(pScrn); */ + + for (i = 0; linep[i] != 0; i++) { + if (linep[i] != -1) { + n++; + linePitches = xnfrealloc(linePitches, n * sizeof(int)); + linePitches[n - 1] = i << 5; + } + } + + /* Mark the end of the list */ + if (n > 0) { + linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int)); + linePitches[n] = 0; + } + return linePitches; +} +#endif /* 0 */ + +/* Mandatory */ +static Bool +TGAPreInit(ScrnInfoPtr pScrn, int flags) +{ + pciVideoPtr pciPtr; + TGAPtr pTga; + MessageType from; + int i; + ClockRangePtr clockRanges; + pointer Base; + + if (flags & PROBE_DETECT) return FALSE; + + /* + * Note: This function is only called once at server startup, and + * not at the start of each server generation. This means that + * only things that are persistent across server generations can + * be initialised here. xf86Screens[] is (pScrn is a pointer to one + * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() + * are too, and should be used for data that must persist across + * server generations. + * + * Per-generation data should be allocated with + * AllocateScreenPrivateIndex() from the ScreenInit() function. + */ + + /* The ramdac module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "ramdac")) + return FALSE; + + xf86LoaderReqSymLists(ramdacSymbols, NULL); + + /* Allocate the TGARec driverPrivate */ + if (!TGAGetRec(pScrn)) { + return FALSE; + } + pTga = TGAPTR(pScrn); + + /* Set pScrn->monitor */ + pScrn->monitor = pScrn->confScreen->monitor; + + /********************* + Handle pci and chipset stuff + *********************/ + + + /* This driver doesn't expect more than one entity per screen */ + if (pScrn->numEntities > 1) + return FALSE; + /* This is the general case */ + for (i = 0; i < pScrn->numEntities; i++) { + pTga->pEnt = xf86GetEntityInfo(pScrn->entityList[i]); + if (pTga->pEnt->resources) return FALSE; + pTga->Chipset = pTga->pEnt->chipset; + pScrn->chipset = (char *)xf86TokenToString(TGAChipsets, + pTga->pEnt->chipset); + + /* TGA is purely PCI */ + if (pTga->pEnt->location.type == BUS_PCI) { + pciPtr = xf86GetPciInfoForEntity(pTga->pEnt->index); + pTga->PciInfo = pciPtr; + pTga->PciTag = pciTag(pTga->PciInfo->bus, + pTga->PciInfo->device, + pTga->PciInfo->func); + } + else + return FALSE; + } + + /* + * This shouldn't happen because such problems should be caught in + * TGAProbe(), but check it just in case. + */ + if (pScrn->chipset == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04X is not recognised\n", pTga->Chipset); + return FALSE; + } + if (pTga->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognised\n", pScrn->chipset); + return FALSE; + } + + from = X_PROBED; + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); + + pTga->PciTag = pciTag(pTga->PciInfo->bus, pTga->PciInfo->device, + pTga->PciInfo->func); + + + + /********************* + deal with depth and framebuffer size + *********************/ + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { + return FALSE; + } else { + /* Check that the returned depth is one we support */ + switch (pScrn->depth) { + case 8: + case 24: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } + } + + /* we can do option processing now */ + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + /* Process the options */ + if (!(pTga->Options = xalloc(sizeof(TGAOptions)))) + return FALSE; + memcpy(pTga->Options, TGAOptions, sizeof(TGAOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTga->Options); + if (xf86ReturnOptValBool(pTga->Options, OPTION_PCI_RETRY, FALSE)) { + pTga->UsePCIRetry = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); + } + + if(xf86ReturnOptValBool(pTga->Options, OPTION_SYNC_ON_GREEN, FALSE)) { + pTga->SyncOnGreen = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n"); + } + + if(xf86ReturnOptValBool(pTga->Options, OPTION_DAC_6_BIT, FALSE)) { + pTga->Dac6Bit = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "6 bit DAC enabled\n"); + } + + if(xf86ReturnOptValBool(pTga->Options, OPTION_NOXAAPOLYSEGMENT, FALSE)) { + pTga->NoXaaPolySegment = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XAA PolySegment() disabled\n"); + } + + /* end option processing */ + + /* + * This must happen after pScrn->display has been set because + * xf86SetWeight references it. + */ + if (pScrn->depth > 8) { + /* The defaults are OK for us */ + rgb zeros = {0, 0, 0}; + + if (!xf86SetWeight(pScrn, zeros, zeros)) { + return FALSE; + } else { + /* XXX check that weight returned is supported */ + ; + } + } + + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } else { + /* We don't currently support DirectColor at > 8bpp */ + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + } + + /* + * The new cmap code requires this to be initialised. + */ + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + /* Set the bits per RGB for 8bpp mode */ + if (pScrn->depth == 8) { + /* Default to 8 */ + pScrn->rgbBits = 8; + if(pTga->Dac6Bit) + pScrn->rgbBits = 6; + } + from = X_DEFAULT; + + /* determine whether we use hardware or software cursor */ + + pTga->HWCursor = TRUE; + if (xf86GetOptValBool(pTga->Options, OPTION_HW_CURSOR, &pTga->HWCursor)) + from = X_CONFIG; + if (xf86ReturnOptValBool(pTga->Options, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pTga->HWCursor = FALSE; + } + + if(pScrn->depth != 8) { + pTga->HWCursor = FALSE; + from = X_WARNING; + xf86DrvMsg(pScrn->scrnIndex, from, + "Hardware cursor currently only works with BT485 ramdac\n"); + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pTga->HWCursor ? "HW" : "SW"); + + if (xf86ReturnOptValBool(pTga->Options, OPTION_NOACCEL, FALSE)) { + pTga->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } + + if (pTga->pEnt->device->MemBase != 0) { + pTga->CardAddress = pTga->pEnt->device->MemBase; + from = X_CONFIG; + } else { + pTga->CardAddress = pTga->PciInfo->memBase[0] & 0xFFC00000;/*??*/ + } + + pTga->FbAddress = pTga->CardAddress; + /* Adjust MMIO region */ + pTga->IOAddress = pTga->CardAddress + TGA_REGS_OFFSET; + + + /********************* + determine what sort of TGA card we have -- the only differences are + framebuffer size and ramdac type, all TGA cards use 21030 chips + *********************/ + + /* check what the user has specified in XF86Config */ + if(pTga->pEnt->device->videoRam) { + switch(pTga->pEnt->device->videoRam) { + case 2048: + pTga->CardType = TYPE_TGA_8PLANE; + break; + case 8192: + pTga->CardType = TYPE_TGA_24PLANE; + break; + case 16384: + pTga->CardType = TYPE_TGA_24PLUSZ; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "%d KB video RAM specified, driver only supports 2048, 8192, or 16384 KB cards\n", + pTga->pEnt->device->videoRam); + return FALSE; + } + } + else { /* try to divine the amount of RAM */ + switch (pTga->Chipset) + { + case PCI_CHIP_TGA2: + Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, + pTga->PciTag, pTga->IOAddress, 0x1000); + pTga->CardType = (*(unsigned int *)((char *)Base+TGA_REVISION_REG) >> 21) & 0x3; + pTga->CardType ^= (pTga->CardType == 1) ? 0 : 3; + xf86UnMapVidMem(pScrn->scrnIndex, Base, 0x1000); + break; + case PCI_CHIP_DEC21030: + Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, + pTga->PciTag, pTga->FbAddress, 4); + pTga->CardType = (*(unsigned int *)Base >> 12) & 0xf; + xf86UnMapVidMem(pScrn->scrnIndex, Base, 4); + break; + } + } + + switch (pTga->CardType) { + case TYPE_TGA_8PLANE: + case TYPE_TGA_24PLANE: + case TYPE_TGA_24PLUSZ: + xf86DrvMsg(pScrn->scrnIndex, from, "Card Name: \"%s\"\n", + tga_cardnames[pTga->CardType]); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Card \"0x%02x\" is not recognised\n", pTga->CardType); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Assuming 8 plane TGA with 2MB frame buffer\n"); + pTga->CardType = TYPE_TGA_8PLANE; + break; + } + + /* Adjust framebuffer for card type */ + pTga->FbAddress += fb_offset_presets[pTga->CardType]; + + if (!(((pScrn->depth == 8) && (pTga->CardType == TYPE_TGA_8PLANE)) || + ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLANE)) || + ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLUSZ)))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this card\n", + pScrn->depth); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + (unsigned long)pTga->FbAddress); + + xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", + (unsigned long)pTga->IOAddress); + + /* RAC stuff: we don't have any resources we need to reserve, + but we should do this here anyway */ + if (xf86RegisterResources(pTga->pEnt->index, NULL, ResExclusive)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86RegisterResources() found resource conflicts\n"); + TGAFreeRec(pScrn); + return FALSE; + } + + + + /* HW bpp matches reported bpp */ + pTga->HwBpp = pScrn->bitsPerPixel; + + if (pTga->pEnt->device->videoRam != 0) { + pScrn->videoRam = pTga->pEnt->device->videoRam; + from = X_CONFIG; + } else { + switch (pTga->CardType) { + case TYPE_TGA_8PLANE: + pScrn->videoRam = 2*1024; + break; + case TYPE_TGA_24PLANE: + pScrn->videoRam = 8*1024; + break; + case TYPE_TGA_24PLUSZ: + pScrn->videoRam = 16*1024; + break; + } + } + + xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", + pScrn->videoRam); + + pTga->FbMapSize = pScrn->videoRam * 1024; + + if (xf86LoadSubModule(pScrn, "fb") == NULL) { + TGAFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(fbSymbols, NULL); + + /* Load XAA if needed */ + if (!pTga->NoAccel || pTga->HWCursor) { + if (!xf86LoadSubModule(pScrn, "xaa")) { + TGAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(xaaSymbols, NULL); + } + + + /********************* + Let's check what type of DAC we have and reject if necessary + *********************/ + + pTga->RamDac = NULL; + + if (pTga->CardType != TYPE_TGA_8PLANE) { + pTga->RamDacRec = NULL; + pTga->RamDac = NULL; + } else { + + pTga->RamDacRec = RamDacCreateInfoRec(); + switch (pTga->Chipset) + { + case PCI_CHIP_DEC21030: + pTga->RamDacRec->ReadDAC = tgaBTInIndReg; + pTga->RamDacRec->WriteDAC = tgaBTOutIndReg; + pTga->RamDacRec->ReadAddress = tgaBTReadAddress; + pTga->RamDacRec->WriteAddress = tgaBTWriteAddress; + pTga->RamDacRec->ReadData = tgaBTReadData; + pTga->RamDacRec->WriteData = tgaBTWriteData; + break; + case PCI_CHIP_TGA2: + pTga->RamDacRec->ReadDAC = tga2BTInIndReg; + pTga->RamDacRec->WriteDAC = tga2BTOutIndReg; + pTga->RamDacRec->ReadAddress = tga2BTReadAddress; + pTga->RamDacRec->WriteAddress = tga2BTWriteAddress; + pTga->RamDacRec->ReadData = tga2BTReadData; + pTga->RamDacRec->WriteData = tga2BTWriteData; + break; + } + + if (!RamDacInit(pScrn, pTga->RamDacRec)) { + RamDacDestroyInfoRec(pTga->RamDacRec); + return FALSE; + } + + TGAMapMem(pScrn); + + pTga->RamDac = BTramdacProbe(pScrn, BTramdacs); + + TGAUnmapMem(pScrn); + + if (pTga->RamDac == NULL) + return FALSE; + } + + /********************* + set up clock and mode stuff + *********************/ + + pScrn->progClock = TRUE; + + /* Set the min pixel clock */ + pTga->MinClock = 16250; /* XXX Guess, need to check this */ + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", + pTga->MinClock / 1000); + + /* + * If the user has specified ramdac speed in the XF86Config + * file, we respect that setting. + */ + if (pTga->pEnt->device->dacSpeeds[0]) { + int speed = 0; + + switch (pScrn->bitsPerPixel) { + case 8: + speed = pTga->pEnt->device->dacSpeeds[DAC_BPP8]; + break; + case 32: + speed = pTga->pEnt->device->dacSpeeds[DAC_BPP32]; + break; + } + if (speed == 0) + pTga->MaxClock = pTga->pEnt->device->dacSpeeds[0]; + else + pTga->MaxClock = speed; + from = X_CONFIG; + } else { + switch (pTga->Chipset) { + case PCI_CHIP_DEC21030: + pTga->MaxClock = 135000; + break; + case PCI_CHIP_TGA2: + pTga->MaxClock = 170000; + break; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", + pTga->MaxClock / 1000); + + /* + * Setup the ClockRanges, which describe what clock ranges are available, + * and what sort of modes they can be used for. + */ + clockRanges = xnfcalloc(sizeof(ClockRange), 1); + clockRanges->next = NULL; + clockRanges->minClock = pTga->MinClock; + clockRanges->maxClock = pTga->MaxClock; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = FALSE; /* XXX check this */ + clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ + + if(pScrn->display->virtualX || pScrn->display->virtualY) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "TGA does not support a virtual desktop\n"); + pScrn->display->virtualX = 0; + pScrn->display->virtualY = 0; + } + + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and + * pScrn->maxVValue are set. Since our TGAValidMode() already takes + * care of this, we don't worry about setting them here. + */ + /* Select valid modes from those available */ + /* + * XXX Assuming min pitch 256, max 2048 + * XXX Assuming min height 128, max 2048 + */ + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + NULL, 256, 2048, + pScrn->bitsPerPixel, 128, 2048, + pScrn->display->virtualX, + pScrn->display->virtualY, + pTga->FbMapSize, + LOOKUP_BEST_REFRESH); + + if (i == -1) { + TGAFreeRec(pScrn); + return FALSE; + } + + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + TGAFreeRec(pScrn); + return FALSE; + } + + if(i > 1) { + DisplayModePtr mp1 = NULL, mp2 = NULL; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "TGA only supports one mode, using first mode.\n"); + mp1 = pScrn->modes->next; + mp2 = mp1; + while(mp1 && mp1->next != mp1) { + mp1 = mp1->next; + xf86DeleteMode(&(pScrn->modes), mp2); + mp2 = mp1; + } + } + + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + + /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; + + /* + This is a bit of a hack; we seem to have to init + the TGA2 chipset knowing what the mode is, so we + do this now as soon as we know it... + */ + if (pTga->Chipset == PCI_CHIP_TGA2) { + TGA2SetupMode(pScrn); + } + + /* Print the list of modes being used */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + return TRUE; +} + + +/* + * Map the framebuffer and MMIO memory. + */ + +static Bool +TGAMapMem(ScrnInfoPtr pScrn) +{ + TGAPtr pTga; + + pTga = TGAPTR(pScrn); + + /* + * Map IO registers to virtual address space + */ + + /* TGA doesn't need a sparse memory mapping, because all register + accesses are doublewords */ + + pTga->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, + pTga->PciTag, + pTga->IOAddress, 0x100000); + if (pTga->IOBase == NULL) + return FALSE; + + pTga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + pTga->PciTag, + (unsigned long)pTga->FbAddress, + pTga->FbMapSize); + if (pTga->FbBase == NULL) + return FALSE; + + if (pTga->Chipset == PCI_CHIP_DEC21030) + return TRUE; + + pTga->ClkBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, + pTga->PciTag, + (unsigned long)pTga->CardAddress + TGA2_CLOCK_OFFSET, + 0x10000); + if (pTga->ClkBase == NULL) + return FALSE; + + pTga->DACBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, + pTga->PciTag, + (unsigned long)pTga->CardAddress + TGA2_RAMDAC_OFFSET, + 0x10000); + if (pTga->DACBase == NULL) + return FALSE; + + /* + * This is a hack specifically for the TGA2 code, as it sometimes + * calculates/uses addresses in TGA2 memory which are NOT mmapped + * by the normal framebuffer code above. This most frequently occurs + * when displaying something close to the top-left corner (in the + * routines CopyLine{Forwards,Backwards}. + * + * This could most likely also be fixed by further modifying the + * code, but it (the code) is ugly enough already... ;-} + * + * So, the workaround is to simply mmap an additional PAGE of + * framebuffer memory in front of the normal mmap to prevent + * SEGVs from happening. + */ + pTga->HACKBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + pTga->PciTag, + (unsigned long)pTga->FbAddress - getpagesize(), + getpagesize()); + if (pTga->HACKBase == NULL) + return FALSE; + + return TRUE; +} + + +/* + * Unmap the framebuffer and MMIO memory. + */ + +static Bool +TGAUnmapMem(ScrnInfoPtr pScrn) +{ + TGAPtr pTga; + + pTga = TGAPTR(pScrn); + + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->IOBase, 0x100000); + pTga->IOBase = NULL; + + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->FbBase, pTga->FbMapSize); + pTga->FbBase = NULL; + + if (pTga->Chipset == PCI_CHIP_DEC21030) + return TRUE; + + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->ClkBase, 0x10000); + pTga->ClkBase = NULL; + + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->DACBase, 0x10000); + pTga->DACBase = NULL; + + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->HACKBase, getpagesize()); + pTga->HACKBase = NULL; + + return TRUE; +} + + +/* + * This function saves the video state. + */ +static void +TGASave(ScrnInfoPtr pScrn) +{ + TGAPtr pTga; + TGARegPtr tgaReg; + RamDacHWRecPtr pBT; + RamDacRegRecPtr BTreg; + + pTga = TGAPTR(pScrn); + tgaReg = &pTga->SavedReg; + + DEC21030Save(pScrn, tgaReg); + if (pTga->RamDac) { /* must be BT485... */ + pBT = RAMDACHWPTR(pScrn); + BTreg = &pBT->SavedReg; + (*pTga->RamDac->Save)(pScrn, pTga->RamDacRec, BTreg); + } else switch (pTga->Chipset) + { + case PCI_CHIP_TGA2: + IBM561ramdacSave(pScrn, pTga->Ibm561saveReg); + break; + case PCI_CHIP_DEC21030: + BT463ramdacSave(pScrn, pTga->Bt463saveReg); + break; + } +} + + +/* + * Initialise a new mode. This is currently still using the old + * "initialise struct, restore/write struct to HW" model. That could + * be changed. + */ + +static Bool +TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + int ret = -1; + TGAPtr pTga; + TGARegPtr tgaReg; + RamDacHWRecPtr pBT; + RamDacRegRecPtr BTreg; + + pTga = TGAPTR(pScrn); + + pScrn->vtSema = TRUE; + + ret = DEC21030Init(pScrn, mode); + + if (pTga->Chipset == PCI_CHIP_TGA2 && pTga->RamDac == NULL) + IBM561ramdacHWInit(pScrn); + + if (!ret) + return FALSE; + + /* Program the registers */ + tgaReg = &pTga->ModeReg; + + DEC21030Restore(pScrn, tgaReg); + + if (pTga->RamDac != NULL) { + pBT = RAMDACHWPTR(pScrn); + BTreg = &pBT->ModeReg; + (*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg); + if (pTga->Chipset == PCI_CHIP_TGA2) { + pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); + pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x0c); + } + pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff); + } else { + switch (pTga->Chipset) { + case PCI_CHIP_TGA2: + IBM561ramdacRestore(pScrn, pTga->Ibm561modeReg); + break; + case PCI_CHIP_DEC21030: + BT463ramdacRestore(pScrn, pTga->Bt463modeReg); + break; + } + } + return TRUE; +} + +/* + * Restore the initial (text) mode. + */ +static void +TGARestore(ScrnInfoPtr pScrn) +{ + TGAPtr pTga; + TGARegPtr tgaReg; + RamDacHWRecPtr pBT; + RamDacRegRecPtr BTreg; + + pTga = TGAPTR(pScrn); + tgaReg = &pTga->SavedReg; + + /* Initial Text mode clock */ + tgaReg->tgaRegs[0x0A] = 25175; + + DEC21030Restore(pScrn, tgaReg); + + if (pTga->RamDac != NULL) { + pBT = RAMDACHWPTR(pScrn); + BTreg = &pBT->SavedReg; + (*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg); + if (pTga->Chipset == PCI_CHIP_TGA2) { + pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); + pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x00); + } + pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff); + } else switch (pTga->Chipset) { + case PCI_CHIP_TGA2: + IBM561ramdacRestore(pScrn, pTga->Ibm561saveReg); + break; + case PCI_CHIP_DEC21030: + BT463ramdacRestore(pScrn, pTga->Bt463saveReg); + break; + } + + if (pTga->HWCursor) + TGARestoreHWCursor(pScrn); +} + + +/* Mandatory */ + +/* This gets called at the start of each server generation */ + +static Bool +TGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn; + TGAPtr pTga; + int ret; + VisualPtr visual; + + /* + * First get the ScrnInfoRec + */ + pScrn = xf86Screens[pScreen->myNum]; + pTga = TGAPTR(pScrn); + + /* Map the TGA memory and MMIO areas */ + if (!TGAMapMem(pScrn)) + return FALSE; + +#if 1 + /* dump original register contents */ + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MODE 0x%x\n", + TGA_READ_REG(TGA_MODE_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VALID 0x%x\n", + TGA_READ_REG(TGA_VALID_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DEEP 0x%x\n", + TGA_READ_REG(TGA_DEEP_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXSH 0x%x\n", + TGA_READ_REG(TGA_PIXELSHIFT_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ROP 0x%x\n", + TGA_READ_REG(TGA_RASTEROP_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "HORIZ 0x%x\n", + TGA_READ_REG(TGA_HORIZ_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VERT 0x%x\n", + TGA_READ_REG(TGA_VERT_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXMSK 0x%x\n", + TGA_READ_REG(TGA_PIXELMASK_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "REV 0x%x\n", + TGA_READ_REG(TGA_REVISION_REG)); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VADDR 0x%x\n", + TGA_READ_REG(TGA_BASE_ADDR_REG)); +#endif + + /* Save the current state */ + TGASave(pScrn); + + /* Initialise the first mode */ + TGAModeInit(pScrn, pScrn->currentMode); + + /* Darken the screen for aesthetic reasons and set the viewport */ + TGASaveScreen(pScreen, SCREEN_SAVER_ON); + + /* + * The next step is to setup the screen's visuals, and initialise the + * framebuffer code. In cases where the framebuffer's default + * choices for things like visual layouts and bits per RGB are OK, + * this may be as simple as calling the framebuffer's ScreenInit() + * function. If not, the visuals will need to be setup before calling + * a fb ScreenInit() function and fixed up after. + * + * For most PC hardware at depths >= 8, the defaults that fb uses + * are not appropriate. In this driver, we fixup the visuals after. + */ + + /* + * Reset visual list. + */ + miClearVisualTypes(); + + /* Setup the visuals we support. */ + + /* + * For bpp > 8, the default visuals are not acceptable because we only + * support TrueColor and not DirectColor. To deal with this, call + * miSetVisualTypes for each visual supported. + */ + + if (pScrn->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, + pScrn->defaultVisual)) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + } + + miSetPixmapDepths (); + + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ + + switch (pScrn->bitsPerPixel) { + case 8: + case 32: + ret = fbScreenInit(pScreen, pTga->FbBase, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, pScrn->bitsPerPixel); + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in TGAScrnInit\n", + pScrn->bitsPerPixel); + ret = FALSE; + break; + } + if (!ret) + return FALSE; + + xf86SetBlackWhitePixels(pScreen); + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + /* must be after RGB ordering fixed */ + + fbPictureInit (pScreen, 0, 0); + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); + + /* we should ALWAYS do this */ + if (pScrn->bitsPerPixel == 8) { + TGA_WRITE_REG(SIMPLE | X11 | BPP8PACKED, TGA_MODE_REG); + TGA_WRITE_REG(0x3 | BPP8PACKED, TGA_RASTEROP_REG); + if (pTga->Chipset == PCI_CHIP_TGA2) + TGA_WRITE_REG(2 << 28, TGA_DEEP_REG); + } else { + TGA_WRITE_REG(SIMPLE | X11 | BPP24, TGA_MODE_REG); + TGA_WRITE_REG(0x3 | BPP24, TGA_RASTEROP_REG); + if (pTga->Chipset == PCI_CHIP_TGA2) + TGA_WRITE_REG((7 << 2) | 1 | (2 << 28), TGA_DEEP_REG); + } + TGA_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); + TGA_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); + + if (!pTga->NoAccel) { + switch (pTga->Chipset) + { + case PCI_CHIP_TGA2: + case PCI_CHIP_DEC21030: + if(DEC21030AccelInit(pScreen) == FALSE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "XAA Initialization failed\n"); + return(FALSE); + } + break; + } + } + + /* Initialise cursor functions */ + miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); + + /* Initialize HW cursor layer. + Must follow software cursor initialization*/ + if (pTga->HWCursor) { + if(!TGAHWCursorInit(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + return(FALSE); + } + } + + + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) + return FALSE; + + if ((pScrn->bitsPerPixel==8) && + (!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits, + CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))) + return FALSE; + + pTga->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = TGACloseScreen; + pScreen->SaveScreen = TGASaveScreen; + + if(xf86DPMSInit(pScreen, TGADisplayPowerManagementSet, 0) == FALSE) + ErrorF("DPMS initialization failed!\n"); + + { + XF86VideoAdaptorPtr *ptr; + int n; + + pScrn->memPhysBase = pTga->FbAddress; + pScrn->fbOffset = 0; + + n = xf86XVListGenericAdaptors(pScrn,&ptr); + + if(n) { + xf86XVScreenInit(pScreen, ptr, n); + } + + } + + /* Report any unused options (only for the first generation) */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } + + /* unblank the screen */ + TGASaveScreen(pScreen, SCREEN_SAVER_OFF); + + /* Done */ + return TRUE; +} + + +/* Usually mandatory */ +static Bool +TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return TGAModeInit(xf86Screens[scrnIndex], mode); +} + + +/* + * This function is used to initialize the Start Address - the first + * displayed location in the video memory. + */ +/* Usually mandatory */ +static void +TGAAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + /* we don't support virtual desktops, because TGA doesn't have the + ability to set the start of the visible framebuffer at an arbitrary + pixel */ + return; +} + +/* + * This is called when VT switching back to the X server. Its job is + * to reinitialise the video mode. + * + * We may wish to unmap video/MMIO memory too. + */ + +/* Mandatory */ +static Bool +TGAEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + /* Should we re-save the text mode on each VT enter? */ + if (!TGAModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + return TRUE; +} + + +/* + * This is called when VT switching away from the X server. Its job is + * to restore the previous (text) mode. + * + * We may wish to remap video/MMIO memory too. + */ + +/* Mandatory */ +static void +TGALeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +/* TGAPtr pTga = TGAPTR(pScrn); */ + + TGARestore(pScrn); + + /* no longer necessary with new VT switching code */ +/* memset(pTga->FbBase, 0, pTga->FbMapSize); */ + return; +} + + +/* + * This is called at the end of each server generation. It restores the + * original (text) mode. + */ + +/* Mandatory */ +static Bool +TGACloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + TGAPtr pTga = TGAPTR(pScrn); + + TGARestore(pScrn); + /* memset(pTga->FbBase, 0, pScrn->videoRam * 1024); */ + TGASync(pScrn); + TGAUnmapMem(pScrn); + + if(pTga->AccelInfoRec) + XAADestroyInfoRec(pTga->AccelInfoRec); + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = pTga->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + + +/* Free up any per-generation data structures */ + +/* Optional */ +static void +TGAFreeScreen(int scrnIndex, int flags) +{ + RamDacFreeRec(xf86Screens[scrnIndex]); + TGAFreeRec(xf86Screens[scrnIndex]); +} + + +/* Checks if a mode is suitable for the selected chipset. */ + +/* Optional */ +static ModeStatus +TGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + if (mode->Flags & V_INTERLACE) + return(MODE_BAD); + + return(MODE_OK); +} + +/* Do screen blanking */ + +/* Mandatory */ +static Bool +TGASaveScreen(ScreenPtr pScreen, int mode) + /* this function should blank the screen when unblank is FALSE and + unblank it when unblank is TRUE -- it doesn't actually seem to be + used for much though */ +{ + TGAPtr pTga; + ScrnInfoPtr pScrn; + int valid_reg = 0; + Bool unblank; + + pScrn = xf86Screens[pScreen->myNum]; + pTga = TGAPTR(pScrn); + valid_reg = TGA_READ_REG(TGA_VALID_REG); + valid_reg &= 0xFFFFFFFC; + + unblank = xf86IsUnblank(mode); + + if(unblank == FALSE) + valid_reg |= 0x3; + else /* this function is sometimes called w/1 || 2 as TRUE */ + valid_reg |= 0x1; + + TGA_WRITE_REG(valid_reg, TGA_VALID_REG); + +/* ErrorF("TGASaveScreen called\n"); */ + + return TRUE; +} + + +/* + * TGADisplayPowerManagementSet -- + * + * Sets VESA Display Power Management Signaling (DPMS) Mode. + */ +static void +TGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, + int flags) +{ + TGAPtr pTga; + int valid_reg = 0; + + pTga = TGAPTR(pScrn); + valid_reg = TGA_READ_REG(TGA_VALID_REG); + valid_reg &= 0xFFFFFFFC; + + switch(PowerManagementMode) { + case DPMSModeOn: + /* HSync: On, VSync: On */ + valid_reg |= 0x1; + break; + case DPMSModeStandby: + case DPMSModeSuspend: + /* TGA gives us a function to blank the screen while maintaining sync... + I guess we can just use that here... */ + valid_reg |= 0x3; + break; + case DPMSModeOff: + valid_reg |= 0x2; + break; + default: + ErrorF("Invalid PowerManagementMode %d passed to TGADisplayPowerManagementSet\n", PowerManagementMode); + break; + } + + TGA_WRITE_REG(valid_reg, TGA_VALID_REG); + return; +} + +static void +TGARestoreHWCursor(ScrnInfoPtr pScrn) + /* + from tga.c in the linux kernel...may not work for BSD... + when the cursor is restored, it is one line down from where it should + be...this is disconcerting, but purely cosmetic. Unfortunately reading + in the cursor framebuffer doesn't seem to work, I get a bunch of junk + at the beginning...other than that, see tga_cursor.c + I believe this to be a problem with the linux kernel code. + Hmm...this seems to be a 2.0.* problem, 2.2 works ok + */ +{ + unsigned char *p = NULL; + int i = 0; + TGAPtr pTga; + + /* Making this static prevents EGCS from compiling memset code + to initialize it, which was causing a problem. */ + static const CARD32 tga_cursor_source[128] = { + 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, + 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, + 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, + 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, + 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, + 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, + 0x000000ff, 0x00000000, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + + /* this is the linux console hw cursor...what about the bsd console? */ + /* what about tgafb? */ + pTga = TGAPTR(pScrn); + + /* we want to move the cursor off the screen before we do anything with it + otherwise, there is a "ghost cursor" that shows up */ + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, 0); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, 0); + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, 0); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, 0); + + + /* set a windows cursor -- oddly, this doesn't seem necessary */ + pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x02); + + /* set a 64 bit cursor */ +/* pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80); */ +/* pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); */ +/* pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04); */ + + /* set the colors */ + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01); + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa); + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); + + + /* load the console cursor */ + pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); + p = (unsigned char *)tga_cursor_source; + for(i = 0; i < 512; i++) + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *p++); + for(i = 0; i < 512; i++) + pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, 0xff); + + return; +} + + +/* + * This is the implementation of the Sync() function. + */ +void +TGASync(ScrnInfoPtr pScrn) +{ + TGAPtr pTga = TGAPTR(pScrn); + unsigned int stat; + + switch (pTga->Chipset) + { + case PCI_CHIP_TGA2: + /* This code is weird, but then so is TGA2... ;-} */ + mem_barrier(); + while((stat = TGA_READ_REG(TGA_CMD_STAT_REG))) { + if (((stat >> 8) & 0xff) == ((stat >> 16) & 0xff)) { + TGA_WRITE_REG(0, TGA_CMD_STAT_REG); + mem_barrier(); +#if 0 +ErrorF("TGASync: writing CMD_STATUS\n"); +#endif + } + usleep(1000); + } + break; + + case PCI_CHIP_DEC21030: +#if 0 + /* I'm experiencing lockups which could be due to this function. + We don't seem to need it anyway... + */ + while (TGA_READ_REG(TGA_CMD_STAT_REG) & 0x01); +#endif + break; + } + + return; +} + diff --git a/driver/xf86-video-tga/src/tga_line.c b/driver/xf86-video-tga/src/tga_line.c new file mode 100644 index 000000000..c8b364980 --- /dev/null +++ b/driver/xf86-video-tga/src/tga_line.c @@ -0,0 +1,632 @@ +/* $XFree86: $ */ + +/* + * Copyright 1999 by Matthew Grossman, Seattle, USA. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of Matthew + * Grossman not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Matthew Grossman makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * MATTHEW GROSSMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL MATTHEW GROSSMAN BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Matthew Grossman, mattg@oz.net + * + */ + +/* tga_line.c */ +/* accelerated solid and dashed lines */ +/* adapted from xaa/xaaLine.c */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/X.h> +#include "misc.h" +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "miline.h" +#include "xf86str.h" +#include "xaa.h" +#include "xaalocal.h" + +/* #include "tga.h" */ +#include "tga_regs.h" + +/* line functions */ +extern void +TGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +extern void +TGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, + int dir); +extern void +TGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int octant, int flags); +extern void +TGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int octant); +extern void +TGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len, + int err); + +extern void +TGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern); +extern void +TGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, + int octant, int flags, int phase); +extern void +TGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len, + int err, int phase); + + +extern void +TGASync(ScrnInfoPtr pScrn); + +void TGAPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, + xSegment *pSeg); +void TGAPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit); +void TGAPolySegmentDashed(DrawablePtr pDrawable, GCPtr pGC, int nseg, + xSegment *pSeg); +void TGAPolyLinesDashed(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit); + + +void +#ifdef POLYSEGMENT +TGAPolySegment( + DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pSeg +#else + TGAPolyLines( + DrawablePtr pDrawable, + GCPtr pGC, + int mode, /* Origin or Previous */ + int npt, /* number of points */ + DDXPointPtr pptInit +#endif + ){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip); + int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip); + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + int xorg = pDrawable->x; + int yorg = pDrawable->y; + int nbox; + BoxPtr pbox; +#ifndef POLYSEGMENT + DDXPointPtr ppt; +#endif + int x1, x2, y1, y2, tmp, len; + +#ifdef POLYSEGMENT +/* ErrorF("TGAPolySegment called!\n"); */ +#else +/* ErrorF("TGAPolyLines called\n"); */ +#endif + + if(!nboxInit) + return; + /****************/ + /* TGA FUNCTION */ + /****************/ + TGASetupForSolidLine(infoRec->pScrn, pGC->fgPixel, pGC->alu, + pGC->planemask); + +#ifdef POLYSEGMENT + while (nseg--) +#else + ppt = pptInit; + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; + while(--npt) +#endif + { + nbox = nboxInit; + pbox = pboxInit; + +#ifdef POLYSEGMENT + x1 = pSeg->x1 + xorg; + y1 = pSeg->y1 + yorg; + x2 = pSeg->x2 + xorg; + y2 = pSeg->y2 + yorg; + pSeg++; +#else + x1 = x2; + y1 = y2; + ++ppt; + if (mode == CoordModePrevious) { + xorg = x1; + yorg = y1; + } + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; +#endif + + if (x1 == x2) { /* vertical line */ + /* make the line go top to bottom of screen, keeping + endpoint semantics + */ + if (y1 > y2) { + tmp = y2; + y2 = y1 + 1; + y1 = tmp + 1; +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) y1--; +#endif + } +#ifdef POLYSEGMENT + else if (pGC->capStyle != CapNotLast) y2++; +#endif + /* get to first band that might contain part of line */ + while(nbox && (pbox->y2 <= y1)) { + pbox++; + nbox--; + } + + /* stop when lower edge of box is beyond end of line */ + while(nbox && (y2 >= pbox->y1)) { + if ((x1 >= pbox->x1) && (x1 < pbox->x2)) { + tmp = max(y1, pbox->y1); + len = min(y2, pbox->y2) - tmp; + if (len) + TGASubsequentSolidHorVertLine(infoRec->pScrn, x1, tmp, + len, DEGREES_270); + } + nbox--; + pbox++; + } +#ifndef POLYSEGMENT + y2 = ppt->y + yorg; +#endif + } else if (y1 == y2) { /* horizontal line */ + /* force line from left to right, keeping endpoint semantics */ + if (x1 > x2) { + tmp = x2; + x2 = x1 + 1; + x1 = tmp + 1; +#ifdef POLYSEGMENT + if (pGC->capStyle != CapNotLast) x1--; +#endif + } +#ifdef POLYSEGMENT + else if (pGC->capStyle != CapNotLast) x2++; +#endif + + /* find the correct band */ + while(nbox && (pbox->y2 <= y1)) { + pbox++; + nbox--; + } + + /* try to draw the line, if we haven't gone beyond it */ + if (nbox && (pbox->y1 <= y1)) { + int orig_y = pbox->y1; + /* when we leave this band, we're done */ + while(nbox && (orig_y == pbox->y1)) { + if (pbox->x2 <= x1) { + /* skip boxes until one might contain start point */ + nbox--; + pbox++; + continue; + } + + /* stop if left of box is beyond right of line */ + if (pbox->x1 >= x2) { + nbox = 0; + break; + } + + tmp = max(x1, pbox->x1); + len = min(x2, pbox->x2) - tmp; + if (len) + TGASubsequentSolidHorVertLine(infoRec->pScrn, tmp, + y1, len, DEGREES_0); + nbox--; + pbox++; + } + } +#ifndef POLYSEGMENT + x2 = ppt->x + xorg; +#endif + } else{ /* sloped line */ + unsigned int oc1, oc2; + int dmin, dmaj, e, octant; + + + if((dmaj = x2 - x1) < 0) { + dmaj = -dmaj; + octant = XDECREASING; + } else octant = 0; + + if((dmin = y2 - y1) < 0) { + dmin = -dmin; + octant |= YDECREASING; + } + + if(dmin >= dmaj){ + tmp = dmin; dmin = dmaj; dmaj = tmp; + octant |= YMAJOR; + } + + e = -dmaj - ((bias >> octant) & 1); + len = dmaj; + dmin *= 2; + dmaj *= 2; + + + while(nbox--) { + oc1 = oc2 = 0; + OUTCODES(oc1, x1, y1, pbox); + OUTCODES(oc2, x2, y2, pbox); + if (!(oc1 | oc2)) { /* unclipped */ + TGASubsequentSolidLine(infoRec->pScrn, x1, y1, x2, y2, + octant, +#ifdef POLYSEGMENT + (pGC->capStyle != CapNotLast) ? 0 : +#endif + OMIT_LAST + ); + break; + } else if (oc1 & oc2) { /* completely clipped */ + pbox++; + + } else { /* partially clipped */ + int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; + int clip1 = 0, clip2 = 0; + int err, adx, ady; + + if(octant & YMAJOR) { + ady = dmaj /= 2; + adx = dmin /= 2; + } else { + ady = dmin /= 2; + adx = dmaj /= 2; + } + + if (miZeroClipLine(pbox->x1, pbox->y1, + pbox->x2 - 1, pbox->y2 - 1, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, &clip1, &clip2, + octant, bias, oc1, oc2) == -1) + { + pbox++; + continue; + } + + if (octant & YMAJOR) + len = abs(new_y2 - new_y1); + else + len = abs(new_x2 - new_x1); +#ifdef POLYSEGMENT + if (clip2 != 0 || pGC->capStyle != CapNotLast) + len++; +#else + len += (clip2 != 0); +#endif + if (len) { /* we have a real line */ + int abserr, clipdx, clipdy; + + /* unwind bresenham error term to first point */ + if (clip1) { + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + + if (octant & YMAJOR) + err = e + clipdy*dmin - clipdx*dmaj; + else + err = e + clipdx*dmin - clipdy*dmaj; + } else + err = e; + +#define range infoRec->SolidBresenhamLineErrorTermBits + abserr = abs(err); + while((abserr & range) || + (dmaj & range) || + (dmin & range)) { + dmin /= 2; + dmaj /= 2; + abserr /= 2; + err /= 2; + } + TGASetupForClippedLine(infoRec->pScrn, x1, y1, x2, + y2, octant); + TGASubsequentClippedSolidLine(infoRec->pScrn, + new_x1, new_y1, len, + err); + + + } + pbox++; + } + } /* while (nbox--) */ + } /* sloped line */ + } /* while (nline--) */ + +#ifndef POLYSEGMENT + /* paint the last point if the end style isn't CapNotLast. + (Assume that a projecting, butt, or round cap that is one + pixel wide is the same as the single pixel of the endpoint.) + */ + + if ((pGC->capStyle != CapNotLast) && + ((ppt->x + xorg != pptInit->x + pDrawable->x) || + (ppt->y + yorg != pptInit->y + pDrawable->y) || + (ppt == pptInit + 1))) + { + nbox = nboxInit; + pbox = pboxInit; + while (nbox--) + { + if ((x2 >= pbox->x1) && (y2 >= pbox->y1) && + (x2 < pbox->x2) && (y2 < pbox->y2)) + { + TGASubsequentSolidHorVertLine(infoRec->pScrn, x2, y2, 1, + DEGREES_0); + break; + } + else + pbox++; + } + } +#endif + + TGASync(infoRec->pScrn); + return; +} + +#undef range + + void +#ifdef POLYSEGMENT + TGAPolySegmentDashed( + DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pSeg +#else + TGAPolyLinesDashed( + DrawablePtr pDrawable, + GCPtr pGC, + int mode, /* Origin or Previous */ + int npt, /* number of points */ + DDXPointPtr pptInit +#endif + ){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGetGCIndex()].ptr; + BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip); + int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip); + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + int xorg = pDrawable->x; + int yorg = pDrawable->y; + int nbox; + BoxPtr pbox; +#ifndef POLYSEGMENT + DDXPointPtr ppt; +#endif + unsigned int oc1, oc2; + int dmin, dmaj, e, octant; + int x1, x2, y1, y2, tmp, len, offset; + int PatternLength, PatternOffset; + +#ifdef POLYSEGMENT +/* ErrorF("TGAPolySegmentDashed called\n"); */ +#else +/* ErrorF("TGAPolyLinesDashed called\n"); */ +#endif + + if(!nboxInit) + return; + + PatternLength = pGCPriv->DashLength; + PatternOffset = pGC->dashOffset % PatternLength; + + TGASetupForDashedLine(infoRec->pScrn, pGC->fgPixel, + (pGC->lineStyle == LineDoubleDash) ? pGC->bgPixel : -1, + pGC->alu, pGC->planemask, PatternLength, pGCPriv->DashPattern); + + +#ifdef POLYSEGMENT + while (nseg--) +#else + ppt = pptInit; + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; + while(--npt) +#endif + { + nbox = nboxInit; + pbox = pboxInit; + +#ifdef POLYSEGMENT + x1 = pSeg->x1 + xorg; + y1 = pSeg->y1 + yorg; + x2 = pSeg->x2 + xorg; + y2 = pSeg->y2 + yorg; + pSeg++; +#else + x1 = x2; + y1 = y2; + ++ppt; + if (mode == CoordModePrevious) { + xorg = x1; + yorg = y1; + } + x2 = ppt->x + xorg; + y2 = ppt->y + yorg; +#endif + + + + if((dmaj = x2 - x1) < 0) { + dmaj = -dmaj; + octant = XDECREASING; + } else octant = 0; + + if((dmin = y2 - y1) < 0) { + dmin = -dmin; + octant |= YDECREASING; + } + + if(dmin >= dmaj){ + tmp = dmin; dmin = dmaj; dmaj = tmp; + octant |= YMAJOR; + } + + e = -dmaj - ((bias >> octant) & 1); + len = dmaj; + dmin <<= 1; + dmaj <<= 1; + + + while(nbox--) { + oc1 = oc2 = 0; + OUTCODES(oc1, x1, y1, pbox); + OUTCODES(oc2, x2, y2, pbox); + if (!(oc1 | oc2)) { /* unclipped */ + TGASubsequentDashedLine(infoRec->pScrn, x1, y1, x2, y2, + octant, +#ifdef POLYSEGMENT + (pGC->capStyle != CapNotLast) ? 0 : +#endif + OMIT_LAST, PatternOffset); + break; + } else if (oc1 & oc2) { /* completely clipped */ + pbox++; + } else { /* partially clipped */ + int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; + int clip1 = 0, clip2 = 0; + int err, adx, ady; + + if(octant & YMAJOR) { + ady = dmaj >> 1; + adx = dmin >> 1; + } else { + ady = dmin >> 1; + adx = dmaj >> 1; + } + + if (miZeroClipLine(pbox->x1, pbox->y1, + pbox->x2 - 1, pbox->y2 - 1, + &new_x1, &new_y1, &new_x2, &new_y2, + adx, ady, &clip1, &clip2, + octant, bias, oc1, oc2) == -1) + { + pbox++; + continue; + } + + if (octant & YMAJOR) + len = abs(new_y2 - new_y1); + else + len = abs(new_x2 - new_x1); +#ifdef POLYSEGMENT + if (clip2 != 0 || pGC->capStyle != CapNotLast) + len++; +#else + len += (clip2 != 0); +#endif + if (len) { + int abserr, clipdx, clipdy; + /* unwind bresenham error term to first point */ + if (clip1) { + clipdx = abs(new_x1 - x1); + clipdy = abs(new_y1 - y1); + + if (octant & YMAJOR) + err = e + clipdy*dmin - clipdx*dmaj; + else + err = e + clipdx*dmin - clipdy*dmaj; + } else + err = e; + +#define range infoRec->DashedBresenhamLineErrorTermBits + abserr = abs(err); + while((abserr & range) || + (dmaj & range) || + (dmin & range)) { + dmin >>= 1; + dmaj >>= 1; + abserr >>= 1; + err /= 2; + } + + if(octant & YMAJOR) + offset = abs(new_y1 - y1); + else + offset = abs(new_x1 - x1); + + offset += PatternOffset; + offset %= PatternLength; + + TGASetupForClippedLine(infoRec->pScrn, x1, x2, y1, y2, + octant); + TGASubsequentClippedDashedLine(infoRec->pScrn, new_x1, + new_y1, len, err, + PatternOffset); + } + pbox++; + } + } /* while (nbox--) */ +#ifndef POLYSEGMENT + len = abs(y2 - y1); + tmp = abs(x2 - x1); + PatternOffset += (len > tmp) ? len : tmp; + PatternOffset %= PatternLength; +#endif + } /* while (nline--) */ + +#ifndef POLYSEGMENT + /* paint the last point if the end style isn't CapNotLast. + (Assume that a projecting, butt, or round cap that is one + pixel wide is the same as the single pixel of the endpoint.) + */ + + if ((pGC->capStyle != CapNotLast) && + ((ppt->x + xorg != pptInit->x + pDrawable->x) || + (ppt->y + yorg != pptInit->y + pDrawable->y) || + (ppt == pptInit + 1))) + { + nbox = nboxInit; + pbox = pboxInit; + while (nbox--) { + if ((x2 >= pbox->x1) && (y2 >= pbox->y1) && + (x2 < pbox->x2) && (y2 < pbox->y2)) + { + TGASubsequentDashedLine(infoRec->pScrn, x2, y2, x2, y2, 0, 0, + PatternOffset); + break; + } else + pbox++; + } + } +#endif + + TGASync(infoRec->pScrn); + return; +} + + diff --git a/driver/xf86-video-tga/src/tga_regs.h b/driver/xf86-video-tga/src/tga_regs.h new file mode 100644 index 000000000..0cf054ddc --- /dev/null +++ b/driver/xf86-video-tga/src/tga_regs.h @@ -0,0 +1,216 @@ +/* + * Copyright 1997,1998 by Alan Hourihane, Wigan, England. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h,v 1.11 2000/10/20 12:57:26 alanh Exp $ */ + +/* TGA hardware description (minimal) + * + * Offsets within Memory Space + * + * Portions taken from linux's own tga driver... + * Courtesy of Jay Estabrook. + */ + +#ifndef TGA_REGS_H +#define TGA_REGS_H + +#include "compiler.h" + +#define TYPE_TGA_8PLANE 0 +#define TYPE_TGA_24PLANE 1 +#define TYPE_TGA_24PLUSZ 3 + +#if 1 +#define WMB mem_barrier() +#else +#define WMB write_mem_barrier() +#endif + +#define TGA_WRITE_REG(v,r) \ + do {\ + *(unsigned int *)((char*)(pTga->IOBase)+(r)) = (v);\ + WMB;\ + } while (0) + +#define TGA_READ_REG(r) \ + ( *(unsigned int *)((char*)(pTga->IOBase)+(r))) + +#define TGA2_WRITE_CLOCK_REG(v,r) \ + do {\ + *(unsigned int *)((char*)(pTga->ClkBase)+(r)) = (v);\ + WMB;\ + } while (0) + +#define TGA2_WRITE_RAMDAC_REG(v,r) \ + do {\ + *(unsigned int *)((char*)(pTga->DACBase)+(r)) = (v);\ + WMB;\ + } while (0) + +#define TGA2_READ_RAMDAC_REG(r) \ + ( *(unsigned int *)((char*)(pTga->DACBase)+(r))) + +#if defined(__alpha__) && 0 /* ?? disable this for now ?? */ +/* we can avoid an mb() if we write to an alternate register space each time */ + +#define MAX_OFFSET 8192 +#define OFFSET_INC 1024 + +#define TGA_DECL() register unsigned long iobase, offset +#define TGA_GET_IOBASE() iobase = (unsigned long)pTga->IOBase; +#define TGA_GET_OFFSET() offset = pTga->regOffset; +#define TGA_SAVE_OFFSET() pTga->regOffset = offset; + +/* #define PROFILE */ +#undef PROFILE + +#ifdef PROFILE +static __inline__ unsigned int realcc() +{ + u_long cc; + __asm__ volatile("rpcc %0" : "=r"(cc) : : "memory"); + return cc; +} + +#define TGA_FAST_WRITE_REG(v,r) \ +do {\ +start = realcc();\ + *(unsigned int *)(iobase + offset + (r)) = v;\ + offset += OFFSET_INC;\ + if(offset > MAX_OFFSET) (offset = 0);\ + stop = realcc();\ + ErrorF("TGA_FAST_WRITE_REG = %d\n", stop - start);\ +} while (0) + +#else /* PROFILE */ + +#define TGA_FAST_WRITE_REG(v,r) \ +do {\ + *(unsigned int *)(iobase + offset + (r)) = v;\ + offset += OFFSET_INC;\ + if(offset > MAX_OFFSET) (offset = 0);\ +} while (0) +#endif /* PROFILE */ + +#else /* __alpha__ */ + +#define TGA_DECL() +#define TGA_GET_IOBASE() ; +#define TGA_GET_OFFSET() ; +#define TGA_SAVE_OFFSET() ; +#define TGA_FAST_WRITE_REG(v,r) TGA_WRITE_REG(v,r) + +#endif /* __alpha__ */ + +#define TGA_ROM_OFFSET 0x00000000 +#define TGA2_CLOCK_OFFSET 0x00060000 +#define TGA2_RAMDAC_OFFSET 0x00080000 +#define TGA_REGS_OFFSET 0x00100000 +#define TGA_8PLANE_FB_OFFSET 0x00200000 +#define TGA_24PLANE_FB_OFFSET 0x00800000 +#define TGA_24PLUSZ_FB_OFFSET 0x01000000 + +#define TGA_FOREGROUND_REG 0x0020 +#define TGA_BACKGROUND_REG 0x0024 +#define TGA_PLANEMASK_REG 0x0028 +#define TGA_MODE_REG 0x0030 +#define SIMPLE 0x00 +#define Z3D 0x10 +#define OPAQUESTIPPLE 0x01 +#define FILL 0x20 +#define TRANSPARENTSTIPPLE 0x05 +#define BLOCKSTIPPLE 0x0D +#define BLOCKFILL 0x2D +#define OPAQUELINE 0x02 +#define TRANSPARENTLINE 0x06 +#define BPP8PACKED (0x00 << 8) +#define BPP8UNPACK (0x01 << 8) +#define BPP12LOW (0x02 << 8) +#define BPP12HIGH (0x06 << 8) +#define BPP24 (0x03 << 8) +#define CAP_ENDS 0x8000 +#define X11 0x0000 +#define MODE_WIN32 0x2000 + /* copy mode */ +#define COPY 0x07 + /* opaque fill mode */ +#define OPAQUEFILL 0x21 +#define TRANSPARENTFILL 0x45 +#define TGA_RASTEROP_REG 0x0034 +#define TGA_PIXELSHIFT_REG 0x0038 +#define TGA_ADDRESS_REG 0x003c +#define TGA_CONTINUE_REG 0x004c +#define TGA_DEEP_REG 0x0050 +#define TGA_REVISION_REG 0x0054 /* TGA2 */ +#define TGA_PIXELMASK_REG 0x002c +#define TGA_PIXELMASK_PERS_REG 0x005c +#define TGA_CURSOR_BASE_REG 0x0060 +#define TGA_HORIZ_REG 0x0064 +#define TGA_VERT_REG 0x0068 +#define TGA_BASE_ADDR_REG 0x006c +#define TGA_VALID_REG 0x0070 +#define TGA_CURSOR_XY_REG 0x0074 +#define TGA_INTR_STAT_REG 0x007c + /* GDAR */ +#define TGA_DATA_REG 0x0080 +#define TGA_WIDTH_REG 0x009c +#define TGA_SPAN_REG 0x00bc +#define TGA_RAMDAC_SETUP_REG 0x00c0 + +#define TGA_NOSLOPE7_REG 0x011C +#define TGA_NOSLOPE6_REG 0x0118 +#define TGA_NOSLOPE5_REG 0x0114 +#define TGA_NOSLOPE4_REG 0x0110 +#define TGA_NOSLOPE3_REG 0x010C +#define TGA_NOSLOPE2_REG 0x0108 +#define TGA_NOSLOPE1_REG 0x0104 +#define TGA_NOSLOPE0_REG 0x0100 + +#define TGA_SLOPE0_REG 0x0120 +#define TGA_SLOPE1_REG 0x0124 +#define TGA_SLOPE2_REG 0x0128 +#define TGA_SLOPE3_REG 0x012C +#define TGA_SLOPE4_REG 0x0130 +#define TGA_SLOPE5_REG 0x0134 +#define TGA_SLOPE6_REG 0x0138 +#define TGA_SLOPE7_REG 0x013C +#define TGA_BRES3_REG 0x0048 +#define TGA_BRES2_REG 0x0044 +#define TGA_BRES1_REG 0x0040 + +#define TGA_BLOCK_COLOR0_REG 0x0140 +#define TGA_BLOCK_COLOR1_REG 0x0144 +#define TGA_BLOCK_COLOR2_REG 0x0148 +#define TGA_BLOCK_COLOR3_REG 0x014c +#define TGA_BLOCK_COLOR4_REG 0x0150 +#define TGA_BLOCK_COLOR5_REG 0x0154 +#define TGA_BLOCK_COLOR6_REG 0x0158 +#define TGA_BLOCK_COLOR7_REG 0x015c +#define TGA_CLOCK_REG 0x01e8 +#define TGA_RAMDAC_REG 0x01f0 +#define TGA_CMD_STAT_REG 0x01f8 + +#define BT485_READ_BIT 0x01 +#define BT485_WRITE_BIT 0x00 + +#endif diff --git a/driver/xf86-video-tga/src/tga_seg.c b/driver/xf86-video-tga/src/tga_seg.c new file mode 100644 index 000000000..31398181a --- /dev/null +++ b/driver/xf86-video-tga/src/tga_seg.c @@ -0,0 +1,2 @@ +#define POLYSEGMENT +#include "./tga_line.c" |