diff options
author | alanh <alanh> | 2003-03-25 11:19:44 +0000 |
---|---|---|
committer | alanh <alanh> | 2003-03-25 11:19:44 +0000 |
commit | a5eb4a7e5329c30f98d76bfc8a7c883dbc93e4b5 (patch) | |
tree | 2f0f1b709282ce566a45bd038783818cfe6ec751 | |
parent | b68a38ee957b07f93f7753c80d9d37de7cf3c94d (diff) |
driver merge
211 files changed, 106528 insertions, 4657 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile index d5c7175b3..f2c2b08db 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile @@ -1,6 +1,6 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v 1.39 2002/09/12 00:33:43 tsi Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v 1.45 2003/02/17 17:06:41 dawes Exp $ XCOMM -XCOMM Copyright 1997 through 2002 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org +XCOMM Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org XCOMM XCOMM Permission to use, copy, modify, distribute, and sell this software and XCOMM its documentation for any purpose is hereby granted without fee, provided @@ -178,7 +178,7 @@ OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) INCLUDES = -I. -I../../include #else INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC) \ - -I$(XF86OSSRC)/vbe -I$(XF86SRC)/int10 \ + -I$(XF86SRC)/vbe -I$(XF86SRC)/int10 \ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ -I$(XF86SRC)/rac -I$(XF86SRC)/ramdac \ -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xaa -I$(XF86SRC)/xf24_32bpp \ @@ -186,7 +186,7 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC) \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \ -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \ - -I$(SERVERSRC)/miext/shadow \ + -I$(SERVERSRC)/miext/shadow \ -I$(SERVERSRC)/render -I$(SERVERSRC)/Xext -I$(SERVERSRC)/include \ $(DRIINCLUDES) -I$(FONTINCSRC) -I$(EXTINCSRC) -I$(XINCLUDESRC) #endif @@ -213,6 +213,8 @@ InstallModuleManPage(ati) InstallModuleManPage(r128) +InstallModuleManPage(radeon) + DependTarget() InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/ati) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.c index a516cfe38..beca2d8ed 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.c @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.c,v 1.8 2002/01/16 16:22:26 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.c,v 1.9 2003/01/01 19:16:31 tsi Exp $ */ /* - * Copyright 2000 through 2002 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * Copyright 2000 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.h index 3751ee196..1011a89ba 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.h @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.h,v 1.5 2002/01/16 16:22:26 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidga.h,v 1.6 2003/01/01 19:16:31 tsi Exp $ */ /* - * Copyright 2000 through 2002 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * Copyright 2000 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64io.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64io.h index 0a862472d..b91a882bc 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64io.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64io.h @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64io.h,v 1.13 2002/01/16 16:22:27 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64io.h,v 1.14 2003/01/01 19:16:32 tsi Exp $ */ /* - * Copyright 2000 through 2002 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * Copyright 2000 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h index 21310bb48..833e421bf 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h,v 1.8 2002/01/16 16:22:27 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h,v 1.9 2003/01/01 19:16:32 tsi Exp $ */ /* - * Copyright 1997 through 2002 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h index 8bc9dac16..d856fd8c1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.20 2002/06/04 23:04:50 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.24 2002/12/16 16:19:10 dawes Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and @@ -64,7 +64,7 @@ #define R128_DEBUG 0 /* Turn off debugging output */ #define R128_IDLE_RETRY 32 /* Fall out of idle loops after this count */ #define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */ -#define R128_MMIOSIZE 0x80000 +#define R128_MMIOSIZE 0x4000 #define R128_VBIOS_SIZE 0x00010000 @@ -457,9 +457,9 @@ do { \ } \ } while (0) +extern drmBufPtr R128CCEGetBuffer(ScrnInfoPtr pScrn); #endif -extern drmBufPtr R128CCEGetBuffer(ScrnInfoPtr pScrn); extern void R128CCEFlushIndirect(ScrnInfoPtr pScrn, int discard); extern void R128CCEReleaseIndirect(ScrnInfoPtr pScrn); extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c index 0ceee28f4..9329ad251 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c,v 1.14 2002/02/14 23:10:11 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c,v 1.16 2002/11/15 03:01:35 dawes Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and @@ -1047,16 +1047,21 @@ void R128EngineInit(ScrnInfoPtr pScrn) OUTREG(R128_DP_WRITE_MASK, 0xffffffff); R128WaitForFifo(pScrn, 1); + #if X_BYTE_ORDER == X_BIG_ENDIAN /* FIXME: this is a kludge for texture uploads in the 3D driver. Look at * how the radeon driver handles HOST_DATA_SWAP if you want to implement * CCE ImageWrite acceleration or anything needing this bit */ - if (!info->directRenderingEnabled) +#ifdef XF86DRI + if (info->directRenderingEnabled) + OUTREGP(R128_DP_DATATYPE, 0, ~R128_HOST_BIG_ENDIAN_EN); + else +#endif OUTREGP(R128_DP_DATATYPE, R128_HOST_BIG_ENDIAN_EN, ~R128_HOST_BIG_ENDIAN_EN); - else +#else /* X_LITTLE_ENDIAN */ + OUTREGP(R128_DP_DATATYPE, 0, ~R128_HOST_BIG_ENDIAN_EN); #endif - OUTREGP(R128_DP_DATATYPE, 0, ~R128_HOST_BIG_ENDIAN_EN); #ifdef XF86DRI info->sc_left = 0x00000000; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c index 4b52c8d25..5a2ac4f09 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.5 2001/03/03 22:26:09 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.6 2003/02/13 20:28:40 tsi Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and @@ -216,7 +216,8 @@ Bool R128CursorInit(ScreenPtr pScreen) cursor->MaxWidth = 64; cursor->MaxHeight = 64; cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP - + | HARDWARE_CURSOR_SHOW_TRANSPARENT + | HARDWARE_CURSOR_UPDATE_UNHIDDEN #if X_BYTE_ORDER == X_LITTLE_ENDIAN | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c index 921b5044a..6c0013afb 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c,v 1.8 2002/05/29 22:48:38 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c,v 1.9 2002/10/30 12:52:12 alanh Exp $ */ /* * Authors: * Ove Kåven <ovek@transgaming.com>, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c index da05fb603..63cedb59f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.24 2002/10/08 22:14:04 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.28 2003/02/07 20:41:14 martin Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and @@ -433,6 +433,7 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen) unsigned long cntl, chunk; int s, l; int flags; + unsigned long agpBase; if (drmAgpAcquire(info->drmFD) < 0) { xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP not available\n"); @@ -604,7 +605,8 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen) info->agpSize*1024); return FALSE; } - OUTREG(R128_AGP_BASE, info->ringHandle); /* Ring buf is at AGP offset 0 */ + agpBase = drmAgpBase(info->drmFD); + OUTREG(R128_AGP_BASE, agpBase); OUTREG(R128_AGP_CNTL, cntl); /* Disable Rage 128's PCIGART registers */ @@ -740,6 +742,40 @@ static Bool R128DRIPciInit(R128InfoPtr info, ScreenPtr pScreen) case PCI_CHIP_RAGE128TF: case PCI_CHIP_RAGE128TL: case PCI_CHIP_RAGE128TR: + /* FIXME: ATI documentation does not specify if the following chips are + * AGP or PCI, it just mentions their PCI IDs. I'm assuming they're AGP + * until I get more correct information. <mharris@redhat.com> + */ + case PCI_CHIP_RAGE128PA: + case PCI_CHIP_RAGE128PB: + case PCI_CHIP_RAGE128PC: + case PCI_CHIP_RAGE128PE: + case PCI_CHIP_RAGE128PG: + case PCI_CHIP_RAGE128PH: + case PCI_CHIP_RAGE128PI: + case PCI_CHIP_RAGE128PJ: + case PCI_CHIP_RAGE128PK: + case PCI_CHIP_RAGE128PL: + case PCI_CHIP_RAGE128PM: + case PCI_CHIP_RAGE128PN: + case PCI_CHIP_RAGE128PO: + case PCI_CHIP_RAGE128PQ: + case PCI_CHIP_RAGE128PS: + case PCI_CHIP_RAGE128PT: + case PCI_CHIP_RAGE128PU: + case PCI_CHIP_RAGE128PV: + case PCI_CHIP_RAGE128PW: + case PCI_CHIP_RAGE128PX: + case PCI_CHIP_RAGE128SE: + case PCI_CHIP_RAGE128SF: + case PCI_CHIP_RAGE128SG: + case PCI_CHIP_RAGE128SH: + case PCI_CHIP_RAGE128SK: + case PCI_CHIP_RAGE128SL: + case PCI_CHIP_RAGE128SN: + case PCI_CHIP_RAGE128TS: + case PCI_CHIP_RAGE128TT: + case PCI_CHIP_RAGE128TU: default: /* This is really an AGP card, force PCI GART mode */ chunk = INREG(R128_BM_CHUNK_0_VAL); @@ -803,7 +839,7 @@ static int R128DRIKernelInit(R128InfoPtr info, ScreenPtr pScreen) drmInfo.depth_pitch = info->depthPitch; drmInfo.span_offset = info->spanOffset; - drmInfo.fb_offset = info->LinearAddr; + drmInfo.fb_offset = info->fbHandle; drmInfo.mmio_offset = info->registerHandle; drmInfo.ring_offset = info->ringHandle; drmInfo.ring_rptr_offset = info->ringReadPtrHandle; @@ -1120,6 +1156,18 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) return FALSE; } + /* DRIScreenInit adds the frame buffer + map, but we need it as well */ + { + void *scratch_ptr; + int scratch_int; + + DRIGetDeviceInfo(pScreen, &info->fbHandle, + &scratch_int, &scratch_int, + &scratch_int, &scratch_int, + &scratch_ptr); + } + /* FIXME: When are these mappings unmapped? */ if (!R128InitVisualConfigs(pScreen)) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h index 64345d3c2..1339a4502 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h,v 1.6 2001/03/21 17:02:21 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h,v 1.7 2002/10/30 12:52:12 alanh Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c index e00b32f2b..b02cd7ab9 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v 1.68 2002/10/08 22:14:04 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v 1.75 2003/02/19 01:19:41 dawes Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and @@ -353,6 +353,7 @@ void R128LoaderRefSymLists(void) driSymbols, #endif fbdevHWSymbols, + int10Symbols, vbeSymbols, /* ddcsymbols, */ i2cSymbols, @@ -931,10 +932,44 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn) switch (info->Chipset) { /* R128 Pro and Pro2 can have DFP, we will deal with it. No support for dual-head/xinerama yet. - M3 can also have DFP, no support for now */ + M3 can also have DFP, no support for now */ case PCI_CHIP_RAGE128TF: case PCI_CHIP_RAGE128TL: - case PCI_CHIP_RAGE128TR: info->isPro2 = TRUE; + case PCI_CHIP_RAGE128TR: + /* FIXME: RAGE128 TS/TT/TU are assumed to be PRO2 as all 6 chips came + * out at the same time, so are of the same family likely. + * This requires confirmation however to be fully correct. + * Mike A. Harris <mharris@redhat.com> + */ + case PCI_CHIP_RAGE128TS: + case PCI_CHIP_RAGE128TT: + case PCI_CHIP_RAGE128TU: info->isPro2 = TRUE; + /* FIXME: RAGE128 P[ABCEGHIJKLMNOQSTUVWX] are assumed to have DFP + * capability, as the comment at the top suggests. + * This requires confirmation however to be fully correct. + * Mike A. Harris <mharris@redhat.com> + */ + case PCI_CHIP_RAGE128PA: + case PCI_CHIP_RAGE128PB: + case PCI_CHIP_RAGE128PC: + case PCI_CHIP_RAGE128PE: + case PCI_CHIP_RAGE128PG: + case PCI_CHIP_RAGE128PH: + case PCI_CHIP_RAGE128PI: + case PCI_CHIP_RAGE128PJ: + case PCI_CHIP_RAGE128PK: + case PCI_CHIP_RAGE128PL: + case PCI_CHIP_RAGE128PM: + case PCI_CHIP_RAGE128PN: + case PCI_CHIP_RAGE128PO: + case PCI_CHIP_RAGE128PQ: + case PCI_CHIP_RAGE128PS: + case PCI_CHIP_RAGE128PT: + case PCI_CHIP_RAGE128PU: + case PCI_CHIP_RAGE128PV: + case PCI_CHIP_RAGE128PW: + case PCI_CHIP_RAGE128PX: + case PCI_CHIP_RAGE128PD: case PCI_CHIP_RAGE128PF: case PCI_CHIP_RAGE128PP: @@ -950,6 +985,18 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn) case PCI_CHIP_RAGE128RK: case PCI_CHIP_RAGE128RL: case PCI_CHIP_RAGE128SM: + /* FIXME: RAGE128 S[EFGHKLN] are assumed to be like the SM above as + * all of them are listed as "Rage 128 4x" in ATI docs. + * This requires confirmation however to be fully correct. + * Mike A. Harris <mharris@redhat.com> + */ + case PCI_CHIP_RAGE128SE: + case PCI_CHIP_RAGE128SF: + case PCI_CHIP_RAGE128SG: + case PCI_CHIP_RAGE128SH: + case PCI_CHIP_RAGE128SK: + case PCI_CHIP_RAGE128SL: + case PCI_CHIP_RAGE128SN: default: info->HasPanelRegs = FALSE; break; } } @@ -1090,20 +1137,53 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn) case PCI_CHIP_RAGE128LE: case PCI_CHIP_RAGE128RE: case PCI_CHIP_RAGE128RK: - case PCI_CHIP_RAGE128PP: + case PCI_CHIP_RAGE128PD: case PCI_CHIP_RAGE128PR: - case PCI_CHIP_RAGE128PD: info->IsPCI = TRUE; break; + case PCI_CHIP_RAGE128PP: info->IsPCI = TRUE; break; case PCI_CHIP_RAGE128LF: case PCI_CHIP_RAGE128MF: case PCI_CHIP_RAGE128ML: + case PCI_CHIP_RAGE128PF: case PCI_CHIP_RAGE128RF: case PCI_CHIP_RAGE128RG: case PCI_CHIP_RAGE128RL: case PCI_CHIP_RAGE128SM: - case PCI_CHIP_RAGE128PF: case PCI_CHIP_RAGE128TF: case PCI_CHIP_RAGE128TL: case PCI_CHIP_RAGE128TR: + /* FIXME: Rage 128 S[EFGHKLN], T[STU], P[ABCEGHIJKLMNOQSTUVWX] are + * believed to be AGP, but need confirmation. <mharris@redhat.com> + */ + case PCI_CHIP_RAGE128PA: + case PCI_CHIP_RAGE128PB: + case PCI_CHIP_RAGE128PC: + case PCI_CHIP_RAGE128PE: + case PCI_CHIP_RAGE128PG: + case PCI_CHIP_RAGE128PH: + case PCI_CHIP_RAGE128PI: + case PCI_CHIP_RAGE128PJ: + case PCI_CHIP_RAGE128PK: + case PCI_CHIP_RAGE128PL: + case PCI_CHIP_RAGE128PM: + case PCI_CHIP_RAGE128PN: + case PCI_CHIP_RAGE128PO: + case PCI_CHIP_RAGE128PQ: + case PCI_CHIP_RAGE128PS: + case PCI_CHIP_RAGE128PT: + case PCI_CHIP_RAGE128PU: + case PCI_CHIP_RAGE128PV: + case PCI_CHIP_RAGE128PW: + case PCI_CHIP_RAGE128PX: + case PCI_CHIP_RAGE128TS: + case PCI_CHIP_RAGE128TT: + case PCI_CHIP_RAGE128TU: + case PCI_CHIP_RAGE128SE: + case PCI_CHIP_RAGE128SF: + case PCI_CHIP_RAGE128SG: + case PCI_CHIP_RAGE128SH: + case PCI_CHIP_RAGE128SK: + case PCI_CHIP_RAGE128SL: + case PCI_CHIP_RAGE128SN: default: info->IsPCI = FALSE; break; } } @@ -2354,8 +2434,6 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } } - /* Set Silken Mouse */ - xf86SetSilkenMouse(pScreen); /* Acceleration setup */ if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { @@ -2373,12 +2451,15 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) info->accelOn = FALSE; } + /* DGA setup */ + R128DGAInit(pScreen); + /* Backing store setup */ miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); - /* DGA setup */ - R128DGAInit(pScreen); + /* Set Silken Mouse */ + xf86SetSilkenMouse(pScreen); /* Cursor setup */ miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); @@ -2403,6 +2484,7 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } } else { + info->cursor_start = 0; xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c index 34d781b34..a5cd42fea 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c,v 1.16 2001/11/05 23:37:50 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c,v 1.18 2003/02/09 15:33:17 tsi Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and @@ -75,44 +75,108 @@ static xf86ValidModeProc * const volatile ValidModeProc = R128ValidMode; #endif SymTabRec R128Chipsets[] = { - { PCI_CHIP_RAGE128RE, "ATI Rage 128 RE (PCI)" }, - { PCI_CHIP_RAGE128RF, "ATI Rage 128 RF (AGP)" }, + /* FIXME: The chipsets with (PCI/AGP) are not known wether they are AGP or + * PCI, so I've labeled them as such in hopes users will submit + * data if we're unable to gather it from official documentation + */ + { PCI_CHIP_RAGE128LE, "ATI Rage 128 Mobility M3 LE (PCI)" }, + { PCI_CHIP_RAGE128LF, "ATI Rage 128 Mobility M3 LF (AGP)" }, + { PCI_CHIP_RAGE128MF, "ATI Rage 128 Mobility M4 MF (AGP)" }, + { PCI_CHIP_RAGE128ML, "ATI Rage 128 Mobility M4 ML (AGP)" }, + { PCI_CHIP_RAGE128PA, "ATI Rage 128 Pro GL PA (PCI/AGP)" }, + { PCI_CHIP_RAGE128PB, "ATI Rage 128 Pro GL PB (PCI/AGP)" }, + { PCI_CHIP_RAGE128PC, "ATI Rage 128 Pro GL PC (PCI/AGP)" }, + { PCI_CHIP_RAGE128PD, "ATI Rage 128 Pro GL PD (PCI)" }, + { PCI_CHIP_RAGE128PE, "ATI Rage 128 Pro GL PE (PCI/AGP)" }, + { PCI_CHIP_RAGE128PF, "ATI Rage 128 Pro GL PF (AGP)" }, + { PCI_CHIP_RAGE128PG, "ATI Rage 128 Pro VR PG (PCI/AGP)" }, + { PCI_CHIP_RAGE128PH, "ATI Rage 128 Pro VR PH (PCI/AGP)" }, + { PCI_CHIP_RAGE128PI, "ATI Rage 128 Pro VR PI (PCI/AGP)" }, + { PCI_CHIP_RAGE128PJ, "ATI Rage 128 Pro VR PJ (PCI/AGP)" }, + { PCI_CHIP_RAGE128PK, "ATI Rage 128 Pro VR PK (PCI/AGP)" }, + { PCI_CHIP_RAGE128PL, "ATI Rage 128 Pro VR PL (PCI/AGP)" }, + { PCI_CHIP_RAGE128PM, "ATI Rage 128 Pro VR PM (PCI/AGP)" }, + { PCI_CHIP_RAGE128PN, "ATI Rage 128 Pro VR PN (PCI/AGP)" }, + { PCI_CHIP_RAGE128PO, "ATI Rage 128 Pro VR PO (PCI/AGP)" }, + { PCI_CHIP_RAGE128PP, "ATI Rage 128 Pro VR PP (PCI)" }, + { PCI_CHIP_RAGE128PQ, "ATI Rage 128 Pro VR PQ (PCI/AGP)" }, + { PCI_CHIP_RAGE128PR, "ATI Rage 128 Pro VR PR (PCI)" }, + { PCI_CHIP_RAGE128PS, "ATI Rage 128 Pro VR PS (PCI/AGP)" }, + { PCI_CHIP_RAGE128PT, "ATI Rage 128 Pro VR PT (PCI/AGP)" }, + { PCI_CHIP_RAGE128PU, "ATI Rage 128 Pro VR PU (PCI/AGP)" }, + { PCI_CHIP_RAGE128PV, "ATI Rage 128 Pro VR PV (PCI/AGP)" }, + { PCI_CHIP_RAGE128PW, "ATI Rage 128 Pro VR PW (PCI/AGP)" }, + { PCI_CHIP_RAGE128PX, "ATI Rage 128 Pro VR PX (PCI/AGP)" }, + { PCI_CHIP_RAGE128RE, "ATI Rage 128 GL RE (PCI)" }, + { PCI_CHIP_RAGE128RF, "ATI Rage 128 GL RF (AGP)" }, { PCI_CHIP_RAGE128RG, "ATI Rage 128 RG (AGP)" }, - { PCI_CHIP_RAGE128RK, "ATI Rage 128 RK (PCI)" }, - { PCI_CHIP_RAGE128RL, "ATI Rage 128 RL (AGP)" }, - { PCI_CHIP_RAGE128SM, "ATI Rage 128 SM (AGP)" }, - { PCI_CHIP_RAGE128PD, "ATI Rage 128 Pro PD (PCI)" }, - { PCI_CHIP_RAGE128PF, "ATI Rage 128 Pro PF (AGP)" }, - { PCI_CHIP_RAGE128PP, "ATI Rage 128 Pro PP (PCI)" }, - { PCI_CHIP_RAGE128PR, "ATI Rage 128 Pro PR (PCI)" }, + { PCI_CHIP_RAGE128RK, "ATI Rage 128 VR RK (PCI)" }, + { PCI_CHIP_RAGE128RL, "ATI Rage 128 VR RL (AGP)" }, + { PCI_CHIP_RAGE128SE, "ATI Rage 128 4X SE (PCI/AGP)" }, + { PCI_CHIP_RAGE128SF, "ATI Rage 128 4X SF (PCI/AGP)" }, + { PCI_CHIP_RAGE128SG, "ATI Rage 128 4X SG (PCI/AGP)" }, + { PCI_CHIP_RAGE128SH, "ATI Rage 128 4X SH (PCI/AGP)" }, + { PCI_CHIP_RAGE128SK, "ATI Rage 128 4X SK (PCI/AGP)" }, + { PCI_CHIP_RAGE128SL, "ATI Rage 128 4X SL (PCI/AGP)" }, + { PCI_CHIP_RAGE128SM, "ATI Rage 128 4X SM (AGP)" }, + { PCI_CHIP_RAGE128SN, "ATI Rage 128 4X SN (PCI/AGP)" }, { PCI_CHIP_RAGE128TF, "ATI Rage 128 Pro ULTRA TF (AGP)" }, { PCI_CHIP_RAGE128TL, "ATI Rage 128 Pro ULTRA TL (AGP)" }, { PCI_CHIP_RAGE128TR, "ATI Rage 128 Pro ULTRA TR (AGP)" }, - { PCI_CHIP_RAGE128LE, "ATI Rage 128 Mobility LE (PCI)" }, - { PCI_CHIP_RAGE128LF, "ATI Rage 128 Mobility LF (AGP)" }, - { PCI_CHIP_RAGE128MF, "ATI Rage 128 Mobility MF (AGP)" }, - { PCI_CHIP_RAGE128ML, "ATI Rage 128 Mobility ML (AGP)" }, + { PCI_CHIP_RAGE128TS, "ATI Rage 128 Pro ULTRA TS (AGP?)" }, + { PCI_CHIP_RAGE128TT, "ATI Rage 128 Pro ULTRA TT (AGP?)" }, + { PCI_CHIP_RAGE128TU, "ATI Rage 128 Pro ULTRA TU (AGP?)" }, { -1, NULL } }; PciChipsets R128PciChipsets[] = { + { PCI_CHIP_RAGE128LE, PCI_CHIP_RAGE128LE, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128LF, PCI_CHIP_RAGE128LF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128MF, PCI_CHIP_RAGE128MF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128ML, PCI_CHIP_RAGE128ML, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PA, PCI_CHIP_RAGE128PA, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PB, PCI_CHIP_RAGE128PB, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PC, PCI_CHIP_RAGE128PC, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PD, PCI_CHIP_RAGE128PD, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PE, PCI_CHIP_RAGE128PE, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PF, PCI_CHIP_RAGE128PF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PG, PCI_CHIP_RAGE128PG, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PH, PCI_CHIP_RAGE128PH, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PI, PCI_CHIP_RAGE128PI, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PJ, PCI_CHIP_RAGE128PJ, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PK, PCI_CHIP_RAGE128PK, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PL, PCI_CHIP_RAGE128PL, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PM, PCI_CHIP_RAGE128PM, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PN, PCI_CHIP_RAGE128PN, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PO, PCI_CHIP_RAGE128PO, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PP, PCI_CHIP_RAGE128PP, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PQ, PCI_CHIP_RAGE128PQ, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PR, PCI_CHIP_RAGE128PR, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PS, PCI_CHIP_RAGE128PS, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PT, PCI_CHIP_RAGE128PT, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PU, PCI_CHIP_RAGE128PU, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PV, PCI_CHIP_RAGE128PV, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PW, PCI_CHIP_RAGE128PW, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PX, PCI_CHIP_RAGE128PX, RES_SHARED_VGA }, { PCI_CHIP_RAGE128RE, PCI_CHIP_RAGE128RE, RES_SHARED_VGA }, { PCI_CHIP_RAGE128RF, PCI_CHIP_RAGE128RF, RES_SHARED_VGA }, { PCI_CHIP_RAGE128RG, PCI_CHIP_RAGE128RG, RES_SHARED_VGA }, { PCI_CHIP_RAGE128RK, PCI_CHIP_RAGE128RK, RES_SHARED_VGA }, { PCI_CHIP_RAGE128RL, PCI_CHIP_RAGE128RL, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128SE, PCI_CHIP_RAGE128SE, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128SF, PCI_CHIP_RAGE128SF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128SG, PCI_CHIP_RAGE128SG, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128SH, PCI_CHIP_RAGE128SH, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128SK, PCI_CHIP_RAGE128SK, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128SL, PCI_CHIP_RAGE128SL, RES_SHARED_VGA }, { PCI_CHIP_RAGE128SM, PCI_CHIP_RAGE128SM, RES_SHARED_VGA }, - { PCI_CHIP_RAGE128PD, PCI_CHIP_RAGE128PD, RES_SHARED_VGA }, - { PCI_CHIP_RAGE128PF, PCI_CHIP_RAGE128PF, RES_SHARED_VGA }, - { PCI_CHIP_RAGE128PP, PCI_CHIP_RAGE128PP, RES_SHARED_VGA }, - { PCI_CHIP_RAGE128PR, PCI_CHIP_RAGE128PR, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128SN, PCI_CHIP_RAGE128SN, RES_SHARED_VGA }, { PCI_CHIP_RAGE128TF, PCI_CHIP_RAGE128TF, RES_SHARED_VGA }, { PCI_CHIP_RAGE128TL, PCI_CHIP_RAGE128TL, RES_SHARED_VGA }, { PCI_CHIP_RAGE128TR, PCI_CHIP_RAGE128TR, RES_SHARED_VGA }, - { PCI_CHIP_RAGE128LE, PCI_CHIP_RAGE128LE, RES_SHARED_VGA }, - { PCI_CHIP_RAGE128LF, PCI_CHIP_RAGE128LF, RES_SHARED_VGA }, - { PCI_CHIP_RAGE128MF, PCI_CHIP_RAGE128MF, RES_SHARED_VGA }, - { PCI_CHIP_RAGE128ML, PCI_CHIP_RAGE128ML, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128TS, PCI_CHIP_RAGE128TS, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128TT, PCI_CHIP_RAGE128TT, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128TU, PCI_CHIP_RAGE128TU, RES_SHARED_VGA }, { -1, -1, RES_UNDEFINED } }; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h index d99e40283..3968bd579 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h,v 1.14 2002/04/29 04:15:54 anderson Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h,v 1.15 2002/12/16 16:19:11 dawes Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c index 0d66d48de..119971fdd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c,v 1.21 2002/06/04 23:04:51 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c,v 1.26 2003/02/19 01:19:41 dawes Exp $ */ #include "r128.h" #include "r128_reg.h" @@ -377,6 +377,8 @@ R128StopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup) if(cleanup) { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { OUTREG(R128_OV0_SCALE_CNTL, 0); + if (info->cursor_start) + xf86ForceHWCursor (pScrn->pScreen, FALSE); } if(pPriv->linear) { xf86FreeOffscreenLinear(pPriv->linear); @@ -885,6 +887,14 @@ R128PutImage( int top, left, npixels, nlines, bpp; BoxRec dstBox; CARD32 tmp; +#if X_BYTE_ORDER == X_BIG_ENDIAN + unsigned char *R128MMIO = info->MMIO; + CARD32 config_cntl = INREG(R128_CONFIG_CNTL); + + /* We need to disable byte swapping, or the data gets mangled */ + OUTREG(R128_CONFIG_CNTL, config_cntl & + ~(APER_0_BIG_ENDIAN_16BPP_SWAP | APER_0_BIG_ENDIAN_32BPP_SWAP)); +#endif /* * s1offset, s2offset, s3offset - byte offsets to the Y, U and V planes @@ -993,24 +1003,9 @@ R128PutImage( } nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top; - { -#if X_BYTE_ORDER == X_BIG_ENDIAN - unsigned char *R128MMIO = info->MMIO; - CARD32 config_cntl; - - /* We need to disable byte swapping, or the data gets mangled */ - config_cntl = INREG(R128_CONFIG_CNTL); - OUTREG(R128_CONFIG_CNTL, config_cntl & - ~(APER_0_BIG_ENDIAN_16BPP_SWAP|APER_0_BIG_ENDIAN_32BPP_SWAP)); -#endif - R128CopyData420(info, buf + s1offset, buf + s2offset, buf + s3offset, - info->FB+d1offset, info->FB+d2offset, info->FB+d3offset, - srcPitch, srcPitch2, dstPitch, nlines, npixels); -#if X_BYTE_ORDER == X_BIG_ENDIAN - /* restore byte swapping */ - OUTREG(R128_CONFIG_CNTL, config_cntl); -#endif - } + R128CopyData420(info, buf + s1offset, buf + s2offset, buf + s3offset, + info->FB+d1offset, info->FB+d2offset, info->FB+d3offset, + srcPitch, srcPitch2, dstPitch, nlines, npixels); break; case FOURCC_UYVY: case FOURCC_YUY2: @@ -1029,6 +1024,10 @@ R128PutImage( break; } +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* restore byte swapping */ + OUTREG(R128_CONFIG_CNTL, config_cntl); +#endif /* update cliplist */ if(!RegionsEqual(&pPriv->clip, clipBoxes)) { @@ -1056,6 +1055,8 @@ R128PutImage( break; } + if (info->cursor_start && !(pPriv->videoStatus & CLIENT_VIDEO_ON)) + xf86ForceHWCursor (pScrn->pScreen, TRUE); pPriv->videoStatus = CLIENT_VIDEO_ON; info->VideoTimerCallback = R128VideoTimerCallback; @@ -1117,6 +1118,8 @@ R128VideoTimerCallback(ScrnInfoPtr pScrn, Time now) if(pPriv->offTime < now) { unsigned char *R128MMIO = info->MMIO; OUTREG(R128_OV0_SCALE_CNTL, 0); + if (info->cursor_start && pPriv->videoStatus & CLIENT_VIDEO_ON) + xf86ForceHWCursor (pScrn->pScreen, FALSE); pPriv->videoStatus = FREE_TIMER; pPriv->freeTime = now + FREE_DELAY; } @@ -1126,6 +1129,8 @@ R128VideoTimerCallback(ScrnInfoPtr pScrn, Time now) xf86FreeOffscreenLinear(pPriv->linear); pPriv->linear = NULL; } + if (info->cursor_start && pPriv->videoStatus & CLIENT_VIDEO_ON) + xf86ForceHWCursor (pScrn->pScreen, FALSE); pPriv->videoStatus = 0; info->VideoTimerCallback = NULL; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h index 983d75ef9..81e0db7b7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v 1.29 2002/10/12 01:38:07 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v 1.37 2003/02/23 23:28:48 dawes Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -194,10 +194,6 @@ typedef struct { CARD32 p2pll_div_0; CARD32 htotal_cntl2; - /* DDA register */ - CARD32 dda_config; - CARD32 dda_on_off; - /* Pallet */ Bool palette_valid; CARD32 palette[256]; @@ -306,6 +302,7 @@ typedef struct { Bool ddc_mode; /* Validate mode by matching exactly * the modes supported in DDC data */ + Bool R300CGWorkaround; /* EDID or BIOS values for FPs */ int PanelXRes; @@ -342,6 +339,11 @@ typedef struct { xf86CursorInfoPtr cursor; unsigned long cursor_start; unsigned long cursor_end; +#ifdef ARGB_CURSOR + Bool cursor_argb; +#endif + int cursor_fg; + int cursor_bg; /* * XAAForceTransBlit is used to change the behavior of the XAA @@ -427,6 +429,7 @@ typedef struct { CARD32 pciCommand; + Bool CPRuns; /* CP is running */ Bool CPInUse; /* CP has been used by X server */ Bool CPStarted; /* CP has started */ int CPMode; /* CP mode that server/clients use */ @@ -551,6 +554,7 @@ extern void RADEONEngineRestore(ScrnInfoPtr pScrn); extern unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr); extern void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn); +extern void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn); extern void RADEONSelectBuffer(ScrnInfoPtr pScrn, int buffer); @@ -588,13 +592,17 @@ do { \ #define RADEONCP_STOP(pScrn, info) \ do { \ - int _ret = RADEONCPStop(pScrn, info); \ - if (_ret) { \ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + int _ret; \ + if (info->CPStarted) { \ + _ret = RADEONCPStop(pScrn, info); \ + if (_ret) { \ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CP stop %d\n", __FUNCTION__, _ret); \ - } \ - info->CPStarted = FALSE; \ + } \ + info->CPStarted = FALSE; \ + } \ RADEONEngineRestore(pScrn); \ + info->CPRuns = FALSE; \ } while (0) #define RADEONCP_RESET(pScrn, info) \ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c index 588d5c835..1d9fbcf3f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c,v 1.29 2002/10/12 01:38:07 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c,v 1.32 2003/01/17 19:54:03 martin Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -172,8 +172,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn) RADEONEngineFlush(pScrn); clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); - if (info->ChipFamily == CHIP_FAMILY_R300) - R300CGWorkaround(pScrn); + if (info->R300CGWorkaround) R300CGWorkaround(pScrn); /* Some ASICs have bugs with dynamic-on feature, which are * ASIC-version dependent, so we force all blocks on for now @@ -249,8 +248,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn) OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); OUTPLL(RADEON_MCLK_CNTL, mclk_cntl); - if (info->ChipFamily == CHIP_FAMILY_R300) - R300CGWorkaround(pScrn); + if (info->R300CGWorkaround) R300CGWorkaround(pScrn); } /* Restore the acceleration hardware to its previous state */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c index d0b01db8e..06dcfd63e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c,v 1.1 2002/09/18 18:14:58 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c,v 1.6 2003/01/29 18:06:06 martin Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -110,12 +110,9 @@ FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn) int i = 0; #ifdef ACCEL_CP - - int ret; - /* Make sure the CP is idle first */ - if (info->CPStarted) { + int ret; FLUSH_RING(); for (;;) { @@ -139,15 +136,13 @@ FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn) RADEONCP_START(pScrn, info); } } - #endif - /* Wait for the engine to go idle */ - RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n", INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, INREG(RADEON_RBBM_STATUS))); + /* Wait for the engine to go idle */ RADEONWaitForFifoFunction(pScrn, 64); for (;;) { @@ -283,6 +278,12 @@ FUNC_NAME(RADEONSetupForSolidLine)(ScrnInfoPtr pScrn, | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP[rop].pattern); + if (info->ChipFamily >= CHIP_FAMILY_RV200) { + BEGIN_ACCEL(1); + OUT_ACCEL_REG(RADEON_DST_LINE_PATCOUNT, + 0x55 << RADEON_BRES_CNTL_SHIFT); + } + BEGIN_ACCEL(3); OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->dp_gui_master_cntl_clip); @@ -581,9 +582,12 @@ FUNC_NAME(RADEONSetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, unsigned int planemask) { RADEONInfoPtr info = RADEONPTR(pScrn); +#if X_BYTE_ORDER == X_BIG_ENDIAN unsigned char pattern[8]; +#endif ACCEL_PREAMBLE(); +#if X_BYTE_ORDER == X_BIG_ENDIAN /* Take care of endianness */ pattern[0] = (patternx & 0x000000ff); pattern[1] = (patternx & 0x0000ff00) >> 8; @@ -593,13 +597,18 @@ FUNC_NAME(RADEONSetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, pattern[5] = (patterny & 0x0000ff00) >> 8; pattern[6] = (patterny & 0x00ff0000) >> 16; pattern[7] = (patterny & 0xff000000) >> 24; +#endif /* Save for later clipping */ info->dp_gui_master_cntl_clip = (info->dp_gui_master_cntl | (bg == -1 ? RADEON_GMC_BRUSH_8X8_MONO_FG_LA : RADEON_GMC_BRUSH_8X8_MONO_FG_BG) - | RADEON_ROP[rop].pattern); + | RADEON_ROP[rop].pattern +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + | RADEON_GMC_BYTE_MSB_TO_LSB +#endif + ); BEGIN_ACCEL((bg == -1) ? 5 : 6); @@ -608,8 +617,13 @@ FUNC_NAME(RADEONSetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); if (bg != -1) OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, bg); +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + OUT_ACCEL_REG(RADEON_BRUSH_DATA0, patternx); + OUT_ACCEL_REG(RADEON_BRUSH_DATA1, patterny); +#else OUT_ACCEL_REG(RADEON_BRUSH_DATA0, *(CARD32 *)(pointer)&pattern[0]); OUT_ACCEL_REG(RADEON_BRUSH_DATA1, *(CARD32 *)(pointer)&pattern[4]); +#endif FINISH_ACCEL(); } @@ -1200,8 +1214,16 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a) = FUNC_NAME(RADEONSubsequentMono8x8PatternFillRect); a->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN - | HARDWARE_PATTERN_SCREEN_ORIGIN - | BIT_ORDER_IN_BYTE_LSBFIRST); + | HARDWARE_PATTERN_SCREEN_ORIGIN); + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + if (info->ChipFamily >= CHIP_FAMILY_RV200) + a->Mono8x8PatternFillFlags |= BIT_ORDER_IN_BYTE_MSBFIRST; + else + a->Mono8x8PatternFillFlags |= BIT_ORDER_IN_BYTE_LSBFIRST; +#else + a->Mono8x8PatternFillFlags |= BIT_ORDER_IN_BYTE_LSBFIRST; +#endif /* Indirect CPU-To-Screen Color Expand */ @@ -1254,21 +1276,23 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a) a->SubsequentSolidTwoPointLine = FUNC_NAME(RADEONSubsequentSolidTwoPointLine); - /* Disabled because it does not pass XTest */ - a->SetupForDashedLine - = FUNC_NAME(RADEONSetupForDashedLine); - a->SubsequentDashedTwoPointLine - = FUNC_NAME(RADEONSubsequentDashedTwoPointLine); - a->DashPatternMaxLength = 32; - /* ROP3 doesn't seem to work properly for dashedline with GXinvert */ - a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED + /* Disabled on RV200 and newer because it does not pass XTest */ + if (info->ChipFamily < CHIP_FAMILY_RV200) { + a->SetupForDashedLine + = FUNC_NAME(RADEONSetupForDashedLine); + a->SubsequentDashedTwoPointLine + = FUNC_NAME(RADEONSubsequentDashedTwoPointLine); + a->DashPatternMaxLength = 32; + /* ROP3 doesn't seem to work properly for dashedline with GXinvert */ + a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED | LINE_PATTERN_POWER_OF_2_ONLY | LINE_LIMIT_COORDS | ROP_NEEDS_SOURCE); - a->DashedLineLimits.x1 = 0; - a->DashedLineLimits.y1 = 0; - a->DashedLineLimits.x2 = pScrn->virtualX-1; - a->DashedLineLimits.y2 = pScrn->virtualY-1; + a->DashedLineLimits.x1 = 0; + a->DashedLineLimits.y1 = 0; + a->DashedLineLimits.x2 = pScrn->virtualX-1; + a->DashedLineLimits.y2 = pScrn->virtualY-1; + } #ifdef XFree86LOADER } else { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c index ecddc34a5..868703d96 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c,v 1.15 2002/10/12 01:38:07 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c,v 1.23 2003/02/24 20:34:55 tsi Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -52,40 +52,78 @@ /* X and server generic header files */ #include "xf86.h" +/* Mono ARGB cursor colours (premultiplied). */ +static CARD32 mono_cursor_color[] = { + 0x00000000, /* White, fully transparent. */ + 0x00000000, /* Black, fully transparent. */ + 0xffffffff, /* White, fully opaque. */ + 0xff000000, /* Black, fully opaque. */ +}; + +#define CURSOR_WIDTH 64 +#define CURSOR_HEIGHT 64 + +/* + * The cursor bits are always 32bpp. On MSBFirst busses, + * configure byte swapping to swap 32 bit units when writing + * the cursor image. Byte swapping must always be returned + * to its previous value before returning. + */ #if X_BYTE_ORDER == X_BIG_ENDIAN -#define P_SWAP32(a, b) \ -do { \ - ((char *)a)[0] = ((char *)b)[3]; \ - ((char *)a)[1] = ((char *)b)[2]; \ - ((char *)a)[2] = ((char *)b)[1]; \ - ((char *)a)[3] = ((char *)b)[0]; \ -} while (0) - -#define P_SWAP16(a, b) \ -do { \ - ((char *)a)[0] = ((char *)b)[1]; \ - ((char *)a)[1] = ((char *)b)[0]; \ - ((char *)a)[2] = ((char *)b)[3]; \ - ((char *)a)[3] = ((char *)b)[2]; \ -} while (0) -#endif +#define CURSOR_SWAPPING_DECL_MMIO unsigned char *RADEONMMIO = info->MMIO; +#define CURSOR_SWAPPING_DECL CARD32 __surface_cntl; +#define CURSOR_SWAPPING_START() \ + OUTREG(RADEON_SURFACE_CNTL, \ + ((__surface_cntl = INREG(RADEON_SURFACE_CNTL)) | \ + RADEON_NONSURF_AP0_SWP_32BPP) & \ + ~RADEON_NONSURF_AP0_SWP_16BPP) +#define CURSOR_SWAPPING_END() (OUTREG(RADEON_SURFACE_CNTL, __surface_cntl)) + +#else + +#define CURSOR_SWAPPING_DECL_MMIO +#define CURSOR_SWAPPING_DECL +#define CURSOR_SWAPPING_START() +#define CURSOR_SWAPPING_END() + +#endif /* Set cursor foreground and background colors */ static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - - if (info->IsSecondary || info->Clone) { - OUTREG(RADEON_CUR2_CLR0, bg); - OUTREG(RADEON_CUR2_CLR1, fg); - } - - if (!info->IsSecondary) { - OUTREG(RADEON_CUR_CLR0, bg); - OUTREG(RADEON_CUR_CLR1, fg); - } + CARD32 *pixels = (CARD32 *)(pointer)(info->FB + info->cursor_start); + int pixel, i; + CURSOR_SWAPPING_DECL_MMIO + CURSOR_SWAPPING_DECL + +#ifdef ARGB_CURSOR + /* Don't recolour cursors set with SetCursorARGB. */ + if (info->cursor_argb) + return; +#endif + + fg |= 0xff000000; + bg |= 0xff000000; + + /* Don't recolour the image if we don't have to. */ + if (fg == info->cursor_fg && bg == info->cursor_bg) + return; + + CURSOR_SWAPPING_START(); + + /* Note: We assume that the pixels are either fully opaque or fully + * transparent, so we won't premultiply them, and we can just + * check for non-zero pixel values; those are either fg or bg + */ + for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++) + if ((pixel = *pixels)) + *pixels = (pixel == info->cursor_fg) ? fg : bg; + + CURSOR_SWAPPING_END(); + info->cursor_fg = fg; + info->cursor_bg = bg; } @@ -102,6 +140,7 @@ static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) int total_y = pScrn->frameY1 - pScrn->frameY0; int X2 = pScrn->frameX0 + x; int Y2 = pScrn->frameY0 + y; + int stride = 256; if (x < 0) xorigin = -x+1; if (y < 0) yorigin = -y+1; @@ -168,7 +207,7 @@ static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y))); - OUTREG(RADEON_CUR_OFFSET, info->cursor_start + yorigin * 16); + OUTREG(RADEON_CUR_OFFSET, info->cursor_start + yorigin * stride); } else { OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK | (xorigin << 16) @@ -177,7 +216,7 @@ static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y))); OUTREG(RADEON_CUR2_OFFSET, - info->cursor_start + pScrn->fbOffset + yorigin * 16); + info->cursor_start + pScrn->fbOffset + yorigin * stride); } if (info->Clone) { @@ -195,7 +234,7 @@ static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) | ((xorigin ? 0 : X2) << 16) | (yorigin ? 0 : Y2))); OUTREG(RADEON_CUR2_OFFSET, - info->cursor_start + pScrn->fbOffset + yorigin * 16); + info->cursor_start + pScrn->fbOffset + yorigin * stride); } } @@ -206,80 +245,56 @@ static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - CARD32 *s = (CARD32 *)(pointer)image; + CARD8 *s = (CARD8 *)(pointer)image; CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_start); - int y; CARD32 save1 = 0; CARD32 save2 = 0; + CARD8 chunk; + CARD32 i, j; + CURSOR_SWAPPING_DECL if (!info->IsSecondary) { - save1 = INREG(RADEON_CRTC_GEN_CNTL); + save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20); + save1 |= (CARD32) (2 << 20); OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN); } if (info->IsSecondary || info->Clone) { - save2 = INREG(RADEON_CRTC2_GEN_CNTL); + save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20); + save2 |= (CARD32) (2 << 20); OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN); } -#if X_BYTE_ORDER == X_BIG_ENDIAN - switch(info->CurrentLayout.pixel_bytes) { - case 4: - case 3: - for (y = 0; y < 64; y++) { - P_SWAP32(d,s); - d++; s++; - P_SWAP32(d,s); - d++; s++; - P_SWAP32(d,s); - d++; s++; - P_SWAP32(d,s); - d++; s++; - } - break; - case 2: - for (y = 0; y < 64; y++) { - P_SWAP16(d,s); - d++; s++; - P_SWAP16(d,s); - d++; s++; - P_SWAP16(d,s); - d++; s++; - P_SWAP16(d,s); - d++; s++; - } - break; - default: - for (y = 0; y < 64; y++) { - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - } - } -#else - for (y = 0; y < 64; y++) { - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - } +#ifdef ARGB_CURSOR + info->cursor_argb = FALSE; #endif - /* Set the area after the cursor to be all transparent so that we - won't display corrupted cursors on the screen */ - for (y = 0; y < 64; y++) { - *d++ = 0xffffffff; /* The AND bits */ - *d++ = 0xffffffff; - *d++ = 0x00000000; /* The XOR bits */ - *d++ = 0x00000000; + /* + * Convert the bitmap to ARGB32. + * + * HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 always places + * source in the low bit of the pair and mask in the high bit, + * and MSBFirst machines set HARDWARE_CURSOR_BIT_ORDER_MSBFIRST + * (which actually bit swaps the image) to make the bits LSBFirst + */ + CURSOR_SWAPPING_START(); +#define ARGB_PER_CHUNK (8 * sizeof (chunk) / 2) + for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT / ARGB_PER_CHUNK; i++) { + chunk = *s++; + for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2) + *d++ = mono_cursor_color[chunk & 3]; } + CURSOR_SWAPPING_END(); + + info->cursor_bg = mono_cursor_color[2]; + info->cursor_fg = mono_cursor_color[3]; if (!info->IsSecondary) OUTREG(RADEON_CRTC_GEN_CNTL, save1); if (info->IsSecondary || info->Clone) OUTREG(RADEON_CRTC2_GEN_CNTL, save2); + } /* Hide hardware cursor. */ @@ -319,6 +334,87 @@ static Bool RADEONUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) return info->cursor_start ? TRUE : FALSE; } +#ifdef ARGB_CURSOR +#include "cursorstr.h" + +static Bool RADEONUseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->cursor_start && + pCurs->bits->height <= CURSOR_HEIGHT && pCurs->bits->width <= CURSOR_WIDTH) + return TRUE; + return FALSE; +} + +static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_start); + int x, y, w, h; + CARD32 save1 = 0; + CARD32 save2 = 0; + CARD32 *image = pCurs->bits->argb; + CARD32 *i; + CURSOR_SWAPPING_DECL + + if (!image) + return; /* XXX can't happen */ + + if (!info->IsSecondary) { + save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20); + save1 |= (CARD32) (2 << 20); + OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN); + } + + if (info->IsSecondary || info->Clone) { + save2 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20); + save2 |= (CARD32) (2 << 20); + OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN); + } + +#ifdef ARGB_CURSOR + info->cursor_argb = TRUE; +#endif + + CURSOR_SWAPPING_START(); + + w = pCurs->bits->width; + if (w > CURSOR_WIDTH) + w = CURSOR_WIDTH; + h = pCurs->bits->height; + if (h > CURSOR_HEIGHT) + h = CURSOR_HEIGHT; + for (y = 0; y < h; y++) + { + i = image; + image += pCurs->bits->width; + for (x = 0; x < w; x++) + *d++ = *i++; + /* pad to the right with transparent */ + for (; x < CURSOR_WIDTH; x++) + *d++ = 0; + } + /* pad below with transparent */ + for (; y < CURSOR_HEIGHT; y++) + for (x = 0; x < CURSOR_WIDTH; x++) + *d++ = 0; + + CURSOR_SWAPPING_END (); + + if (!info->IsSecondary) + OUTREG(RADEON_CRTC_GEN_CNTL, save1); + + if (info->IsSecondary || info->Clone) + OUTREG(RADEON_CRTC2_GEN_CNTL, save2); + +} + +#endif + + /* Initialize hardware cursor support. */ Bool RADEONCursorInit(ScreenPtr pScreen) { @@ -327,23 +423,25 @@ Bool RADEONCursorInit(ScreenPtr pScreen) xf86CursorInfoPtr cursor; FBAreaPtr fbarea; int width; + int width_bytes; int height; - int size; - + int size_bytes; if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE; - cursor->MaxWidth = 64; - cursor->MaxHeight = 64; + cursor->MaxWidth = CURSOR_WIDTH; + cursor->MaxHeight = CURSOR_HEIGHT; cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP - -#if X_BYTE_ORDER == X_LITTLE_ENDIAN + | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* this is a lie -- + * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST + * actually inverts the bit order, so + * this switches to LSBFIRST + */ | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST #endif - | HARDWARE_CURSOR_INVERT_MASK - | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK - | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 - | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK); + | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1); cursor->SetCursorColors = RADEONSetCursorColors; cursor->SetCursorPosition = RADEONSetCursorPosition; @@ -352,13 +450,18 @@ Bool RADEONCursorInit(ScreenPtr pScreen) cursor->ShowCursor = RADEONShowCursor; cursor->UseHWCursor = RADEONUseHWCursor; - size = (cursor->MaxWidth/4) * cursor->MaxHeight; +#ifdef ARGB_CURSOR + cursor->UseHWCursorARGB = RADEONUseHWCursorARGB; + cursor->LoadCursorARGB = RADEONLoadCursorARGB; +#endif + size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT; width = pScrn->displayWidth; - height = (size*2 + 1023) / pScrn->displayWidth; + width_bytes = width * (pScrn->bitsPerPixel / 8); + height = (size_bytes + width_bytes - 1) / width_bytes; fbarea = xf86AllocateOffscreenArea(pScreen, width, height, - 16, + 256, NULL, NULL, NULL); @@ -369,11 +472,11 @@ Bool RADEONCursorInit(ScreenPtr pScreen) "Hardware cursor disabled" " due to insufficient offscreen memory\n"); } else { - info->cursor_start = RADEON_ALIGN((fbarea->box.x1 - + width * fbarea->box.y1) - * info->CurrentLayout.pixel_bytes, - 16); - info->cursor_end = info->cursor_start + size; + info->cursor_start = RADEON_ALIGN((fbarea->box.x1 + + fbarea->box.y1 * width) * + info->CurrentLayout.pixel_bytes, + 256); + info->cursor_end = info->cursor_start + size_bytes; } RADEONTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n", diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c index ee42e4157..099641a5e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v 1.19 2002/10/12 01:38:07 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v 1.32 2003/02/19 09:17:30 alanh Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, * VA Linux Systems Inc., Fremont, California. @@ -38,8 +38,8 @@ /* Driver data structures */ #include "radeon.h" -#include "radeon_dri.h" #include "radeon_macros.h" +#include "radeon_dri.h" #include "radeon_reg.h" #include "radeon_version.h" @@ -56,12 +56,6 @@ #include "sarea.h" #include "radeon_sarea.h" -#if defined(__alpha__) || defined(__powerpc__) -# define PCIGART_ENABLED -#else -# undef PCIGART_ENABLED -#endif - /* HACK - for now, put this here... */ /* Alpha - this may need to be a variable to handle UP1x00 vs TITAN */ #if defined(__alpha__) @@ -166,9 +160,9 @@ static Bool RADEONInitVisualConfigs(ScreenPtr pScreen) pConfigs[i].accumAlphaSize = 0; } if (db) - pConfigs[i].doubleBuffer = TRUE; + pConfigs[i].doubleBuffer = TRUE; else - pConfigs[i].doubleBuffer = FALSE; + pConfigs[i].doubleBuffer = FALSE; pConfigs[i].stereo = FALSE; pConfigs[i].bufferSize = 16; pConfigs[i].depthSize = 16; @@ -249,9 +243,9 @@ static Bool RADEONInitVisualConfigs(ScreenPtr pScreen) pConfigs[i].accumAlphaSize = 0; } if (db) - pConfigs[i].doubleBuffer = TRUE; + pConfigs[i].doubleBuffer = TRUE; else - pConfigs[i].doubleBuffer = FALSE; + pConfigs[i].doubleBuffer = FALSE; pConfigs[i].stereo = FALSE; pConfigs[i].bufferSize = 32; if (stencil) { @@ -698,6 +692,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen) unsigned char *RADEONMMIO = info->MMIO; unsigned long mode; unsigned int vendor, device; + unsigned long agpBase; int ret; int s, l; @@ -736,8 +731,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen) * market, so this is not yet a problem. */ if ((info->ChipFamily == CHIP_FAMILY_M6) || - (info->ChipFamily == CHIP_FAMILY_M7) || - (info->ChipFamily == CHIP_FAMILY_M9)) + (info->ChipFamily == CHIP_FAMILY_M7)) return FALSE; /* Disable fast write for AMD 761 chipset, since they cause @@ -877,13 +871,13 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen) (unsigned long)info->agpTex); /* Initialize Radeon's AGP registers */ - /* Ring buffer is at AGP offset 0 */ - OUTREG(RADEON_AGP_BASE, info->ringHandle); + + agpBase = drmAgpBase(info->drmFD); + OUTREG(RADEON_AGP_BASE, agpBase); return TRUE; } -#if defined(PCIGART_ENABLED) /* Initialize the PCIGART state. Request memory for use in PCI space, * and initialize the Radeon registers to point to that memory. */ @@ -937,7 +931,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen) (unsigned long)info->ring); xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] Ring contents 0x%08lx\n", - *(unsigned long *)info->ring); + *(unsigned long *)(pointer)info->ring); if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize, DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { @@ -960,7 +954,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen) (unsigned long)info->ringReadPtr); xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] Ring read ptr contents 0x%08lx\n", - *(unsigned long *)info->ringReadPtr); + *(unsigned long *)(pointer)info->ringReadPtr); if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize, DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { @@ -983,11 +977,10 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen) (unsigned long)info->buf); xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] Vertex/indirect buffers contents 0x%08lx\n", - *(unsigned long *)info->buf); + *(unsigned long *)(pointer)info->buf); return TRUE; } -#endif /* Add a map for the MMIO registers that will be accessed by any * DRI-based clients. @@ -1039,7 +1032,7 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) drmInfo.depth_offset = info->depthOffset; drmInfo.depth_pitch = info->depthPitch * cpp; - drmInfo.fb_offset = info->LinearAddr; + drmInfo.fb_offset = info->fbHandle; drmInfo.mmio_offset = info->registerHandle; drmInfo.ring_offset = info->ringHandle; drmInfo.ring_rptr_offset = info->ringReadPtrHandle; @@ -1092,15 +1085,11 @@ static Bool RADEONDRIBufInit(RADEONInfoPtr info, ScreenPtr pScreen) { /* Initialize vertex buffers */ if (info->IsPCI) { -#if !defined(PCIGART_ENABLED) - return TRUE; -#else info->bufNumBufs = drmAddBufs(info->drmFD, info->bufMapSize / RADEON_BUFFER_SIZE, RADEON_BUFFER_SIZE, DRM_SG_BUFFER, info->bufStart); -#endif } else { info->bufNumBufs = drmAddBufs(info->drmFD, info->bufMapSize / RADEON_BUFFER_SIZE, @@ -1415,30 +1404,21 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) drmFreeVersion(version); } -#if !defined(PCIGART_ENABLED) - /* Initialize AGP */ - if (!info->IsPCI && !RADEONDRIAgpInit(info, pScreen)) { - RADEONDRICloseScreen(pScreen); - return FALSE; - } - - /* Initialize PCI */ - if (info->IsPCI) { - xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] PCI cards not yet " - "supported. Disabling DRI.\n"); - RADEONDRICloseScreen(pScreen); - return FALSE; - } -#else /* Initialize AGP */ if (!info->IsPCI && !RADEONDRIAgpInit(info, pScreen)) { +#if defined(__alpha__) || defined(__powerpc__) info->IsPCI = TRUE; xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP failed to initialize " "-- falling back to PCI mode.\n"); xf86DrvMsg(pScreen->myNum, X_WARNING, - "[agp] Make sure you have the agpgart kernel module " - "loaded.\n"); + "[agp] If this is an AGP card, you may want to make sure " + "the agpgart\nkernel module is loaded before the radeon " + "kernel module.\n"); +#else + RADEONDRICloseScreen(pScreen); + return FALSE; +#endif } /* Initialize PCI */ @@ -1446,7 +1426,6 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) RADEONDRICloseScreen(pScreen); return FALSE; } -#endif /* DRIScreenInit doesn't add all the * common mappings. Add additional @@ -1457,6 +1436,18 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) return FALSE; } + /* DRIScreenInit adds the frame buffer + map, but we need it as well */ + { + void *scratch_ptr; + int scratch_int; + + DRIGetDeviceInfo(pScreen, &info->fbHandle, + &scratch_int, &scratch_int, + &scratch_int, &scratch_int, + &scratch_ptr); + } + /* FIXME: When are these mappings unmapped? */ if (!RADEONInitVisualConfigs(pScreen)) { @@ -1557,8 +1548,8 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) #endif /* Have shadowfb run only while there is 3d active. */ - if (info->allowPageFlip /* && info->drmMinor >= 3 */) { - ShadowFBInit2( pScreen, NULL, RADEONDRIRefreshArea, FALSE ); + if (info->allowPageFlip /* && info->drmMinor >= 3 */) { + ShadowFBInit( pScreen, RADEONDRIRefreshArea ); } else { info->allowPageFlip = 0; } @@ -1714,15 +1705,15 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) (CARD32)(-1), -1); for (i = 0 ; i < num ; i++, pbox++) { - int x1 = max(pbox->x1, 0), x2 = min(pbox->x2, pScrn->virtualX-1); - int y1 = max(pbox->y1, 0), y2 = min(pbox->y2, pScrn->virtualY-1); - - if (x1 <= x2 && y1 <= y2) { - (*info->accel->SubsequentScreenToScreenCopy)(pScrn, x1, y1, - x1 + info->backX, - y1 + info->backY, - x2 - x1 + 1, - y2 - y1 + 1); + int xa = max(pbox->x1, 0), xb = min(pbox->x2, pScrn->virtualX-1); + int ya = max(pbox->y1, 0), yb = min(pbox->y2, pScrn->virtualY-1); + + if (xa <= xb && ya <= yb) { + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya, + xa + info->backX, + ya + info->backY, + xb - xa + 1, + yb - ya + 1); } } } @@ -1839,6 +1830,9 @@ static void RADEONDRITransitionTo3d(ScreenPtr pScreen) RADEONEnablePageFlip(pScreen); info->have3DWindows = 1; + + if (info->cursor_start) + xf86ForceHWCursor (pScreen, TRUE); } static void RADEONDRITransitionTo2d(ScreenPtr pScreen) @@ -1861,4 +1855,7 @@ static void RADEONDRITransitionTo2d(ScreenPtr pScreen) xf86FreeOffscreenArea(info->depthTexArea); info->have3DWindows = 0; + + if (info->cursor_start) + xf86ForceHWCursor (pScreen, FALSE); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h index c15990e7b..abfcb4ef0 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h,v 1.3 2002/04/24 16:20:40 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h,v 1.4 2002/10/30 12:52:13 alanh Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, * VA Linux Systems Inc., Fremont, California. diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h index 88593162e..5f011928d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h,v 1.3 2002/04/24 16:20:40 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h,v 1.4 2002/10/30 12:52:13 alanh Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, * VA Linux Systems Inc., Fremont, California. diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c index a36809641..ae584332e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.67 2002/10/16 04:53:15 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.91 2003/02/25 03:50:15 dawes Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -259,6 +259,7 @@ static const char *xf8_32bppSymbols[] = { static const char *ramdacSymbols[] = { "xf86CreateCursorInfoRec", "xf86DestroyCursorInfoRec", + "xf86ForceHWCursor", "xf86InitCursor", NULL }; @@ -272,6 +273,7 @@ static const char *drmSymbols[] = { "drmAddMap", "drmAgpAcquire", "drmAgpAlloc", + "drmAgpBase", "drmAgpBind", "drmAgpDeviceId", "drmAgpEnable", @@ -298,6 +300,7 @@ static const char *drmSymbols[] = { "drmRadeonStartCP", "drmRadeonStopCP", "drmRadeonWaitForIdleCP", + "drmScatterGatherAlloc", "drmScatterGatherFree", "drmUnmap", "drmUnmapBufs", @@ -310,6 +313,7 @@ static const char *driSymbols[] = { "DRIDestroyInfoRec", "DRIFinishScreenInit", "DRIGetContext", + "DRIGetDeviceInfo", "DRIGetSAREAPrivate", "DRILock", "DRIQueryVersion", @@ -320,7 +324,7 @@ static const char *driSymbols[] = { }; static const char *driShadowFBSymbols[] = { - "ShadowFBInit2", + "ShadowFBInit", NULL }; #endif @@ -364,13 +368,13 @@ void RADEONLoaderRefSymLists(void) #ifdef XF86DRI drmSymbols, driSymbols, + driShadowFBSymbols, #endif fbdevHWSymbols, vbeSymbols, int10Symbols, + i2cSymbols, ddcSymbols, - /* i2csymbols, */ - /* driShadowFBSymbols, */ NULL); } @@ -401,16 +405,23 @@ static struct extern int gRADEONEntityIndex; -#if !defined(__alpha__) -# define RADEONPreInt10Save(s, r1, r2) -# define RADEONPostInt10Check(s, r1, r2) -#else /* __alpha__ */ +struct RADEONInt10Save { + CARD32 MEM_CNTL; + CARD32 MEMSIZE; + CARD32 MPP_TB_CONFIG; +}; + +static Bool RADEONMapMMIO(ScrnInfoPtr pScrn); +static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn); + static void -RADEONSaveRegsZapMemCntl(ScrnInfoPtr pScrn, CARD32 *MEM_CNTL, CARD32 *MEMSIZE) +RADEONPreInt10Save(ScrnInfoPtr pScrn, void **pPtr) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO; int mapped = 0; + CARD32 CardTmp; + static struct RADEONInt10Save SaveStruct = { 0, 0, 0 }; /* * First make sure we have the pci and mmio info and that mmio is mapped @@ -429,9 +440,19 @@ RADEONSaveRegsZapMemCntl(ScrnInfoPtr pScrn, CARD32 *MEM_CNTL, CARD32 *MEMSIZE) RADEONMMIO = info->MMIO; /* Save the values and zap MEM_CNTL */ - *MEM_CNTL = INREG(RADEON_MEM_CNTL); - *MEMSIZE = INREG(RADEON_CONFIG_MEMSIZE); + SaveStruct.MEM_CNTL = INREG(RADEON_MEM_CNTL); + SaveStruct.MEMSIZE = INREG(RADEON_CONFIG_MEMSIZE); + SaveStruct.MPP_TB_CONFIG = INREG(RADEON_MPP_TB_CONFIG); + + /* + * Zap MEM_CNTL and set MPP_TB_CONFIG<31:24> to 4 + */ OUTREG(RADEON_MEM_CNTL, 0); + CardTmp = SaveStruct.MPP_TB_CONFIG & 0x00ffffffu; + CardTmp |= 0x04 << 24; + OUTREG(RADEON_MPP_TB_CONFIG, CardTmp); + + *pPtr = (void *)&SaveStruct; /* Unmap mmio space if we mapped it */ if (mapped) @@ -439,15 +460,16 @@ RADEONSaveRegsZapMemCntl(ScrnInfoPtr pScrn, CARD32 *MEM_CNTL, CARD32 *MEMSIZE) } static void -RADEONCheckRegs(ScrnInfoPtr pScrn, CARD32 Saved_MEM_CNTL, CARD32 Saved_MEMSIZE) +RADEONPostInt10Check(ScrnInfoPtr pScrn, void *ptr) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO; - CARD32 MEM_CNTL; + struct RADEONInt10Save *pSave = ptr; + CARD32 CardTmp; int mapped = 0; /* If we don't have a valid (non-zero) saved MEM_CNTL, get out now */ - if (!Saved_MEM_CNTL) + if (!pSave || !pSave->MEM_CNTL) return; /* First make sure that mmio is mapped */ @@ -462,20 +484,33 @@ RADEONCheckRegs(ScrnInfoPtr pScrn, CARD32 Saved_MEM_CNTL, CARD32 Saved_MEMSIZE) * two channels with the two channels configured differently), restore * the saved registers. */ - MEM_CNTL = INREG(RADEON_MEM_CNTL); - if (!MEM_CNTL || - ((MEM_CNTL & 1) && - (((MEM_CNTL >> 8) & 0xff) != ((MEM_CNTL >> 24) & 0xff)))) { + CardTmp = INREG(RADEON_MEM_CNTL); + if (!CardTmp || + ((CardTmp & 1) && + (((CardTmp >> 8) & 0xff) != ((CardTmp >> 24) & 0xff)))) { /* Restore the saved registers */ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Restoring MEM_CNTL (%08x), setting to %08x\n", - MEM_CNTL, Saved_MEM_CNTL); - OUTREG(RADEON_MEM_CNTL, Saved_MEM_CNTL); + CardTmp, pSave->MEM_CNTL); + OUTREG(RADEON_MEM_CNTL, pSave->MEM_CNTL); + CardTmp = INREG(RADEON_CONFIG_MEMSIZE); + if (CardTmp != pSave->MEMSIZE) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Restoring CONFIG_MEMSIZE (%08x), setting to %08x\n", + CardTmp, pSave->MEMSIZE); + OUTREG(RADEON_CONFIG_MEMSIZE, pSave->MEMSIZE); + } + } + + CardTmp = INREG(RADEON_MPP_TB_CONFIG); + if ((CardTmp & 0xff000000u) != (pSave->MPP_TB_CONFIG & 0xff000000u)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Restoring CONFIG_MEMSIZE (%08x), setting to %08x\n", - INREG(RADEON_CONFIG_MEMSIZE), Saved_MEMSIZE); - OUTREG(RADEON_CONFIG_MEMSIZE, Saved_MEMSIZE); + "Restoring MPP_TB_CONFIG<31:24> (%02x), setting to %02x\n", + CardTmp >> 24, pSave->MPP_TB_CONFIG >> 24); + CardTmp &= 0x00ffffffu; + CardTmp |= (pSave->MPP_TB_CONFIG & 0xff000000u); + OUTREG(RADEON_MPP_TB_CONFIG, CardTmp); } /* Unmap mmio space if we mapped it */ @@ -483,12 +518,6 @@ RADEONCheckRegs(ScrnInfoPtr pScrn, CARD32 Saved_MEM_CNTL, CARD32 Saved_MEMSIZE) RADEONUnmapMMIO(pScrn); } -# define RADEONPreInt10Save(s, r1, r2) \ - RADEONSaveRegsZapMemCntl((s), (r1), (r2)) -# define RADEONPostInt10Check(s, r1, r2) \ - RADEONCheckRegs((s), (r1), (r2)) -#endif /* __alpha__ */ - /* Allocate our private RADEONInfoRec */ static Bool RADEONGetRec(ScrnInfoPtr pScrn) { @@ -619,8 +648,7 @@ unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr) OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f); data = INREG(RADEON_CLOCK_CNTL_DATA); - if (info->ChipFamily == CHIP_FAMILY_R300) - R300CGWorkaround(pScrn); + if (info->R300CGWorkaround) R300CGWorkaround(pScrn); return data; } @@ -637,16 +665,37 @@ static int RADEONINPAL(int idx) } #endif -/* Wait for vertical sync */ +/* Wait for vertical sync on primary CRTC */ void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; int i; - OUTREG(RADEON_GEN_INT_STATUS, RADEON_VSYNC_INT_AK); - for (i = 0; i < RADEON_TIMEOUT; i++) { - if (INREG(RADEON_GEN_INT_STATUS) & RADEON_VSYNC_INT) break; + /* Clear the CRTC_VBLANK_SAVE bit */ + OUTREG(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR); + + /* Wait for it to go back up */ + for (i = 0; i < RADEON_TIMEOUT/1000; i++) { + if (INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) break; + usleep(1); + } +} + +/* Wait for vertical sync on secondary CRTC */ +void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + /* Clear the CRTC2_VBLANK_SAVE bit */ + OUTREG(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR); + + /* Wait for it to go back up */ + for (i = 0; i < RADEON_TIMEOUT/1000; i++) { + if (INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) break; + usleep(1); } } @@ -1317,16 +1366,25 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) info->ChipFamily = CHIP_FAMILY_M6; break; - case PCI_CHIP_RADEON_QY: - case PCI_CHIP_RADEON_QZ: + case PCI_CHIP_RV100_QY: + case PCI_CHIP_RV100_QZ: info->ChipFamily = CHIP_FAMILY_VE; break; + case PCI_CHIP_R200_BB: + case PCI_CHIP_R200_QH: + case PCI_CHIP_R200_QI: + case PCI_CHIP_R200_QJ: + case PCI_CHIP_R200_QK: case PCI_CHIP_R200_QL: + case PCI_CHIP_R200_QM: case PCI_CHIP_R200_QN: case PCI_CHIP_R200_QO: + case PCI_CHIP_R200_Qh: + case PCI_CHIP_R200_Qi: + case PCI_CHIP_R200_Qj: + case PCI_CHIP_R200_Qk: case PCI_CHIP_R200_Ql: - case PCI_CHIP_R200_BB: info->ChipFamily = CHIP_FAMILY_R200; break; @@ -1354,6 +1412,10 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) info->ChipFamily = CHIP_FAMILY_M9; break; + case PCI_CHIP_R300_AD: + case PCI_CHIP_R300_AE: + case PCI_CHIP_R300_AF: + case PCI_CHIP_R300_AG: case PCI_CHIP_R300_ND: case PCI_CHIP_R300_NE: case PCI_CHIP_R300_NF: @@ -1479,6 +1541,11 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) info1->CurCloneMode = NULL; } + info->R300CGWorkaround = + (info->ChipFamily == CHIP_FAMILY_R300 && + (INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) + == RADEON_CFG_ATI_REV_A11); + info->MemCntl = INREG(RADEON_SDRAM_MODE_REG); info->BusCntl = INREG(RADEON_BUS_CNTL); RADEONMMIO = NULL; @@ -1515,8 +1582,8 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) #if 0 case PCI_CHIP_RADEON_XX: info->IsPCI = TRUE; break; #endif - case PCI_CHIP_RADEON_QY: - case PCI_CHIP_RADEON_QZ: + case PCI_CHIP_RV100_QY: + case PCI_CHIP_RV100_QZ: case PCI_CHIP_RADEON_LW: case PCI_CHIP_RADEON_LX: case PCI_CHIP_RADEON_LY: @@ -1525,12 +1592,38 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) case PCI_CHIP_RADEON_QE: case PCI_CHIP_RADEON_QF: case PCI_CHIP_RADEON_QG: + case PCI_CHIP_R200_BB: + case PCI_CHIP_R200_QH: + case PCI_CHIP_R200_QI: + case PCI_CHIP_R200_QJ: + case PCI_CHIP_R200_QK: case PCI_CHIP_R200_QL: + case PCI_CHIP_R200_QM: case PCI_CHIP_R200_QN: case PCI_CHIP_R200_QO: + case PCI_CHIP_R200_Qh: + case PCI_CHIP_R200_Qi: + case PCI_CHIP_R200_Qj: + case PCI_CHIP_R200_Qk: case PCI_CHIP_R200_Ql: - case PCI_CHIP_R200_BB: case PCI_CHIP_RV200_QW: + case PCI_CHIP_RV200_QX: + case PCI_CHIP_RV250_Id: + case PCI_CHIP_RV250_Ie: + case PCI_CHIP_RV250_If: + case PCI_CHIP_RV250_Ig: + case PCI_CHIP_RV250_Ld: + case PCI_CHIP_RV250_Le: + case PCI_CHIP_RV250_Lf: + case PCI_CHIP_RV250_Lg: + case PCI_CHIP_R300_AD: + case PCI_CHIP_R300_AE: + case PCI_CHIP_R300_AF: + case PCI_CHIP_R300_AG: + case PCI_CHIP_R300_ND: + case PCI_CHIP_R300_NE: + case PCI_CHIP_R300_NF: + case PCI_CHIP_R300_NG: default: info->IsPCI = FALSE; break; } } @@ -1902,6 +1995,8 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn) new->VSyncEnd = new->VSyncStart + d_timings->v_sync_width; new->Clock = d_timings->clock / 1000; new->Flags = (d_timings->interlaced ? V_INTERLACE : 0); + new->status = MODE_OK; + new->type = M_T_DEFAULT; if (d_timings->sync == 3) { switch (d_timings->misc) { @@ -1918,7 +2013,6 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn) new->name); RADEONSortModes(&new, &first, &last); - break; } } @@ -1938,6 +2032,7 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn) new->name = xnfalloc(strlen(p->name) + 1); strcpy(new->name, p->name); new->status = MODE_OK; + new->type = M_T_DEFAULT; count++; @@ -1969,6 +2064,7 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn) new->name = xnfalloc(strlen(p->name) + 1); strcpy(new->name, p->name); new->status = MODE_OK; + new->type = M_T_DEFAULT; count++; @@ -2007,7 +2103,6 @@ static int RADEONValidateDDCModes(ScrnInfoPtr pScrn, char **ppModeName, pScrn->virtualX = pScrn->display->virtualX; pScrn->virtualY = pScrn->display->virtualY; - /* We have a flat panel connected */ if (pScrn->monitor->DDC) { int maxVirtX = pScrn->virtualX; int maxVirtY = pScrn->virtualY; @@ -2027,7 +2122,8 @@ static int RADEONValidateDDCModes(ScrnInfoPtr pScrn, char **ppModeName, for (p = ddcModes; p; p = p->next) { /* If primary head is a flat panel, use RMX by default */ - if (!info->IsSecondary && DisplayType != MT_CRT) { + if ((!info->IsSecondary && DisplayType != MT_CRT) && + !info->ddc_mode) { /* These values are effective values after expansion. * They are not really used to set CRTC registers. */ @@ -2097,9 +2193,41 @@ static int RADEONValidateDDCModes(ScrnInfoPtr pScrn, char **ppModeName, } } + /* + * Add remaining DDC modes if they're smaller than the user + * specified modes + */ + for (p = ddcModes; p; p = next) { + next = p->next; + if (p->HDisplay <= maxVirtX && p->VDisplay <= maxVirtY) { + /* Unhook from DDC modes */ + if (p->prev) p->prev->next = p->next; + if (p->next) p->next->prev = p->prev; + if (p == ddcModes) ddcModes = p->next; + + /* Add to used modes */ + if (last) { + last->next = p; + p->prev = last; + } else { + first = p; + p->prev = NULL; + } + p->next = NULL; + last = p; + } + } + /* Delete unused modes */ while (ddcModes) xf86DeleteMode(&ddcModes, ddcModes); + } else { + /* + * No modes were configured, so we make the DDC modes + * available for the user to cycle through. + */ + for (p = ddcModes; p; p = p->next) + p->type |= M_T_USERDEF; } pScrn->virtualX = pScrn->display->virtualX = maxVirtX; @@ -2150,6 +2278,7 @@ static DisplayModePtr RADEONFPNativeMode(ScrnInfoPtr pScrn) new->Clock = info->DotClock; new->Flags = 0; + new->type = M_T_USERDEF; new->next = NULL; new->prev = NULL; @@ -2240,7 +2369,10 @@ static int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName) } /* If all else fails, add the native mode */ - if (!count) first = last = RADEONFPNativeMode(pScrn); + if (!count) { + first = last = RADEONFPNativeMode(pScrn); + if (first) count = 1; + } /* Close the doubly-linked mode list, if we found any usable modes */ if (last) { @@ -2460,6 +2592,11 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) "DDC detection (type %d) for clone modes\n", info->CloneDDCType); + /* When primary head has an invalid DDC type, I2C is not + * initialized, so we do it here. + */ + if (!info->ddc2) info->ddc2 = xf86I2CBusInit(info->pI2CBus); + pScrn->monitor->DDC = RADEONDoDDC(pScrn, NULL); if (pScrn->monitor->DDC) { if (info->CloneType == MT_CRT) { @@ -2494,8 +2631,10 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) LOOKUP_BEST_REFRESH); } else { /* Try to add DDC modes */ + info->IsSecondary = TRUE; /* Fake it */ modesFound = RADEONValidateDDCModes(pScrn, clone_mode_names, info->CloneType); + info->IsSecondary = FALSE; /* Restore it!!! */ /* If that fails and we're connect to a flat panel, then try to * add the flat panel modes @@ -2508,7 +2647,7 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) xf86SetCrtcForModes(pScrn, 0); xf86PrintModes(pScrn); for (i = 0; i < modesFound; i++) { - while(pScrn->modes->status != MODE_OK) { + while (pScrn->modes->status != MODE_OK) { pScrn->modes = pScrn->modes->next; } if (!pScrn->modes) break; @@ -2554,6 +2693,16 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) pScrn->monitor->nHsync = save_n_hsync; pScrn->monitor->nVrefresh = save_n_vrefresh; + /* + * Also delete the clockRanges (if it was setup) since it will be + * set up during the primary head initialization. + */ + while (pScrn->clockRanges) { + ClockRangesPtr CRtmp = pScrn->clockRanges; + pScrn->clockRanges = pScrn->clockRanges->next; + xfree(CRtmp); + } + /* modePool is no longer needed, free it */ while (pScrn->modePool) xf86DeleteMode(&pScrn->modePool, pScrn->modePool); @@ -2657,37 +2806,36 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) "No DDC data available, DDCMode option is dismissed\n"); } + if (pScrn->monitor->DDC) { + /* If we still don't know sync range yet, let's try EDID. + * + * Note that, since we can have dual heads, Xconfigurator + * may not be able to probe both monitors correctly through + * vbe probe function (RADEONProbeDDC). Here we provide an + * additional way to auto-detect sync ranges if they haven't + * been added to XF86Config manually. + */ + if (pScrn->monitor->nHsync <= 0) + RADEONSetSyncRangeFromEdid(pScrn, 1); + if (pScrn->monitor->nVrefresh <= 0) + RADEONSetSyncRangeFromEdid(pScrn, 0); + } + + pScrn->progClock = TRUE; + + clockRanges = xnfcalloc(sizeof(*clockRanges), 1); + clockRanges->next = NULL; + clockRanges->minClock = info->pll.min_pll_freq; + clockRanges->maxClock = info->pll.max_pll_freq * 10; + clockRanges->clockIndex = -1; + clockRanges->interlaceAllowed = (info->DisplayType == MT_CRT); + clockRanges->doubleScanAllowed = (info->DisplayType == MT_CRT); + /* We'll use our own mode validation routine for DFP/LCD, since * xf86ValidateModes does not work correctly with the DFP/LCD modes * 'stretched' from their native mode. */ if (info->DisplayType == MT_CRT && !info->ddc_mode) { - - /* Get mode information */ - pScrn->progClock = TRUE; - clockRanges = xnfcalloc(sizeof(*clockRanges), 1); - clockRanges->next = NULL; - clockRanges->minClock = info->pll.min_pll_freq; - clockRanges->maxClock = info->pll.max_pll_freq * 10; - clockRanges->clockIndex = -1; - clockRanges->interlaceAllowed = TRUE; - clockRanges->doubleScanAllowed = TRUE; - - if (pScrn->monitor->DDC) { - /* If we still don't know sync range yet, let's try EDID. - * - * Note that, since we can have dual heads, Xconfigurator - * may not be able to probe both monitors correctly through - * vbe probe function (RADEONProbeDDC). Here we provide an - * additional way to auto-detect sync ranges if they haven't - * been added to XF86Config manually. - */ - if (pScrn->monitor->nHsync <= 0) - RADEONSetSyncRangeFromEdid(pScrn, 1); - if (pScrn->monitor->nVrefresh <= 0) - RADEONSetSyncRangeFromEdid(pScrn, 0); - } - modesFound = xf86ValidateModes(pScrn, pScrn->monitor->Modes, @@ -2749,6 +2897,11 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) } return FALSE; } + + /* Setup the screen's clockRanges for the VidMode extension */ + pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1); + memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges)); + pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH; } xf86SetCrtcForModes(pScrn, 0); @@ -2994,7 +3147,7 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping %sabled\n", - info->allowPageFlip ? "en" : "dis"); + info->allowPageFlip ? "en" : "dis"); return TRUE; } @@ -3016,10 +3169,8 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) { RADEONInfoPtr info; xf86Int10InfoPtr pInt10 = NULL; -#ifdef __alpha__ - CARD32 save1, save2; -#endif - + void *int10_save = NULL; + RADEONTRACE(("RADEONPreInit\n")); if (pScrn->numEntities != 1) return FALSE; @@ -3035,7 +3186,23 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (info->pEnt->location.type != BUS_PCI) goto fail; - RADEONPreInt10Save(pScrn, &save1, &save2); + info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); + info->PciTag = pciTag(info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + +#if !defined(__alpha__) + if (xf86GetPciDomain(info->PciTag) || + !xf86IsPrimaryPci(info->PciInfo)) + RADEONPreInt10Save(pScrn, &int10_save); +#else + /* [Alpha] On the primary, the console already ran the BIOS and we're + * going to run it again - so make sure to "fix up" the card + * so that (1) we can read the BIOS ROM and (2) the BIOS will + * get the memory config right. + */ + RADEONPreInt10Save(pScrn, &int10_save); +#endif if (xf86IsEntityShared(pScrn->entityList[0])) { if (xf86IsPrimInitDone(pScrn->entityList[0])) { @@ -3073,7 +3240,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (flags & PROBE_DETECT) { RADEONProbeDDC(pScrn, info->pEnt->index); - RADEONPostInt10Check(pScrn, save1, save2); + RADEONPostInt10Check(pScrn, int10_save); return TRUE; } @@ -3086,11 +3253,6 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) vgaHWGetIOBase(VGAHWPTR(pScrn)); - info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); - info->PciTag = pciTag(info->PciInfo->bus, - info->PciInfo->device, - info->PciInfo->func); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PCI bus %d card %d func %d\n", info->PciInfo->bus, @@ -3154,7 +3316,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (!RADEONPreInitInt10(pScrn, &pInt10)) goto fail; - RADEONPostInt10Check(pScrn, save1, save2); + RADEONPostInt10Check(pScrn, int10_save); if (!RADEONPreInitConfig(pScrn)) goto fail; @@ -3457,7 +3619,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) info->directRenderingEnabled = FALSE; xf86DrvMsg(scrnIndex, X_WARNING, "Direct rendering not yet supported on " - "Radeon 9700 and newer cards\n"); + "Radeon 9500/9700 and newer cards\n"); } else { if (info->IsSecondary) info->directRenderingEnabled = FALSE; @@ -3546,6 +3708,20 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) fbPictureInit (pScreen, 0, 0); #endif +#ifdef RENDER + if (PictureGetSubpixelOrder (pScreen) == SubPixelUnknown) + { + int subPixelOrder; + + switch (info->DisplayType) { + case MT_NONE: subPixelOrder = SubPixelUnknown; break; + case MT_LCD: subPixelOrder = SubPixelHorizontalRGB; break; + case MT_DFP: subPixelOrder = SubPixelHorizontalRGB; break; + default: subPixelOrder = SubPixelNone; break; + } + PictureSetSubpixelOrder (pScreen, subPixelOrder); + } +#endif /* Memory manager setup */ #ifdef XF86DRI if (info->directRenderingEnabled) { @@ -3793,9 +3969,6 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - /* Set Silken Mouse */ - xf86SetSilkenMouse(pScreen); - /* Acceleration setup */ if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { if (RADEONAccelInit(pScreen)) { @@ -3816,12 +3989,15 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) info->accelOn = FALSE; } + /* DGA setup */ + RADEONDGAInit(pScreen); + /* Backing store setup */ miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); - /* DGA setup */ - RADEONDGAInit(pScreen); + /* Set Silken Mouse */ + xf86SetSilkenMouse(pScreen); /* Cursor setup */ miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); @@ -3847,6 +4023,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } } else { + info->cursor_start = 0; xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); } @@ -3924,6 +4101,7 @@ static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, * CRT are connected. */ if (info->HasCRTC2 && + !info->IsSwitching && info->ChipFamily != CHIP_FAMILY_R200 && info->ChipFamily != CHIP_FAMILY_R300) { DevUnion *pPriv; @@ -4020,7 +4198,7 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, * TV_DAC_CNTL to a correct value which causes too high * contrast for the second CRT (using TV_DAC). */ - OUTREG(0x88c, 0x00280203); + OUTREG(RADEON_TV_DAC_CNTL, 0x00280203); } } @@ -4155,9 +4333,25 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, RADEON_PLL_DIV_SEL, ~(RADEON_PLL_DIV_SEL)); - OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, - restore->ppll_ref_div, - ~RADEON_PPLL_REF_DIV_MASK); + if (info->ChipFamily == CHIP_FAMILY_R300) { + if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { + /* When restoring console mode, use saved PPLL_REF_DIV + * setting. + */ + OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, + restore->ppll_ref_div, + 0); + } else { + /* R300 uses ref_div_acc field as real ref divider */ + OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, + (restore->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT), + ~R300_PPLL_REF_DIV_ACC_MASK); + } + } else { + OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, + restore->ppll_ref_div, + ~RADEON_PPLL_REF_DIV_MASK); + } OUTPLLP(pScrn, RADEON_PPLL_DIV_3, restore->ppll_div_3, @@ -4588,8 +4782,7 @@ static void RADEONSave(ScrnInfoPtr pScrn) save->dp_datatype = INREG(RADEON_DP_DATATYPE); save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); - if (info->ChipFamily == CHIP_FAMILY_R300) - R300CGWorkaround(pScrn); + if (info->R300CGWorkaround) R300CGWorkaround(pScrn); } RADEONSaveMode(pScrn, save); @@ -4617,8 +4810,7 @@ static void RADEONRestore(ScrnInfoPtr pScrn) RADEONBlank(pScrn); OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index); - if (info->ChipFamily == CHIP_FAMILY_R300) - R300CGWorkaround(pScrn); + if (info->R300CGWorkaround) R300CGWorkaround(pScrn); OUTREG(RADEON_RBBM_SOFT_RESET, restore->rbbm_soft_reset); OUTREG(RADEON_DP_DATATYPE, restore->dp_datatype); @@ -4783,12 +4975,11 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, << 16)); hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; - if (!hsync_wid) hsync_wid = 1; - if (hsync_wid > 0x3f) hsync_wid = 0x3f; + if (!hsync_wid) hsync_wid = 1; hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) - | (hsync_wid << 16) + | ((hsync_wid & 0x3f) << 16) | ((mode->Flags & V_NHSYNC) ? RADEON_CRTC_H_SYNC_POL : 0)); @@ -4808,11 +4999,10 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, #endif vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; - if (!vsync_wid) vsync_wid = 1; - if (vsync_wid > 0x1f) vsync_wid = 0x1f; + if (!vsync_wid) vsync_wid = 1; save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) - | (vsync_wid << 16) + | ((vsync_wid & 0x1f) << 16) | ((mode->Flags & V_NVSYNC) ? RADEON_CRTC_V_SYNC_POL : 0)); @@ -4920,15 +5110,14 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16)); hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; - if (!hsync_wid) hsync_wid = 1; - if (hsync_wid > 0x3f) hsync_wid = 0x3f; + if (!hsync_wid) hsync_wid = 1; hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff) - | (hsync_wid << 16) + | ((hsync_wid & 0x3f) << 16) | ((mode->Flags & V_NHSYNC) ? RADEON_CRTC_H_SYNC_POL - : RADEON_CRTC_H_SYNC_POL)); + : 0)); #if 1 /* This works for double scan mode. */ @@ -4945,14 +5134,13 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, #endif vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; - if (!vsync_wid) vsync_wid = 1; - if (vsync_wid > 0x1f) vsync_wid = 0x1f; + if (!vsync_wid) vsync_wid = 1; save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) - | (vsync_wid << 16) + | ((vsync_wid & 0x1f) << 16) | ((mode->Flags & V_NVSYNC) ? RADEON_CRTC2_V_SYNC_POL - : RADEON_CRTC2_V_SYNC_POL)); + : 0)); save->crtc2_offset = 0; save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL); @@ -4970,6 +5158,11 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, RADEON_FP2_PANEL_FORMAT | RADEON_FP2_ON); + if (pScrn->rgbBits == 8) + save->fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format */ + else + save->fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format */ + /* FIXME: When there are two DFPs, the 2nd DFP is driven by the * external TMDS transmitter. It may have a problem at * high dot clock for certain panels. Since we don't @@ -5075,12 +5268,18 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, save->fp_gen_cntl |= (RADEON_FP_CRTC_DONT_SHADOW_VPAR | RADEON_FP_CRTC_DONT_SHADOW_HEND ); + if (pScrn->rgbBits == 8) + save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ + else + save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */ + save->lvds_gen_cntl = orig->lvds_gen_cntl; save->lvds_pll_cntl = orig->lvds_pll_cntl; /* This is needed for some panel at high resolution (>=1600x1200) */ - if (save->dot_clock_freq > 15000) + if ((save->dot_clock_freq > 15000) && + (info->ChipFamily != CHIP_FAMILY_R300)) save->tmds_pll_cntl = 0xA3F; else save->tmds_pll_cntl = orig->tmds_pll_cntl; @@ -5291,8 +5490,7 @@ static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, info->Flags = mode->Flags; if (info->IsSecondary) { - if (!RADEONInitCrtc2Registers(pScrn, save, - pScrn->currentMode,info)) + if (!RADEONInitCrtc2Registers(pScrn, save, mode, info)) return FALSE; RADEONInitPLL2Registers(save, &info->pll, dot_clock); } else { @@ -5301,23 +5499,7 @@ static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, return FALSE; dot_clock = mode->Clock/1000.0; if (dot_clock) { - if (info->ChipFamily == CHIP_FAMILY_R300) { - CARD16 ref_div = info->pll.reference_div; - - /* When using a DFP on R300, the BIOS seems to configure - * the reference divider to a value different from the - * value in PLL information table. Here we use the - * register value set by the BIOS. We need to restore - * the PLL info table value back in case it needs to be - * used for the 2nd head. - */ - info->pll.reference_div = (INPLL(pScrn, RADEON_PPLL_REF_DIV) & - RADEON_PPLL_REF_DIV_MASK); - RADEONInitPLLRegisters(save, &info->pll, dot_clock); - info->pll.reference_div = ref_div; - } else { - RADEONInitPLLRegisters(save, &info->pll, dot_clock); - } + RADEONInitPLLRegisters(save, &info->pll, dot_clock); } else { save->ppll_ref_div = info->SavedReg.ppll_ref_div; save->ppll_div_3 = info->SavedReg.ppll_div_3; @@ -5419,17 +5601,7 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) } if (!clone_mode->next) { - if (info->CurCloneMode->next) - info->CurCloneMode = info->CurCloneMode->next; - else - info->CurCloneMode = info->CloneModes; - - info->CloneFrameX0 = (info->CurCloneMode->HDisplay + - info->CloneFrameX0 - - clone_mode->HDisplay - 1) / 2; - info->CloneFrameY0 = - (info->CurCloneMode->VDisplay + info->CloneFrameY0 - - clone_mode->VDisplay - 1) / 2; + info->CurCloneMode = info->CloneModes; break; } @@ -5453,7 +5625,8 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) else if (info->CloneFrameY0 < 0) info->CloneFrameY0 = 0; - RADEONDoAdjustFrame(pScrn, info->CloneFrameX0, info->CloneFrameY0, TRUE); + RADEONDoAdjustFrame(pScrn, info->CloneFrameX0, info->CloneFrameY0, + TRUE); } info->IsSwitching = FALSE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c index 751e561cf..d9c978fee 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c,v 1.6 2002/04/24 16:20:40 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c,v 1.7 2003/01/01 19:16:35 tsi Exp $ */ /* - * Copyright 2000 through 2002 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * Copyright 2000 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -63,13 +63,13 @@ RADEONSetup static Bool Inited = FALSE; if (!Inited) { - /* Ensure main driver module is loaded, but not as a submodule */ - if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME)) - xf86LoadOneModule(ATI_DRIVER_NAME, Options); + /* Ensure main driver module is loaded, but not as a submodule */ + if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME)) + xf86LoadOneModule(ATI_DRIVER_NAME, Options); - RADEONLoaderRefSymLists(); + RADEONLoaderRefSymLists(); - Inited = TRUE; + Inited = TRUE; } return (pointer)TRUE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c index 64c575365..bcf80c188 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c,v 1.20 2002/10/12 01:38:07 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c,v 1.24 2003/02/07 20:41:15 martin Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -78,15 +78,24 @@ SymTabRec RADEONChipsets[] = { { PCI_CHIP_RADEON_QE, "ATI Radeon QE (AGP)" }, { PCI_CHIP_RADEON_QF, "ATI Radeon QF (AGP)" }, { PCI_CHIP_RADEON_QG, "ATI Radeon QG (AGP)" }, - { PCI_CHIP_RADEON_QY, "ATI Radeon VE QY (AGP)" }, - { PCI_CHIP_RADEON_QZ, "ATI Radeon VE QZ (AGP)" }, + { PCI_CHIP_RV100_QY, "ATI Radeon VE/7000 QY (AGP)" }, + { PCI_CHIP_RV100_QZ, "ATI Radeon VE/7000 QZ (AGP)" }, { PCI_CHIP_RADEON_LW, "ATI Radeon Mobility M7 LW (AGP)" }, - { PCI_CHIP_RADEON_LX, "ATI Radeon Mobility M7 LX (AGP)" }, + { PCI_CHIP_RADEON_LX, "ATI Mobility FireGL 7800 M7 LX (AGP)" }, { PCI_CHIP_RADEON_LY, "ATI Radeon Mobility M6 LY (AGP)" }, { PCI_CHIP_RADEON_LZ, "ATI Radeon Mobility M6 LZ (AGP)" }, + { PCI_CHIP_R200_QH, "ATI FireGL 8700/8800 QH (AGP)" }, + { PCI_CHIP_R200_QI, "ATI Radeon 8500 QI (AGP)" }, + { PCI_CHIP_R200_QJ, "ATI Radeon 8500 QJ (AGP)" }, + { PCI_CHIP_R200_QK, "ATI Radeon 8500 QK (AGP)" }, { PCI_CHIP_R200_QL, "ATI Radeon 8500 QL (AGP)" }, + { PCI_CHIP_R200_QM, "ATI Radeon 9100 QM (AGP)" }, { PCI_CHIP_R200_QN, "ATI Radeon 8500 QN (AGP)" }, { PCI_CHIP_R200_QO, "ATI Radeon 8500 QO (AGP)" }, + { PCI_CHIP_R200_Qh, "ATI Radeon 8500 Qh (AGP)" }, + { PCI_CHIP_R200_Qi, "ATI Radeon 8500 Qi (AGP)" }, + { PCI_CHIP_R200_Qj, "ATI Radeon 8500 Qj (AGP)" }, + { PCI_CHIP_R200_Qk, "ATI Radeon 8500 Qk (AGP)" }, { PCI_CHIP_R200_Ql, "ATI Radeon 8500 Ql (AGP)" }, { PCI_CHIP_R200_BB, "ATI Radeon 8500 BB (AGP)" }, { PCI_CHIP_RV200_QW, "ATI Radeon 7500 QW (AGP)" }, @@ -99,10 +108,14 @@ SymTabRec RADEONChipsets[] = { { PCI_CHIP_RV250_Le, "ATI Radeon Mobility M9 Le (AGP)" }, { PCI_CHIP_RV250_Lf, "ATI Radeon Mobility M9 Lf (AGP)" }, { PCI_CHIP_RV250_Lg, "ATI Radeon Mobility M9 Lg (AGP)" }, - { PCI_CHIP_R300_ND, "ATI Radeon 9700 ND (AGP)" }, - { PCI_CHIP_R300_NE, "ATI Radeon 9700 NE (AGP)" }, + { PCI_CHIP_R300_AD, "ATI Radeon 9500 AD (AGP)" }, + { PCI_CHIP_R300_AE, "ATI Radeon 9500 AE (AGP)" }, + { PCI_CHIP_R300_AF, "ATI Radeon 9500 AF (AGP)" }, + { PCI_CHIP_R300_AG, "ATI FireGL Z1/X1 AG (AGP)" }, + { PCI_CHIP_R300_ND, "ATI Radeon 9700 Pro ND (AGP)" }, + { PCI_CHIP_R300_NE, "ATI Radeon 9700/9500Pro NE (AGP)" }, { PCI_CHIP_R300_NF, "ATI Radeon 9700 NF (AGP)" }, - { PCI_CHIP_R300_NG, "ATI Radeon 9700 NG (AGP)" }, + { PCI_CHIP_R300_NG, "ATI FireGL X1 NG (AGP)" }, { -1, NULL } }; @@ -111,15 +124,24 @@ PciChipsets RADEONPciChipsets[] = { { PCI_CHIP_RADEON_QE, PCI_CHIP_RADEON_QE, RES_SHARED_VGA }, { PCI_CHIP_RADEON_QF, PCI_CHIP_RADEON_QF, RES_SHARED_VGA }, { PCI_CHIP_RADEON_QG, PCI_CHIP_RADEON_QG, RES_SHARED_VGA }, - { PCI_CHIP_RADEON_QY, PCI_CHIP_RADEON_QY, RES_SHARED_VGA }, - { PCI_CHIP_RADEON_QZ, PCI_CHIP_RADEON_QZ, RES_SHARED_VGA }, + { PCI_CHIP_RV100_QY, PCI_CHIP_RV100_QY, RES_SHARED_VGA }, + { PCI_CHIP_RV100_QZ, PCI_CHIP_RV100_QZ, RES_SHARED_VGA }, { PCI_CHIP_RADEON_LW, PCI_CHIP_RADEON_LW, RES_SHARED_VGA }, { PCI_CHIP_RADEON_LX, PCI_CHIP_RADEON_LX, RES_SHARED_VGA }, { PCI_CHIP_RADEON_LY, PCI_CHIP_RADEON_LY, RES_SHARED_VGA }, { PCI_CHIP_RADEON_LZ, PCI_CHIP_RADEON_LZ, RES_SHARED_VGA }, + { PCI_CHIP_R200_QH, PCI_CHIP_R200_QH, RES_SHARED_VGA }, + { PCI_CHIP_R200_QI, PCI_CHIP_R200_QI, RES_SHARED_VGA }, + { PCI_CHIP_R200_QJ, PCI_CHIP_R200_QJ, RES_SHARED_VGA }, + { PCI_CHIP_R200_QK, PCI_CHIP_R200_QK, RES_SHARED_VGA }, { PCI_CHIP_R200_QL, PCI_CHIP_R200_QL, RES_SHARED_VGA }, + { PCI_CHIP_R200_QM, PCI_CHIP_R200_QM, RES_SHARED_VGA }, { PCI_CHIP_R200_QN, PCI_CHIP_R200_QN, RES_SHARED_VGA }, { PCI_CHIP_R200_QO, PCI_CHIP_R200_QO, RES_SHARED_VGA }, + { PCI_CHIP_R200_Qh, PCI_CHIP_R200_Qh, RES_SHARED_VGA }, + { PCI_CHIP_R200_Qi, PCI_CHIP_R200_Qi, RES_SHARED_VGA }, + { PCI_CHIP_R200_Qj, PCI_CHIP_R200_Qj, RES_SHARED_VGA }, + { PCI_CHIP_R200_Qk, PCI_CHIP_R200_Qk, RES_SHARED_VGA }, { PCI_CHIP_R200_Ql, PCI_CHIP_R200_Ql, RES_SHARED_VGA }, { PCI_CHIP_R200_BB, PCI_CHIP_R200_BB, RES_SHARED_VGA }, { PCI_CHIP_RV200_QW, PCI_CHIP_RV200_QW, RES_SHARED_VGA }, @@ -132,6 +154,10 @@ PciChipsets RADEONPciChipsets[] = { { PCI_CHIP_RV250_Le, PCI_CHIP_RV250_Le, RES_SHARED_VGA }, { PCI_CHIP_RV250_Lf, PCI_CHIP_RV250_Lf, RES_SHARED_VGA }, { PCI_CHIP_RV250_Lg, PCI_CHIP_RV250_Lg, RES_SHARED_VGA }, + { PCI_CHIP_R300_AD, PCI_CHIP_R300_AD, RES_SHARED_VGA }, + { PCI_CHIP_R300_AE, PCI_CHIP_R300_AE, RES_SHARED_VGA }, + { PCI_CHIP_R300_AF, PCI_CHIP_R300_AF, RES_SHARED_VGA }, + { PCI_CHIP_R300_AG, PCI_CHIP_R300_AG, RES_SHARED_VGA }, { PCI_CHIP_R300_ND, PCI_CHIP_R300_ND, RES_SHARED_VGA }, { PCI_CHIP_R300_NE, PCI_CHIP_R300_NE, RES_SHARED_VGA }, { PCI_CHIP_R300_NF, PCI_CHIP_R300_NF, RES_SHARED_VGA }, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h index 22a278add..adf38650d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.20 2002/10/12 01:38:07 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.25 2003/02/07 18:08:59 martin Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -217,6 +217,10 @@ #define RADEON_CONFIG_APER_SIZE 0x0108 #define RADEON_CONFIG_BONDS 0x00e8 #define RADEON_CONFIG_CNTL 0x00e0 +# define RADEON_CFG_ATI_REV_A11 (0 << 16) +# define RADEON_CFG_ATI_REV_A12 (1 << 16) +# define RADEON_CFG_ATI_REV_A13 (2 << 16) +# define RADEON_CFG_ATI_REV_ID_MASK (0xf << 16) #define RADEON_CONFIG_MEMSIZE 0x00f8 #define RADEON_CONFIG_MEMSIZE_EMBEDDED 0x0114 #define RADEON_CONFIG_REG_1_BASE 0x010c @@ -303,6 +307,10 @@ #define RADEON_CRTC2_PITCH 0x032c #define RADEON_CRTC_STATUS 0x005c # define RADEON_CRTC_VBLANK_SAVE (1 << 1) +# define RADEON_CRTC_VBLANK_SAVE_CLEAR (1 << 1) +#define RADEON_CRTC2_STATUS 0x03fc +# define RADEON_CRTC2_VBLANK_SAVE (1 << 1) +# define RADEON_CRTC2_VBLANK_SAVE_CLEAR (1 << 1) #define RADEON_CRTC_V_SYNC_STRT_WID 0x020c # define RADEON_CRTC_V_SYNC_STRT (0x7ff << 0) # define RADEON_CRTC_V_SYNC_STRT_SHIFT 0 @@ -493,6 +501,7 @@ #define RADEON_DST_LINE_START 0x1600 #define RADEON_DST_LINE_END 0x1604 #define RADEON_DST_LINE_PATCOUNT 0x1608 +# define RADEON_BRES_CNTL_SHIFT 8 #define RADEON_DST_OFFSET 0x1404 #define RADEON_DST_PITCH 0x1408 #define RADEON_DST_PITCH_OFFSET 0x142c @@ -555,6 +564,7 @@ #define RADEON_FP_GEN_CNTL 0x0284 # define RADEON_FP_FPON (1 << 0) # define RADEON_FP_TMDS_EN (1 << 2) +# define RADEON_FP_PANEL_FORMAT (1 << 3) # define RADEON_FP_EN_TMDS (1 << 7) # define RADEON_FP_DETECT_SENSE (1 << 8) # define RADEON_FP_SEL_CRTC2 (1 << 13) @@ -613,6 +623,8 @@ #define RADEON_GEN_INT_STATUS 0x0044 # define RADEON_VSYNC_INT_AK (1 << 2) # define RADEON_VSYNC_INT (1 << 2) +# define RADEON_VSYNC2_INT_AK (1 << 6) +# define RADEON_VSYNC2_INT (1 << 6) #define RADEON_GENENB 0x03c3 /* VGA */ #define RADEON_GENFC_RD 0x03ca /* VGA */ #define RADEON_GENFC_WT 0x03da /* VGA, 0x03ba */ @@ -709,6 +721,9 @@ #define RADEON_MM_DATA 0x0004 #define RADEON_MM_INDEX 0x0000 #define RADEON_MPLL_CNTL 0x000e /* PLL */ +#define RADEON_MPP_TB_CONFIG 0x01c0 /* ? */ +#define RADEON_MPP_GP_CONFIG 0x01c8 /* ? */ + #define RADEON_N_VIF_COUNT 0x0248 @@ -864,6 +879,8 @@ # define RADEON_P2PLL_REF_DIV_MASK 0x03ff # define RADEON_P2PLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ # define RADEON_P2PLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +# define R300_PPLL_REF_DIV_ACC_MASK (0x3ff < 18) +# define R300_PPLL_REF_DIV_ACC_SHIFT 18 #define RADEON_PALETTE_DATA 0x00b4 #define RADEON_PALETTE_30_DATA 0x00b8 #define RADEON_PALETTE_INDEX 0x00b0 @@ -1183,20 +1200,20 @@ #define RADEON_PP_CUBIC_FACES_2 0x1d2c # define RADEON_FACE_WIDTH_1_SHIFT 0 # define RADEON_FACE_HEIGHT_1_SHIFT 4 -# define RADEON_FACE_WIDTH_1_MASK 0xf << 0) -# define RADEON_FACE_HEIGHT_1_MASK 0xf << 4) +# define RADEON_FACE_WIDTH_1_MASK (0xf << 0) +# define RADEON_FACE_HEIGHT_1_MASK (0xf << 4) # define RADEON_FACE_WIDTH_2_SHIFT 8 -# define RADEON_FACE_HEIGHT_2_SHIFT 2 -# define RADEON_FACE_WIDTH_2_MASK 0xf << 8) -# define RADEON_FACE_HEIGHT_2_MASK 0xf << 12) -# define RADEON_FACE_WIDTH_3_SHIFT 6 -# define RADEON_FACE_HEIGHT_3_SHIFT 0 -# define RADEON_FACE_WIDTH_3_MASK 0xf << 16) -# define RADEON_FACE_HEIGHT_3_MASK 0xf << 20) -# define RADEON_FACE_WIDTH_4_SHIFT 4 -# define RADEON_FACE_HEIGHT_4_SHIFT 8 -# define RADEON_FACE_WIDTH_4_MASK 0xf << 24) -# define RADEON_FACE_HEIGHT_4_MASK 0xf << 28) +# define RADEON_FACE_HEIGHT_2_SHIFT 12 +# define RADEON_FACE_WIDTH_2_MASK (0xf << 8) +# define RADEON_FACE_HEIGHT_2_MASK (0xf << 12) +# define RADEON_FACE_WIDTH_3_SHIFT 16 +# define RADEON_FACE_HEIGHT_3_SHIFT 20 +# define RADEON_FACE_WIDTH_3_MASK (0xf << 16) +# define RADEON_FACE_HEIGHT_3_MASK (0xf << 20) +# define RADEON_FACE_WIDTH_4_SHIFT 24 +# define RADEON_FACE_HEIGHT_4_SHIFT 28 +# define RADEON_FACE_WIDTH_4_MASK (0xf << 24) +# define RADEON_FACE_HEIGHT_4_MASK (0xf << 28) #define RADEON_PP_TXOFFSET_0 0x1c5c #define RADEON_PP_TXOFFSET_1 0x1c74 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h index e7d648271..788c6f690 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h,v 1.4 2002/04/24 16:20:41 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h,v 1.5 2002/10/30 12:52:14 alanh Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, * VA Linux Systems Inc., Fremont, California. diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h index b9a22e283..a1170d389 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h @@ -1,6 +1,6 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h,v 1.4 2002/04/06 19:06:07 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h,v 1.8 2003/01/01 19:16:35 tsi Exp $ */ /* - * Copyright 2000 through 2002 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * Copyright 2000 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -24,16 +24,29 @@ #ifndef _RADEON_VERSION_H_ #define _RADEON_VERSION_H_ 1 +#undef RADEON_NAME +#undef RADEON_DRIVER_NAME +#undef R200_DRIVER_NAME +#undef RADEON_VERSION_MAJOR +#undef RADEON_VERSION_MINOR +#undef RADEON_VERSION_PATCH +#undef RADEON_VERSION_CURRENT +#undef RADEON_VERSION_EVALUATE +#undef RADEON_VERSION_STRINGIFY +#undef RADEON_VERSION_NAME + #define RADEON_NAME "RADEON" #define RADEON_DRIVER_NAME "radeon" #define R200_DRIVER_NAME "r200" -#define RV250_DRIVER_NAME "r200" +#define RV250_DRIVER_NAME "r200" #define RADEON_VERSION_MAJOR 4 #define RADEON_VERSION_MINOR 0 #define RADEON_VERSION_PATCH 1 +#ifndef RADEON_VERSION_EXTRA #define RADEON_VERSION_EXTRA "" +#endif #define RADEON_VERSION_CURRENT \ ((RADEON_VERSION_MAJOR << 20) | \ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c index 88d323a0a..44ee2e688 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c @@ -1,7 +1,8 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c,v 1.18 2002/10/12 01:38:08 martin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c,v 1.24 2003/02/19 01:19:43 dawes Exp $ */ #include "radeon.h" #include "radeon_macros.h" +#include "radeon_probe.h" #include "radeon_reg.h" #include "xf86.h" @@ -19,6 +20,8 @@ #define TIMER_MASK (OFF_TIMER | FREE_TIMER) +extern int gRADEONEntityIndex; + #ifndef XvExtension void RADEONInitVideo(ScreenPtr pScreen) {} #else @@ -401,21 +404,14 @@ RADEONResetVideo(ScrnInfoPtr pScrn) if (info->ChipFamily == CHIP_FAMILY_R200 || info->ChipFamily == CHIP_FAMILY_R300) { + int i; + OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a20000); OUTREG(RADEON_OV0_LIN_TRANS_B, 0x198a190e); OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a2f9da); OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf2fe0442); OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a22046); OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f); - } else { - int i; - - OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000); - OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e); - OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0); - OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442); - OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040); - OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f); /* * Set default Gamma ramp: @@ -428,6 +424,13 @@ RADEONResetVideo(ScrnInfoPtr pScrn) OUTREG(def_gamma[i].gammaReg, (def_gamma[i].gammaSlope<<16) | def_gamma[i].gammaOffset); } + } else { + OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000); + OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e); + OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0); + OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442); + OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040); + OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f); } } @@ -677,6 +680,8 @@ RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup) if(pPriv->videoStatus & CLIENT_VIDEO_ON) { RADEONWaitForFifo(pScrn, 2); OUTREG(RADEON_OV0_SCALE_CNTL, 0); + if (info->cursor_start) + xf86ForceHWCursor (pScrn->pScreen, FALSE); } if(info->videoLinear) { xf86FreeOffscreenLinear(info->videoLinear); @@ -1004,6 +1009,11 @@ RADEONDisplayVideo( offset1 += ((left >> 16) & ~7) << 1; offset2 += ((left >> 16) & ~7) << 1; + if (info->IsSecondary) { + offset1 += info->FbMapSize; + offset2 += info->FbMapSize; + } + tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); p1_h_accum_init = ((tmp << 4) & 0x000f8000) | ((tmp << 12) & 0xf0000000); @@ -1035,14 +1045,12 @@ RADEONDisplayVideo( x_off = 0; /* Put the hardware overlay on CRTC2: - * For now, the CRTC2 overlay is only implemented for clone mode. - * Xinerama 2nd head will be similar, but there are other issues. * * Since one hardware overlay can not be displayed on two heads * at the same time, we might need to consider using software - * rendering for the second head (do we really need it?). + * rendering for the second head. */ - if (info->Clone && info->OverlayOnCRTC2) { + if ((info->Clone && info->OverlayOnCRTC2) || info->IsSecondary) { x_off = 0; OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off @@ -1134,6 +1142,13 @@ RADEONPutImage( int top, left, npixels, nlines, bpp; BoxRec dstBox; CARD32 tmp; +#if X_BYTE_ORDER == X_BIG_ENDIAN + unsigned char *RADEONMMIO = info->MMIO; + CARD32 surface_cntl = INREG(RADEON_SURFACE_CNTL); + + OUTREG(RADEON_SURFACE_CNTL, (surface_cntl | + RADEON_NONSURF_AP0_SWP_32BPP) & ~RADEON_NONSURF_AP0_SWP_16BPP); +#endif /* * s2offset, s3offset - byte offsets into U and V plane of the @@ -1211,6 +1226,7 @@ RADEONPutImage( offset = (info->videoLinear->offset * bpp) + (top * dstPitch); if(pPriv->doubleBuffer) offset += pPriv->currentBuffer * new_size * bpp; + dst_start = info->FB + offset; switch(id) { @@ -1227,24 +1243,13 @@ RADEONPutImage( s3offset = tmp; } nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top; - { - #if X_BYTE_ORDER == X_BIG_ENDIAN - unsigned char *RADEONMMIO = info->MMIO; - CARD32 surface_cntl; - - surface_cntl = INREG(RADEON_SURFACE_CNTL); - OUTREG(RADEON_SURFACE_CNTL, (surface_cntl | - RADEON_NONSURF_AP0_SWP_32BPP) & ~RADEON_NONSURF_AP0_SWP_16BPP); + OUTREG(RADEON_SURFACE_CNTL, (surface_cntl | RADEON_NONSURF_AP0_SWP_32BPP) + & ~RADEON_NONSURF_AP0_SWP_16BPP); #endif RADEONCopyMungedData(buf + (top * srcPitch) + left, buf + s2offset, - buf + s3offset, dst_start, srcPitch, srcPitch2, - dstPitch, nlines, npixels); -#if X_BYTE_ORDER == X_BIG_ENDIAN - /* restore byte swapping */ - OUTREG(RADEON_SURFACE_CNTL, surface_cntl); -#endif - } + buf + s3offset, dst_start, srcPitch, srcPitch2, + dstPitch, nlines, npixels); break; case FOURCC_UYVY: case FOURCC_YUY2: @@ -1253,10 +1258,18 @@ RADEONPutImage( buf += (top * srcPitch) + left; nlines = ((yb + 0xffff) >> 16) - top; dst_start += left; +#if X_BYTE_ORDER == X_BIG_ENDIAN + OUTREG(RADEON_SURFACE_CNTL, surface_cntl & ~(RADEON_NONSURF_AP0_SWP_32BPP + | RADEON_NONSURF_AP0_SWP_16BPP)); +#endif RADEONCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels); break; } +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* restore byte swapping */ + OUTREG(RADEON_SURFACE_CNTL, surface_cntl); +#endif /* update cliplist */ if(!RegionsEqual(&pPriv->clip, clipBoxes)) @@ -1270,6 +1283,9 @@ RADEONPutImage( REGION_RECTS(clipBoxes)); } + if (info->cursor_start && !(pPriv->videoStatus & CLIENT_VIDEO_ON)) + xf86ForceHWCursor (pScrn->pScreen, TRUE); + RADEONDisplayVideo(pScrn, id, offset, offset, width, height, dstPitch, xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h); @@ -1334,6 +1350,8 @@ RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now) if(pPriv->offTime < now) { unsigned char *RADEONMMIO = info->MMIO; OUTREG(RADEON_OV0_SCALE_CNTL, 0); + if (info->cursor_start && pPriv->videoStatus & CLIENT_VIDEO_ON) + xf86ForceHWCursor (pScrn->pScreen, FALSE); pPriv->videoStatus = FREE_TIMER; pPriv->freeTime = now + FREE_DELAY; } @@ -1343,6 +1361,8 @@ RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now) xf86FreeOffscreenLinear(info->videoLinear); info->videoLinear = NULL; } + if (info->cursor_start && pPriv->videoStatus & CLIENT_VIDEO_ON) + xf86ForceHWCursor (pScrn->pScreen, FALSE); pPriv->videoStatus = 0; info->VideoTimerCallback = NULL; } @@ -1524,6 +1544,8 @@ RADEONDisplaySurface( if (portPriv->videoStatus & CLIENT_VIDEO_ON) { REGION_EMPTY(pScrn->pScreen, &portPriv->clip); UpdateCurrentTime(); + if (info->cursor_start) + xf86ForceHWCursor (pScrn->pScreen, FALSE); portPriv->videoStatus = FREE_TIMER; portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; info->VideoTimerCallback = RADEONVideoTimerCallback; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_video.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_video.c index 0aa1bb504..f5a824e90 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_video.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_video.c,v 1.11 2002/09/16 18:05:53 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_video.c,v 1.12 2002/11/25 14:04:58 eich Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -130,7 +130,7 @@ static XF86ImageRec Images[NUM_IMAGES] = 16, XvPacked, 1, - 15, 0x001F, 0x03E0, 0x7C00, + 15, 0x7C00, 0x03E0, 0x001F, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -147,7 +147,7 @@ static XF86ImageRec Images[NUM_IMAGES] = 16, XvPacked, 1, - 16, 0x001F, 0x07E0, 0xF800, + 16, 0xF800, 0x07E0, 0x001F, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cyrix/ChangeLog b/xc/programs/Xserver/hw/xfree86/drivers/cyrix/ChangeLog new file mode 100644 index 000000000..99f2789c5 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/cyrix/ChangeLog @@ -0,0 +1,11 @@ + +Release 0.2 +----------- +First release to the unsuspecting masses. + +Release 0.3 +----------- +Fix segv on X -configure (Bruce Montague) +Fix hang with weird video layouts (Bruce Montague) +Initial (not yet used) code for VSA free mode setup (Alan Cox) + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cyrix/README b/xc/programs/Xserver/hw/xfree86/drivers/cyrix/README new file mode 100644 index 000000000..f25e7590c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/cyrix/README @@ -0,0 +1,59 @@ + +MediaGX Fun +----------- + +This tries to document the "gotcha's" associated with the Cyrix +hardware and also the SoftVGA (SMM BIOS emulation of video) implementation. + +o Palette Handling + + In theory 8bit modes can use the VGA colour control. In practice + this doesn't work at least on some 5530 based systems with LCD + displays. + + Some 5510 based systems need special handling for external LCD + RAMDAC. We don't currently do this. + +o Mode Switches + + If you load unsuitable data into the Soft VGA mode switching + registers or forgot to set the ModeSwitch disable before you + load the registers up mode switches may fail. In a few cases + you get bogus illegal instructions reported + +o BIOS Versions + + The VSA1/VSA2 firmware that does all the magic on the Cyrix + processors is an SMM mode software block in the BIOS. This means + the Cyrix is one system where different BIOSes have different bugs + instead of just having to fight the hardware + + The BIOS is just plain unusable in a few systems. Code exists to + do some mode switches the hard way without VSA getting involved. + +o Compression Buffer + + To cut down on the memory usage the display scan checks dirty + bits on each scan line (per frame in some situations) and if the + line is dirty it scans it from the original buffer and writes back + a compressed line if it can do so. If it does this it clears the + dirty bit. We have to handle dirty bits ourselves and getting it + wrong produces interesting visuals. + +o Memory Layout + + When you use VSA to do mode set up it makes certain assumptions + about memory layout. Typically it lays out the frame buffer + with the compression buffer at the end. When there is enough + space between the lines (the chip only handles 1024/2048 bytes + stride) it will hide them in the gaps + + + +To Do +----- +- Add bare-metal setup option for the BIOS afflicted +- Add 5510 external ics5432 RAMDAC support +- Restore hardware cursor support +- DDC/EDID and friends +- RandR would be nice for the tablet pc systems diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_shadow.c b/xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_shadow.c new file mode 100644 index 000000000..479ad36dd --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_shadow.c @@ -0,0 +1,155 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cyrix/cyrix_shadow.c,v 1.1 2002/11/06 11:38:59 alanh Exp $ */ + +/* + Copyright (c) 1999, The XFree86 Project Inc. + Written by Mark Vojkovich <markv@valinux.com> +*/ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "cyrix.h" +#include "shadowfb.h" +#include "servermd.h" + + + +void +CYRIXRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pCyrix->ShadowPtr + (pbox->y1 * pCyrix->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pCyrix->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pCyrix->ShadowPitch; + } + + pbox++; + } +} + +void +CYRIXPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int newX, newY; + + if(pCyrix->Rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + } + + (*pCyrix->PointerMoved)(index, newX, newY); +} + +void +CYRIXRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pCyrix->Rotate * pCyrix->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if(pCyrix->Rotate == 1) { + dstPtr = pCyrix->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = pCyrix->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = pCyrix->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pCyrix->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch * 2] << 16) | + (src[srcPitch * 3] << 24); + src += srcPitch * 4; + } + srcPtr += pCyrix->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +void +CYRIXRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pCyrix->Rotate * pCyrix->ShadowPitch >> 1; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + + if(pCyrix->Rotate == 1) { + dstPtr = (CARD16*)pCyrix->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16*)pCyrix->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD16*)pCyrix->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16*)pCyrix->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch * 2; + } + srcPtr += pCyrix->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile index 1222d85fb..2290d16b8 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile,v 1.37 2002/02/25 00:44:07 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile,v 1.39 2003/02/17 17:06:42 dawes Exp $ XCOMM XCOMM This is an Imakefile for the GLINT driver. XCOMM @@ -42,7 +42,7 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \ -I$(XF86SRC)/xf4bpp -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(EXTINCSRC) $(DRIINCLUDES) \ -I$(XF86SRC)/shadowfb -I$(XF86SRC)/fbdevhw \ - -I$(XF86OSSRC)/vbe \ + -I$(XF86SRC)/vbe \ -I$(SERVERSRC)/render #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c index 92b357daa..e471c01b3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c @@ -27,7 +27,7 @@ * glintOutTIIndReg() and glintInTIIndReg() are used to access * the indirect TI RAMDAC registers only. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c,v 1.4 2001/01/31 16:14:52 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c,v 1.5 2002/10/30 12:52:15 alanh Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h index 7a497b434..58c1a8cb3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h,v 1.56 2002/06/06 22:33:40 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h,v 1.58 2003/02/17 16:08:28 dawes Exp $ */ /* * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> * @@ -71,6 +71,7 @@ typedef struct { typedef struct { pciVideoPtr PciInfo; pciVideoPtr MultiPciInfo[GLINT_MAX_MULTI_DEVICES]; + int MultiIndex; int numMultiDevices; int MultiChip; Bool MultiAperture; @@ -307,8 +308,6 @@ void Permedia2WriteAddress(ScrnInfoPtr pScrn, CARD32 index); void Permedia2ReadAddress(ScrnInfoPtr pScrn, CARD32 index); void Permedia2WriteData(ScrnInfoPtr pScrn, unsigned char data); unsigned char Permedia2ReadData(ScrnInfoPtr pScrn); -void TIramdacLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, - LOCO *colors, VisualPtr pVisual); void Permedia2LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual); void Permedia2LoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c index 87d18df9a..9994b71c6 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c,v 1.29 2002/10/08 22:14:07 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c,v 1.32 2003/02/10 13:20:10 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -148,7 +148,7 @@ GLINTInitVisualConfigs(ScreenPtr pScreen) pConfigs[i].doubleBuffer = FALSE; } pConfigs[i].stereo = FALSE; - pConfigs[i].bufferSize = 16; + pConfigs[i].bufferSize = 20; if ( depth ) { pConfigs[i].depthSize = 16; } else { @@ -243,7 +243,7 @@ GLINTInitVisualConfigs(ScreenPtr pScreen) pConfigs[i].doubleBuffer = FALSE; } pConfigs[i].stereo = FALSE; - pConfigs[i].bufferSize = 32; + pConfigs[i].bufferSize = 24; if ( depth ) { pConfigs[i].depthSize = 16; pConfigs[i].stencilSize = 8; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h index 7b00143ca..3952759f8 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h,v 1.6 2002/02/22 21:45:16 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h,v 1.7 2002/10/30 12:52:16 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h index 7803c4b19..15d5e487e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h,v 1.5 2000/06/17 10:00:13 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h,v 1.6 2002/10/30 12:52:16 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c index f9d36ffbc..de0c99209 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c @@ -28,7 +28,7 @@ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen, * Siemens Nixdorf Informationssysteme and Appian Graphics. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c,v 1.150 2002/10/08 22:14:07 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c,v 1.156 2003/02/17 16:08:28 dawes Exp $ */ #include "fb.h" #include "cfb8_32.h" @@ -275,12 +275,14 @@ static const char *shadowSymbols[] = { NULL }; +#ifdef XFree86LOADER static const char *vbeSymbols[] = { "VBEInit", "vbeDoEDID", "vbeFree", NULL }; +#endif static const char *ramdacSymbols[] = { "IBMramdac526CalculateMNPCForClock", @@ -1385,22 +1387,25 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) } else { pGlint->IOAddress = pGlint->PciInfo->memBase[0] & 0xFFFFC000; } -#if X_BYTE_ORDER == X_BIG_ENDIAN - pGlint->IOAddress += 0x10000; -#endif if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) { - /* Fix up for dual head mode, offset gamma registers at 0x10000 */ + /* We know which head is the primary on the J2000 board, need a more + * generix solution though. + */ if ((xf86IsEntityShared(pScrn->entityList[0])) && (xf86IsPrimInitDone(pScrn->entityList[0]))) { -#if 0 /* When we need gamma & acceleration, this should be used instead */ pGlint->IOAddress += 0x10000; -#endif + pGlint->MultiIndex = 2; } else { xf86SetPrimInitDone(pScrn->entityList[0]); + pGlint->MultiIndex = 1; } -#if 1 /* And then remove this */ - pGlint->IOAddress = pGlint->MultiPciInfo[0]->memBase[0] & 0xFFFFC000; +#if X_BYTE_ORDER == X_BIG_ENDIAN + GLINT_SLOW_WRITE_REG( + GLINT_READ_REG(GCSRAperture) | GCSRBitSwap + , GCSRAperture); + } else { + pGlint->IOAddress += 0x10000; #endif } @@ -1866,11 +1871,6 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) RamDacDestroyInfoRec(pGlint->RamDacRec); return FALSE; } -#if 1 /* REMOVE LATER - see other IS_J2000 fixup code */ - /* As we push the acceleration through the pm3 (for now) we can - * safely set the FIFOSize to 120 again */ - pGlint->FIFOSize = 120; -#endif break; } if (IS_GMX2000) { @@ -1932,6 +1932,15 @@ GLINTPreInit(ScrnInfoPtr pScrn, int flags) break; } + if ( pGlint->RamDac && + (pGlint->RamDac->RamDacType != (IBM640_RAMDAC)) && + (pScrn->depth == 30) ) + { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Depth 30 not supported for this chip\n"); + return FALSE; + } + if (pGlint->FIFOSize) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "FIFO Size is %d DWORDS\n", pGlint->FIFOSize); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h index c8f7e0e7a..122832d32 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h,v 1.34 2002/07/25 05:06:15 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h,v 1.36 2003/01/12 03:55:47 tsi Exp $ */ /* * glint register file @@ -191,47 +191,47 @@ #define PMRomControl 0x1040 #define PMBootAddress 0x1080 #define PMMemConfig 0x10C0 - #define RowCharge8 1 << 10 - #define TimeRCD8 1 << 7 - #define TimeRC8 0x6 << 3 - #define TimeRP8 1 - #define CAS3Latency8 0 << 16 - #define BootAdress8 0x10 - #define NumberBanks8 0x3 << 29 - #define RefreshCount8 0x41 << 21 - #define TimeRASMin8 1 << 13 - #define DeadCycle8 1 << 17 - #define BankDelay8 0 << 18 - #define Burst1Cycle8 1 << 31 - #define SDRAM8 0 << 4 - - #define RowCharge6 1 << 10 - #define TimeRCD6 1 << 7 - #define TimeRC6 0x6 << 3 - #define TimeRP6 0x2 - #define CAS3Latency6 1 << 16 - #define BootAdress6 0x60 - #define NumberBanks6 0x2 << 29 - #define RefreshCount6 0x41 << 21 - #define TimeRASMin6 1 << 13 - #define DeadCycle6 1 << 17 - #define BankDelay6 0 << 18 - #define Burst1Cycle6 1 << 31 - #define SDRAM6 0 << 4 - - #define RowCharge4 0 << 10 - #define TimeRCD4 0 << 7 - #define TimeRC4 0x4 << 3 - #define TimeRP4 1 - #define CAS3Latency4 0 << 16 - #define BootAdress4 0x10 - #define NumberBanks4 1 << 29 - #define RefreshCount4 0x30 << 21 - #define TimeRASMin4 1 << 13 - #define DeadCycle4 0 << 17 - #define BankDelay4 0 << 18 - #define Burst1Cycle4 1 << 31 - #define SDRAM4 0 << 4 +# define RowCharge8 1 << 10 +# define TimeRCD8 1 << 7 +# define TimeRC8 0x6 << 3 +# define TimeRP8 1 +# define CAS3Latency8 0 << 16 +# define BootAdress8 0x10 +# define NumberBanks8 0x3 << 29 +# define RefreshCount8 0x41 << 21 +# define TimeRASMin8 1 << 13 +# define DeadCycle8 1 << 17 +# define BankDelay8 0 << 18 +# define Burst1Cycle8 1 << 31 +# define SDRAM8 0 << 4 + +# define RowCharge6 1 << 10 +# define TimeRCD6 1 << 7 +# define TimeRC6 0x6 << 3 +# define TimeRP6 0x2 +# define CAS3Latency6 1 << 16 +# define BootAdress6 0x60 +# define NumberBanks6 0x2 << 29 +# define RefreshCount6 0x41 << 21 +# define TimeRASMin6 1 << 13 +# define DeadCycle6 1 << 17 +# define BankDelay6 0 << 18 +# define Burst1Cycle6 1 << 31 +# define SDRAM6 0 << 4 + +# define RowCharge4 0 << 10 +# define TimeRCD4 0 << 7 +# define TimeRC4 0x4 << 3 +# define TimeRP4 1 +# define CAS3Latency4 0 << 16 +# define BootAdress4 0x10 +# define NumberBanks4 1 << 29 +# define RefreshCount4 0x30 << 21 +# define TimeRASMin4 1 << 13 +# define DeadCycle4 0 << 17 +# define BankDelay4 0 << 18 +# define Burst1Cycle4 1 << 31 +# define SDRAM4 0 << 4 /* Permedia 2 Control */ #define MemControl 0x1040 @@ -509,6 +509,7 @@ #define GCSRAperture 0x0878 #define GCSRSecondaryGLINTMapEn 1 << 0 +#define GCSRBitSwap 1 << 1 #define GPageTableAddr 0x0c00 #define GPageTableLength 0x0c08 @@ -546,26 +547,26 @@ #define dY GLINT_TAG_ADDR(0x00,0x05) #define GLINTCount GLINT_TAG_ADDR(0x00,0x06) #define Render GLINT_TAG_ADDR(0x00,0x07) - #define AreaStippleEnable 0x00001 - #define LineStippleEnable 0x00002 - #define ResetLineStipple 0x00004 - #define FastFillEnable 0x00008 - #define PrimitiveLine 0 - #define PrimitiveTrapezoid 0x00040 - #define PrimitivePoint 0x00080 - #define PrimitiveRectangle 0x000C0 - #define AntialiasEnable 0x00100 - #define AntialiasingQuality 0x00200 - #define UsePointTable 0x00400 - #define SyncOnBitMask 0x00800 - #define SyncOnHostData 0x01000 - #define TextureEnable 0x02000 - #define FogEnable 0x04000 - #define CoverageEnable 0x08000 - #define SubPixelCorrectionEnable 0x10000 - #define SpanOperation 0x40000 - #define XPositive 1<<21 - #define YPositive 1<<22 +# define AreaStippleEnable 0x00001 +# define LineStippleEnable 0x00002 +# define ResetLineStipple 0x00004 +# define FastFillEnable 0x00008 +# define PrimitiveLine 0 +# define PrimitiveTrapezoid 0x00040 +# define PrimitivePoint 0x00080 +# define PrimitiveRectangle 0x000C0 +# define AntialiasEnable 0x00100 +# define AntialiasingQuality 0x00200 +# define UsePointTable 0x00400 +# define SyncOnBitMask 0x00800 +# define SyncOnHostData 0x01000 +# define TextureEnable 0x02000 +# define FogEnable 0x04000 +# define CoverageEnable 0x08000 +# define SubPixelCorrectionEnable 0x10000 +# define SpanOperation 0x40000 +# define XPositive 1<<21 +# define YPositive 1<<22 #define ContinueNewLine GLINT_TAG_ADDR(0x00,0x08) @@ -596,9 +597,9 @@ #define PackedDataLimits GLINT_TAG_ADDR(0x02,0x0a) /* PM only */ #define ScissorMode GLINT_TAG_ADDR(0x03,0x00) - #define SCI_USER 0x01 - #define SCI_SCREEN 0x02 - #define SCI_USERANDSCREEN 0x03 +# define SCI_USER 0x01 +# define SCI_SCREEN 0x02 +# define SCI_USERANDSCREEN 0x03 #define ScissorMinXY GLINT_TAG_ADDR(0x03,0x01) #define ScissorMaxXY GLINT_TAG_ADDR(0x03,0x02) @@ -612,17 +613,17 @@ /* XAddress_1bit */ /* UNIT_DISABLE */ - #define ASM_XAddress_2bit 1 << 1 - #define ASM_XAddress_3bit 2 << 1 - #define ASM_XAddress_4bit 3 << 1 - #define ASM_XAddress_5bit 4 << 1 - #define ASM_YAddress_2bit 1 << 4 - #define ASM_YAddress_3bit 2 << 4 - #define ASM_YAddress_4bit 3 << 4 - #define ASM_YAddress_5bit 4 << 4 - #define ASM_InvertPattern 1 << 17 - #define ASM_MirrorX 1 << 18 - #define ASM_MirrorY 1 << 19 +# define ASM_XAddress_2bit 1 << 1 +# define ASM_XAddress_3bit 2 << 1 +# define ASM_XAddress_4bit 3 << 1 +# define ASM_XAddress_5bit 4 << 1 +# define ASM_YAddress_2bit 1 << 4 +# define ASM_YAddress_3bit 2 << 4 +# define ASM_YAddress_4bit 3 << 4 +# define ASM_YAddress_5bit 4 << 4 +# define ASM_InvertPattern 1 << 17 +# define ASM_MirrorX 1 << 18 +# define ASM_MirrorY 1 << 19 #define LineStippleMode GLINT_TAG_ADDR(0x03,0x05) #define LoadLineStippleCounters GLINT_TAG_ADDR(0x03,0x06) @@ -656,12 +657,12 @@ #define TextureReadMode GLINT_TAG_ADDR(0x09,0x00) #define TextureFormat GLINT_TAG_ADDR(0x09,0x01) - #define Texture_4_Components 3 << 3 - #define Texture_Texel 0 +# define Texture_4_Components 3 << 3 +# define Texture_Texel 0 #define TextureCacheControl GLINT_TAG_ADDR(0x09,0x02) - #define TextureCacheControlEnable 2 - #define TextureCacheControlInvalidate 1 +# define TextureCacheControlEnable 2 +# define TextureCacheControlInvalidate 1 #define GLINTBorderColor GLINT_TAG_ADDR(0x09,0x05) @@ -708,10 +709,10 @@ #define TexelLUTMode GLINT_TAG_ADDR(0x0c,0x0f) #define TextureColorMode GLINT_TAG_ADDR(0x0d,0x00) - #define TextureTypeOpenGL 0 - #define TextureTypeApple 1 << 4 - #define TextureKsDDA 1 << 5 /* only Apple-Mode */ - #define TextureKdDDA 1 << 6 /* only Apple-Mode */ +# define TextureTypeOpenGL 0 +# define TextureTypeApple 1 << 4 +# define TextureKsDDA 1 << 5 /* only Apple-Mode */ +# define TextureKdDDA 1 << 6 /* only Apple-Mode */ #define TextureEnvColor GLINT_TAG_ADDR(0x0d,0x01) #define FogMode GLINT_TAG_ADDR(0x0d,0x02) @@ -719,7 +720,7 @@ /* FOG RGBA */ /* UNIT_DISABLE */ - #define FOG_CI 0x0002 +# define FOG_CI 0x0002 #define FogColor GLINT_TAG_ADDR(0x0d,0x03) #define FStart GLINT_TAG_ADDR(0x0d,0x04) @@ -746,9 +747,9 @@ #define dAdyDom GLINT_TAG_ADDR(0x0f,0x0b) #define ColorDDAMode GLINT_TAG_ADDR(0x0f,0x0c) /* 0: */ - #define CDDA_FlatShading 0 +# define CDDA_FlatShading 0 /* UNIT_DISABLE */ - #define CDDA_GouraudShading 0x0002 +# define CDDA_GouraudShading 0x0002 #define ConstantColor GLINT_TAG_ADDR(0x0f,0x0d) @@ -766,36 +767,36 @@ /* DstFBData */ /* UNIT_DISABLE */ - #define ABM_SrcONE 1 << 1 - #define ABM_SrcDST_COLOR 2 << 1 - #define ABM_SrcONE_MINUS_DST_COLOR 3 << 1 - #define ABM_SrcSRC_ALPHA 4 << 1 - #define ABM_SrcONE_MINUS_SRC_ALPHA 5 << 1 - #define ABM_SrcDST_ALPHA 6 << 1 - #define ABM_SrcONE_MINUS_DST_ALPHA 7 << 1 - #define ABM_SrcSRC_ALPHA_SATURATE 8 << 1 - #define ABM_DstONE 1 << 5 - #define ABM_DstSRC_COLOR 2 << 5 - #define ABM_DstONE_MINUS_SRC_COLOR 3 << 5 - #define ABM_DstSRC_ALPHA 4 << 5 - #define ABM_DstONE_MINUS_SRC_ALPHA 5 << 5 - #define ABM_DstDST_ALPHA 6 << 5 - #define ABM_DstONE_MINUS_DST_ALPHA 7 << 5 - #define ABM_ColorFormat5555 1 << 8 - #define ABM_ColorFormat4444 2 << 8 - #define ABM_ColorFormat4444_Front 3 << 8 - #define ABM_ColorFormat4444_Back 4 << 8 - #define ABM_ColorFormat332_Front 5 << 8 - #define ABM_ColorFormat332_Back 6 << 8 - #define ABM_ColorFormat121_Front 7 << 8 - #define ABM_ColorFormat121_Back 8 << 8 - #define ABM_ColorFormat555_Back 13 << 8 - #define ABM_ColorFormat_CI8 14 << 8 - #define ABM_ColorFormat_CI4 15 << 8 - #define ABM_NoAlphaBuffer 0x1000 - #define ABM_ColorOrderRGB 0x2000 - #define ABM_TypeQuickDraw3D 0x4000 - #define ABM_DstFBSourceData 0x8000 +# define ABM_SrcONE 1 << 1 +# define ABM_SrcDST_COLOR 2 << 1 +# define ABM_SrcONE_MINUS_DST_COLOR 3 << 1 +# define ABM_SrcSRC_ALPHA 4 << 1 +# define ABM_SrcONE_MINUS_SRC_ALPHA 5 << 1 +# define ABM_SrcDST_ALPHA 6 << 1 +# define ABM_SrcONE_MINUS_DST_ALPHA 7 << 1 +# define ABM_SrcSRC_ALPHA_SATURATE 8 << 1 +# define ABM_DstONE 1 << 5 +# define ABM_DstSRC_COLOR 2 << 5 +# define ABM_DstONE_MINUS_SRC_COLOR 3 << 5 +# define ABM_DstSRC_ALPHA 4 << 5 +# define ABM_DstONE_MINUS_SRC_ALPHA 5 << 5 +# define ABM_DstDST_ALPHA 6 << 5 +# define ABM_DstONE_MINUS_DST_ALPHA 7 << 5 +# define ABM_ColorFormat5555 1 << 8 +# define ABM_ColorFormat4444 2 << 8 +# define ABM_ColorFormat4444_Front 3 << 8 +# define ABM_ColorFormat4444_Back 4 << 8 +# define ABM_ColorFormat332_Front 5 << 8 +# define ABM_ColorFormat332_Back 6 << 8 +# define ABM_ColorFormat121_Front 7 << 8 +# define ABM_ColorFormat121_Back 8 << 8 +# define ABM_ColorFormat555_Back 13 << 8 +# define ABM_ColorFormat_CI8 14 << 8 +# define ABM_ColorFormat_CI4 15 << 8 +# define ABM_NoAlphaBuffer 0x1000 +# define ABM_ColorOrderRGB 0x2000 +# define ABM_TypeQuickDraw3D 0x4000 +# define ABM_DstFBSourceData 0x8000 #define DitherMode GLINT_TAG_ADDR(0x10,0x03) /* 0: */ @@ -806,31 +807,31 @@ /* DitherDisable */ /* UNIT_DISABLE */ - #define DTM_DitherEnable 1 << 1 - #define DTM_ColorFormat5555 1 << 2 - #define DTM_ColorFormat4444 2 << 2 - #define DTM_ColorFormat4444_Front 3 << 2 - #define DTM_ColorFormat4444_Back 4 << 2 - #define DTM_ColorFormat332_Front 5 << 2 - #define DTM_ColorFormat332_Back 6 << 2 - #define DTM_ColorFormat121_Front 7 << 2 - #define DTM_ColorFormat121_Back 8 << 2 - #define DTM_ColorFormat555_Back 13 << 2 - #define DTM_ColorFormat_CI8 14 << 2 - #define DTM_ColorFormat_CI4 15 << 2 - #define DTM_ColorOrderRGB 1 << 10 - #define DTM_NoAlphaDither 1 << 14 - #define DTM_RoundMode 1 << 15 +# define DTM_DitherEnable 1 << 1 +# define DTM_ColorFormat5555 1 << 2 +# define DTM_ColorFormat4444 2 << 2 +# define DTM_ColorFormat4444_Front 3 << 2 +# define DTM_ColorFormat4444_Back 4 << 2 +# define DTM_ColorFormat332_Front 5 << 2 +# define DTM_ColorFormat332_Back 6 << 2 +# define DTM_ColorFormat121_Front 7 << 2 +# define DTM_ColorFormat121_Back 8 << 2 +# define DTM_ColorFormat555_Back 13 << 2 +# define DTM_ColorFormat_CI8 14 << 2 +# define DTM_ColorFormat_CI4 15 << 2 +# define DTM_ColorOrderRGB 1 << 10 +# define DTM_NoAlphaDither 1 << 14 +# define DTM_RoundMode 1 << 15 #define FBSoftwareWriteMask GLINT_TAG_ADDR(0x10,0x04) #define LogicalOpMode GLINT_TAG_ADDR(0x10,0x05) - #define Use_ConstantFBWriteData 0x40 +# define Use_ConstantFBWriteData 0x40 #define FBWriteData GLINT_TAG_ADDR(0x10,0x06) #define RouterMode GLINT_TAG_ADDR(0x10,0x08) - #define ROUTER_Depth_Texture 1 - #define ROUTER_Texture_Depth 0 +# define ROUTER_Depth_Texture 1 +# define ROUTER_Texture_Depth 0 #define LBReadMode GLINT_TAG_ADDR(0x11,0x00) @@ -842,60 +843,60 @@ /* NoPatch */ /* ScanlineInterval1 */ - #define LBRM_SrcEnable 1 << 9 - #define LBRM_DstEnable 1 << 10 - #define LBRM_DataLBStencil 1 << 16 - #define LBRM_DataLBDepth 2 << 16 - #define LBRM_WinBottomLeft 1 << 18 - #define LBRM_DoPatch 1 << 19 +# define LBRM_SrcEnable 1 << 9 +# define LBRM_DstEnable 1 << 10 +# define LBRM_DataLBStencil 1 << 16 +# define LBRM_DataLBDepth 2 << 16 +# define LBRM_WinBottomLeft 1 << 18 +# define LBRM_DoPatch 1 << 19 - #define LBRM_ScanlineInt2 1 << 20 - #define LBRM_ScanlineInt4 2 << 20 - #define LBRM_ScanlineInt8 3 << 20 +# define LBRM_ScanlineInt2 1 << 20 +# define LBRM_ScanlineInt4 2 << 20 +# define LBRM_ScanlineInt8 3 << 20 #define LBReadFormat GLINT_TAG_ADDR(0x11,0x01) - #define LBRF_DepthWidth15 0x03 /* only permedia */ - #define LBRF_DepthWidth16 0x00 - #define LBRF_DepthWidth24 0x01 - #define LBRF_DepthWidth32 0x02 - - #define LBRF_StencilWidth0 (0 << 2) - #define LBRF_StencilWidth4 (1 << 2) - #define LBRF_StencilWidth8 (2 << 2) - - #define LBRF_StencilPos16 (0 << 4) - #define LBRF_StencilPos20 (1 << 4) - #define LBRF_StencilPos24 (2 << 4) - #define LBRF_StencilPos28 (3 << 4) - #define LBRF_StencilPos32 (4 << 4) - - #define LBRF_FrameCount0 (0 << 7) - #define LBRF_FrameCount4 (1 << 7) - #define LBRF_FrameCount8 (2 << 7) - - #define LBRF_FrameCountPos16 (0 << 9) - #define LBRF_FrameCountPos20 (1 << 9) - #define LBRF_FrameCountPos24 (2 << 9) - #define LBRF_FrameCountPos28 (3 << 9) - #define LBRF_FrameCountPos32 (4 << 9) - #define LBRF_FrameCountPos36 (5 << 9) - #define LBRF_FrameCountPos40 (6 << 9) - - #define LBRF_GIDWidth0 (0 << 12) - #define LBRF_GIDWidth4 (1 << 12) - - #define LBRF_GIDPos16 (0 << 13) - #define LBRF_GIDPos20 (1 << 13) - #define LBRF_GIDPos24 (2 << 13) - #define LBRF_GIDPos28 (3 << 13) - #define LBRF_GIDPos32 (4 << 13) - #define LBRF_GIDPos36 (5 << 13) - #define LBRF_GIDPos40 (6 << 13) - #define LBRF_GIDPos44 (7 << 13) - #define LBRF_GIDPos48 (8 << 13) - - #define LBRF_Compact32 (1 << 17) +# define LBRF_DepthWidth15 0x03 /* only permedia */ +# define LBRF_DepthWidth16 0x00 +# define LBRF_DepthWidth24 0x01 +# define LBRF_DepthWidth32 0x02 + +# define LBRF_StencilWidth0 (0 << 2) +# define LBRF_StencilWidth4 (1 << 2) +# define LBRF_StencilWidth8 (2 << 2) + +# define LBRF_StencilPos16 (0 << 4) +# define LBRF_StencilPos20 (1 << 4) +# define LBRF_StencilPos24 (2 << 4) +# define LBRF_StencilPos28 (3 << 4) +# define LBRF_StencilPos32 (4 << 4) + +# define LBRF_FrameCount0 (0 << 7) +# define LBRF_FrameCount4 (1 << 7) +# define LBRF_FrameCount8 (2 << 7) + +# define LBRF_FrameCountPos16 (0 << 9) +# define LBRF_FrameCountPos20 (1 << 9) +# define LBRF_FrameCountPos24 (2 << 9) +# define LBRF_FrameCountPos28 (3 << 9) +# define LBRF_FrameCountPos32 (4 << 9) +# define LBRF_FrameCountPos36 (5 << 9) +# define LBRF_FrameCountPos40 (6 << 9) + +# define LBRF_GIDWidth0 (0 << 12) +# define LBRF_GIDWidth4 (1 << 12) + +# define LBRF_GIDPos16 (0 << 13) +# define LBRF_GIDPos20 (1 << 13) +# define LBRF_GIDPos24 (2 << 13) +# define LBRF_GIDPos28 (3 << 13) +# define LBRF_GIDPos32 (4 << 13) +# define LBRF_GIDPos36 (5 << 13) +# define LBRF_GIDPos40 (6 << 13) +# define LBRF_GIDPos44 (7 << 13) +# define LBRF_GIDPos48 (8 << 13) + +# define LBRF_Compact32 (1 << 17) @@ -904,9 +905,9 @@ #define LBDepth GLINT_TAG_ADDR(0x11,0x06) #define LBWindowBase GLINT_TAG_ADDR(0x11,0x07) #define LBWriteMode GLINT_TAG_ADDR(0x11,0x08) - #define LBWM_WriteEnable 0x1 - #define LBWM_UpLoad_LBDepth 0x2 - #define LBWM_UpLoad_LBStencil 0x4 +# define LBWM_WriteEnable 0x1 +# define LBWM_UpLoad_LBDepth 0x2 +# define LBWM_UpLoad_LBStencil 0x4 #define LBWriteFormat GLINT_TAG_ADDR(0x11,0x09) @@ -916,16 +917,16 @@ #define LBWindowOffset GLINT_TAG_ADDR(0x11,0x0f) #define GLINTWindow GLINT_TAG_ADDR(0x13,0x00) - #define GWIN_UnitEnable (1 << 0) - #define GWIN_ForceLBUpdate (1 << 3) - #define GWIN_LBUpdateSourceREG (1 << 4) - #define GWIN_LBUpdateSourceLB (0 << 4) - #define GWIN_StencilFCP (1 << 17) - #define GWIN_DepthFCP (1 << 18) - #define GWIN_OverrideWriteFilter (1 << 19) +# define GWIN_UnitEnable (1 << 0) +# define GWIN_ForceLBUpdate (1 << 3) +# define GWIN_LBUpdateSourceREG (1 << 4) +# define GWIN_LBUpdateSourceLB (0 << 4) +# define GWIN_StencilFCP (1 << 17) +# define GWIN_DepthFCP (1 << 18) +# define GWIN_OverrideWriteFilter (1 << 19) /* ??? is this needed, set by permedia (2) modules */ - #define GWIN_DisableLBUpdate 0x40000 +# define GWIN_DisableLBUpdate 0x40000 #define StencilMode GLINT_TAG_ADDR(0x13,0x01) #define StencilData GLINT_TAG_ADDR(0x13,0x02) @@ -937,17 +938,17 @@ /* CompFuncNEVER */ /* UNIT_DISABLE */ - #define DPM_WriteEnable 1 << 1 - #define DPM_SrcCompLBData 1 << 2 - #define DPM_SrcCompDregister 2 << 2 - #define DPM_SrcCompLBSourceData 3 << 2 - #define DPM_CompFuncLESS 1 << 4 - #define DPM_CompFuncEQUAL 2 << 4 - #define DPM_CompFuncLESS_OR_EQ 3 << 4 - #define DPM_CompFuncGREATER 4 << 4 - #define DPM_CompFuncNOT_EQ 5 << 4 - #define DPM_CompFuncGREATER_OR_EQ 6 << 4 - #define DPM_CompFuncALWAYS 7 << 4 +# define DPM_WriteEnable 1 << 1 +# define DPM_SrcCompLBData 1 << 2 +# define DPM_SrcCompDregister 2 << 2 +# define DPM_SrcCompLBSourceData 3 << 2 +# define DPM_CompFuncLESS 1 << 4 +# define DPM_CompFuncEQUAL 2 << 4 +# define DPM_CompFuncLESS_OR_EQ 3 << 4 +# define DPM_CompFuncGREATER 4 << 4 +# define DPM_CompFuncNOT_EQ 5 << 4 +# define DPM_CompFuncGREATER_OR_EQ 6 << 4 +# define DPM_CompFuncALWAYS 7 << 4 #define GLINTDepth GLINT_TAG_ADDR(0x13,0x05) #define ZStartU GLINT_TAG_ADDR(0x13,0x06) @@ -966,14 +967,14 @@ /* WinTopLeft */ /* ScanlineInterval1 */ - #define FBRM_SrcEnable 1 << 9 - #define FBRM_DstEnable 1 << 10 - #define FBRM_DataFBColor 1 << 15 - #define FBRM_WinBottomLeft 1 << 16 - #define FBRM_Packed 1 << 19 - #define FBRM_ScanlineInt2 1 << 23 - #define FBRM_ScanlineInt4 2 << 23 - #define FBRM_ScanlineInt8 3 << 23 +# define FBRM_SrcEnable 1 << 9 +# define FBRM_DstEnable 1 << 10 +# define FBRM_DataFBColor 1 << 15 +# define FBRM_WinBottomLeft 1 << 16 +# define FBRM_Packed 1 << 19 +# define FBRM_ScanlineInt2 1 << 23 +# define FBRM_ScanlineInt4 2 << 23 +# define FBRM_ScanlineInt8 3 << 23 #define FBSourceOffset GLINT_TAG_ADDR(0x15,0x01) @@ -987,10 +988,10 @@ /* 0: */ /* FBWM_NoColorUpload */ /* FBWM_WriteDisable */ - #define FBWM_WriteEnable 1 - #define FBWM_UploadColor 1 << 3 +# define FBWM_WriteEnable 1 +# define FBWM_UploadColor 1 << 3 /* Permedia3 extensions */ - #define FBWM_Enable0 1 << 12 +# define FBWM_Enable0 1 << 12 #define FBHardwareWriteMask GLINT_TAG_ADDR(0x15,0x08) #define FBBlockColor GLINT_TAG_ADDR(0x15,0x09) @@ -1019,16 +1020,16 @@ /* CullStatisticTag */ /* CullStatisticData */ - #define FM_PassDepthTags 0x0010 - #define FM_PassDepthData 0x0020 - #define FM_PassStencilTags 0x0040 - #define FM_PassStencilData 0x0080 - #define FM_PassColorTag 0x0100 - #define FM_PassColorData 0x0200 - #define FM_PassSyncTag 0x0400 - #define FM_PassSyncData 0x0800 - #define FM_PassStatisticTag 0x1000 - #define FM_PassStatisticData 0x2000 +# define FM_PassDepthTags 0x0010 +# define FM_PassDepthData 0x0020 +# define FM_PassStencilTags 0x0040 +# define FM_PassStencilData 0x0080 +# define FM_PassColorTag 0x0100 +# define FM_PassColorData 0x0200 +# define FM_PassSyncTag 0x0400 +# define FM_PassSyncData 0x0800 +# define FM_PassStatisticTag 0x1000 +# define FM_PassStatisticData 0x2000 #define Sync_tag 0x0188 @@ -1140,43 +1141,43 @@ /* GLINT_300SX */ /* DeltaMode Register Bit Field Assignments */ - #define DM_GLINT_300SX 0x0000 - #define DM_GLINT_500TX 0x0001 - #define DM_PERMEDIA 0x0002 - #define DM_Depth_16BPP (1 << 2) - #define DM_Depth_24BPP (2 << 2) - #define DM_Depth_32BPP (3 << 2) - #define DM_FogEnable 0x0010 - #define DM_TextureEnable 0x0020 - #define DM_SmoothShadingEnable 0x0040 - #define DM_DepthEnable 0x0080 - #define DM_SpecularTextureEnable 0x0100 - #define DM_DiffuseTextureEnable 0x0200 - #define DM_SubPixelCorrectionEnable 0x0400 - #define DM_DiamondExit 0x0800 - #define DM_NoDraw 0x1000 - #define DM_ClampEnable 0x2000 - #define DM_ClampedTexParMode 0x4000 - #define DM_NormalizedTexParMode 0xC000 - - - #define DDCMD_AreaStrippleEnable 0x0001 - #define DDCMD_LineStrippleEnable 0x0002 - #define DDCMD_ResetLineStripple 1 << 2 - #define DDCMD_FastFillEnable 1 << 3 +# define DM_GLINT_300SX 0x0000 +# define DM_GLINT_500TX 0x0001 +# define DM_PERMEDIA 0x0002 +# define DM_Depth_16BPP (1 << 2) +# define DM_Depth_24BPP (2 << 2) +# define DM_Depth_32BPP (3 << 2) +# define DM_FogEnable 0x0010 +# define DM_TextureEnable 0x0020 +# define DM_SmoothShadingEnable 0x0040 +# define DM_DepthEnable 0x0080 +# define DM_SpecularTextureEnable 0x0100 +# define DM_DiffuseTextureEnable 0x0200 +# define DM_SubPixelCorrectionEnable 0x0400 +# define DM_DiamondExit 0x0800 +# define DM_NoDraw 0x1000 +# define DM_ClampEnable 0x2000 +# define DM_ClampedTexParMode 0x4000 +# define DM_NormalizedTexParMode 0xC000 + + +# define DDCMD_AreaStrippleEnable 0x0001 +# define DDCMD_LineStrippleEnable 0x0002 +# define DDCMD_ResetLineStripple 1 << 2 +# define DDCMD_FastFillEnable 1 << 3 /* 2 Bits reserved */ - #define DDCMD_PrimitiveType_Point 2 << 6 - #define DDCMD_PrimitiveType_Line 0 << 6 - #define DDCMD_PrimitiveType_Trapezoid 1 << 6 - #define DDCMD_AntialiasEnable 1 << 8 - #define DDCMD_AntialiasingQuality 1 << 9 - #define DDCMD_UsePointTable 1 << 10 - #define DDCMD_SyncOnBitMask 1 << 11 - #define DDCMD_SyncOnHostDate 1 << 12 - #define DDCMD_TextureEnable 1 << 13 - #define DDCMD_FogEnable 1 << 14 - #define DDCMD_CoverageEnable 1 << 15 - #define DDCMD_SubPixelCorrectionEnable 1 << 16 +# define DDCMD_PrimitiveType_Point 2 << 6 +# define DDCMD_PrimitiveType_Line 0 << 6 +# define DDCMD_PrimitiveType_Trapezoid 1 << 6 +# define DDCMD_AntialiasEnable 1 << 8 +# define DDCMD_AntialiasingQuality 1 << 9 +# define DDCMD_UsePointTable 1 << 10 +# define DDCMD_SyncOnBitMask 1 << 11 +# define DDCMD_SyncOnHostDate 1 << 12 +# define DDCMD_TextureEnable 1 << 13 +# define DDCMD_FogEnable 1 << 14 +# define DDCMD_CoverageEnable 1 << 15 +# define DDCMD_SubPixelCorrectionEnable 1 << 16 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c index 3a7d0191a..9599590b8 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c @@ -26,7 +26,7 @@ * * Permedia 3 accelerated options. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c,v 1.30 2002/05/21 14:38:04 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c,v 1.31 2003/01/06 00:04:54 alanh Exp $ */ #include "Xarch.h" #include "xf86.h" @@ -139,7 +139,11 @@ Permedia3InitializeEngine(ScrnInfoPtr pScrn) /* Initialize the Accelerator Engine to defaults */ TRACE_ENTER("Permedia3InitializeEngine"); + if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) { + GLINT_SLOW_WRITE_REG(pGlint->MultiIndex, BroadcastMask); + } if (pGlint->MultiAperture) { + ErrorF("pm3_accel: SVEN : multiAperture set\n"); /* Only write the following register to the first PM3 */ GLINT_SLOW_WRITE_REG(1, BroadcastMask); GLINT_SLOW_WRITE_REG(0x00000001, ScanLineOwnership); @@ -1040,6 +1044,10 @@ Permedia3SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) static void Permedia3RestoreAccelState(ScrnInfoPtr pScrn) { + GLINTPtr pGlint = GLINTPTR(pScrn); + if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) { + GLINT_SLOW_WRITE_REG(pGlint->MultiIndex, BroadcastMask); + } Permedia3Sync(pScrn); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h index 8cfd2607d..be9fc510f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h,v 1.9 2001/11/20 00:09:15 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h,v 1.10 2003/01/12 03:55:47 tsi Exp $ */ /* * glint register file @@ -53,33 +53,33 @@ * GLINT Permedia3 Region 0 Bypass Controls * ***********************************************/ #define PM3ByAperture1Mode 0x0300 - #define PM3ByApertureMode_BYTESWAP_ABCD (0<<0) - #define PM3ByApertureMode_BYTESWAP_BADC (1<<0) - #define PM3ByApertureMode_BYTESWAP_CDAB (2<<0) - #define PM3ByApertureMode_BYTESWAP_DCBA (3<<0) - #define PM3ByApertureMode_PATCH_DISABLE (0<<2) - #define PM3ByApertureMode_PATCH_ENABLE (1<<2) - #define PM3ByApertureMode_FORMAT_RAW (0<<3) - #define PM3ByApertureMode_FORMAT_YUYV (1<<3) - #define PM3ByApertureMode_FORMAT_UYVY (2<<3) - #define PM3ByApertureMode_PIXELSIZE_8BIT (0<<5) - #define PM3ByApertureMode_PIXELSIZE_16BIT (1<<5) - #define PM3ByApertureMode_PIXELSIZE_32BIT (2<<5) - #define PM3ByApertureMode_EFFECTIVE_STRIDE_1024 (0<<7) - #define PM3ByApertureMode_EFFECTIVE_STRIDE_2048 (1<<7) - #define PM3ByApertureMode_EFFECTIVE_STRIDE_4096 (2<<7) - #define PM3ByApertureMode_EFFECTIVE_STRIDE_8192 (3<<7) - #define PM3ByApertureMode_PATCH_OFFSET_X(off) (((off)&7f)<<9) - #define PM3ByApertureMode_PATCH_OFFSET_Y(off) (((off)&7f)<<16) - #define PM3ByApertureMode_FRAMEBUFFER (0<<21) - #define PM3ByApertureMode_LOCALBUFFER (1<<21) - #define PM3ByApertureMode_DOUBLE_WRITE_OFF (0<<22) - #define PM3ByApertureMode_DOUBLE_WRITE_1MB (1<<22) - #define PM3ByApertureMode_DOUBLE_WRITE_2MB (2<<22) - #define PM3ByApertureMode_DOUBLE_WRITE_4MB (3<<22) - #define PM3ByApertureMode_DOUBLE_WRITE_8MB (4<<22) - #define PM3ByApertureMode_DOUBLE_WRITE_16MB (5<<22) - #define PM3ByApertureMode_DOUBLE_WRITE_32MB (6<<22) +# define PM3ByApertureMode_BYTESWAP_ABCD (0<<0) +# define PM3ByApertureMode_BYTESWAP_BADC (1<<0) +# define PM3ByApertureMode_BYTESWAP_CDAB (2<<0) +# define PM3ByApertureMode_BYTESWAP_DCBA (3<<0) +# define PM3ByApertureMode_PATCH_DISABLE (0<<2) +# define PM3ByApertureMode_PATCH_ENABLE (1<<2) +# define PM3ByApertureMode_FORMAT_RAW (0<<3) +# define PM3ByApertureMode_FORMAT_YUYV (1<<3) +# define PM3ByApertureMode_FORMAT_UYVY (2<<3) +# define PM3ByApertureMode_PIXELSIZE_8BIT (0<<5) +# define PM3ByApertureMode_PIXELSIZE_16BIT (1<<5) +# define PM3ByApertureMode_PIXELSIZE_32BIT (2<<5) +# define PM3ByApertureMode_EFFECTIVE_STRIDE_1024 (0<<7) +# define PM3ByApertureMode_EFFECTIVE_STRIDE_2048 (1<<7) +# define PM3ByApertureMode_EFFECTIVE_STRIDE_4096 (2<<7) +# define PM3ByApertureMode_EFFECTIVE_STRIDE_8192 (3<<7) +# define PM3ByApertureMode_PATCH_OFFSET_X(off) (((off)&7f)<<9) +# define PM3ByApertureMode_PATCH_OFFSET_Y(off) (((off)&7f)<<16) +# define PM3ByApertureMode_FRAMEBUFFER (0<<21) +# define PM3ByApertureMode_LOCALBUFFER (1<<21) +# define PM3ByApertureMode_DOUBLE_WRITE_OFF (0<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_1MB (1<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_2MB (2<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_4MB (3<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_8MB (4<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_16MB (5<<22) +# define PM3ByApertureMode_DOUBLE_WRITE_32MB (6<<22) #define PM3ByAperture2Mode 0x0328 @@ -90,7 +90,7 @@ #define PM3MemBypassWriteMask 0x1008 #define PM3MemScratch 0x1010 #define PM3LocalMemCaps 0x1018 - #define PM3LocalMemCaps_NoWriteMask (1<<28) +# define PM3LocalMemCaps_NoWriteMask (1<<28) #define PM3LocalMemTimings 0x1020 #define PM3LocalMemControl 0x1028 #define PM3LocalMemRefresh 0x1030 @@ -113,43 +113,43 @@ #define PM3VsStart 0x3048 #define PM3VsEnd 0x3050 #define PM3VideoControl 0x3058 - #define PM3VideoControl_DISABLE (0<<0) - #define PM3VideoControl_ENABLE (1<<0) - #define PM3VideoControl_BLANK_ACTIVE_HIGH (0<<1) - #define PM3VideoControl_BLANK_ACTIVE_LOW (1<<1) - #define PM3VideoControl_LINE_DOUBLE_OFF (0<<2) - #define PM3VideoControl_LINE_DOUBLE_ON (1<<2) - #define PM3VideoControl_HSYNC_FORCE_HIGH (0<<3) - #define PM3VideoControl_HSYNC_ACTIVE_HIGH (1<<3) - #define PM3VideoControl_HSYNC_FORCE_LOW (2<<3) - #define PM3VideoControl_HSYNC_ACTIVE_LOW (3<<3) - #define PM3VideoControl_VSYNC_FORCE_HIGH (0<<5) - #define PM3VideoControl_VSYNC_ACTIVE_HIGH (1<<5) - #define PM3VideoControl_VSYNC_FORCE_LOW (2<<5) - #define PM3VideoControl_VSYNC_ACTIVE_LOW (3<<5) - #define PM3VideoControl_BYTE_DOUBLE_OFF (0<<7) - #define PM3VideoControl_BYTE_DOUBLE_ON (1<<7) - #define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK (0<<9) - #define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING (1<<9) - #define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE (2<<9) - #define PM3VideoControl_STEREO_DISABLE (0<<11) - #define PM3VideoControl_STEREO_ENABLE (1<<11) - #define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH (0<<12) - #define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW (1<<12) - #define PM3VideoControl_VIDEO_EXT_LOW (0<<14) - #define PM3VideoControl_VIDEO_EXT_HIGH (1<<14) - #define PM3VideoControl_SYNC_MODE_INDEPENDENT (0<<16) - #define PM3VideoControl_SYNC_MODE_SYNCTO_VSA (1<<16) - #define PM3VideoControl_SYNC_MODE_SYNCTO_VSB (2<<16) - #define PM3VideoControl_PATCH_DISABLE (0<<18) - #define PM3VideoControl_PATCH_ENABLE (1<<18) - #define PM3VideoControl_PIXELSIZE_8BIT (0<<19) - #define PM3VideoControl_PIXELSIZE_16BIT (1<<19) - #define PM3VideoControl_PIXELSIZE_32BIT (2<<19) - #define PM3VideoControl_DISPLAY_DISABLE (0<<21) - #define PM3VideoControl_DISPLAY_ENABLE (1<<21) - #define PM3VideoControl_PATCH_OFFSET_X(off) (((off)&0x3f)<<22) - #define PM3VideoControl_PATCH_OFFSET_Y(off) (((off)&0x3f)<<28) +# define PM3VideoControl_DISABLE (0<<0) +# define PM3VideoControl_ENABLE (1<<0) +# define PM3VideoControl_BLANK_ACTIVE_HIGH (0<<1) +# define PM3VideoControl_BLANK_ACTIVE_LOW (1<<1) +# define PM3VideoControl_LINE_DOUBLE_OFF (0<<2) +# define PM3VideoControl_LINE_DOUBLE_ON (1<<2) +# define PM3VideoControl_HSYNC_FORCE_HIGH (0<<3) +# define PM3VideoControl_HSYNC_ACTIVE_HIGH (1<<3) +# define PM3VideoControl_HSYNC_FORCE_LOW (2<<3) +# define PM3VideoControl_HSYNC_ACTIVE_LOW (3<<3) +# define PM3VideoControl_VSYNC_FORCE_HIGH (0<<5) +# define PM3VideoControl_VSYNC_ACTIVE_HIGH (1<<5) +# define PM3VideoControl_VSYNC_FORCE_LOW (2<<5) +# define PM3VideoControl_VSYNC_ACTIVE_LOW (3<<5) +# define PM3VideoControl_BYTE_DOUBLE_OFF (0<<7) +# define PM3VideoControl_BYTE_DOUBLE_ON (1<<7) +# define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK (0<<9) +# define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING (1<<9) +# define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE (2<<9) +# define PM3VideoControl_STEREO_DISABLE (0<<11) +# define PM3VideoControl_STEREO_ENABLE (1<<11) +# define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH (0<<12) +# define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW (1<<12) +# define PM3VideoControl_VIDEO_EXT_LOW (0<<14) +# define PM3VideoControl_VIDEO_EXT_HIGH (1<<14) +# define PM3VideoControl_SYNC_MODE_INDEPENDENT (0<<16) +# define PM3VideoControl_SYNC_MODE_SYNCTO_VSA (1<<16) +# define PM3VideoControl_SYNC_MODE_SYNCTO_VSB (2<<16) +# define PM3VideoControl_PATCH_DISABLE (0<<18) +# define PM3VideoControl_PATCH_ENABLE (1<<18) +# define PM3VideoControl_PIXELSIZE_8BIT (0<<19) +# define PM3VideoControl_PIXELSIZE_16BIT (1<<19) +# define PM3VideoControl_PIXELSIZE_32BIT (2<<19) +# define PM3VideoControl_DISPLAY_DISABLE (0<<21) +# define PM3VideoControl_DISPLAY_ENABLE (1<<21) +# define PM3VideoControl_PATCH_OFFSET_X(off) (((off)&0x3f)<<22) +# define PM3VideoControl_PATCH_OFFSET_Y(off) (((off)&0x3f)<<28) #define PM3InterruptLine 0x3060 #define PM3DisplayData 0x3068 #define PM3VerticalLineCount 0x3070 @@ -158,54 +158,54 @@ #define PM3MiscControl 0x3088 #define PM3VideoOverlayUpdate 0x3100 - #define PM3VideoOverlayUpdate_DISABLE (0<<0) - #define PM3VideoOverlayUpdate_ENABLE (1<<0) +# define PM3VideoOverlayUpdate_DISABLE (0<<0) +# define PM3VideoOverlayUpdate_ENABLE (1<<0) #define PM3VideoOverlayMode 0x3108 - #define PM3VideoOverlayMode_DISABLE (0<<0) - #define PM3VideoOverlayMode_ENABLE (1<<0) - #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL (0<<1) - #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA (1<<1) - #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB (2<<1) - #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL (0<<4) - #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT (1<<4) - #define PM3VideoOverlayMode_PIXELSIZE_8BIT (0<<5) - #define PM3VideoOverlayMode_PIXELSIZE_16BIT (1<<5) - #define PM3VideoOverlayMode_PIXELSIZE_32BIT (2<<5) - #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_RGB565 ((3<<7)|(1<<12)|(1<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_RGB332 ((4<<7)|(1<<12)|(0<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_BGR565 ((3<<7)|(1<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_BGR332 ((4<<7)|(0<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_CI8 ((5<<7)|(1<<12)|(0<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_VUY444 ((2<<10)|(1<<12)|(2<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_YUV444 ((2<<10)|(2<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_VUY422 ((1<<10)|(1<<12)|(1<<5)) - #define PM3VideoOverlayMode_COLORFORMAT_YUV422 ((1<<10)|(1<<5)) - #define PM3VideoOverlayMode_COLORORDER_BGR (0<<12) - #define PM3VideoOverlayMode_COLORORDER_RGB (1<<12) - #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF (0<<13) - #define PM3VideoOverlayMode_LINEARCOLOREXT_ON (1<<13) - #define PM3VideoOverlayMode_FILTER_MASK (3<<14) - #define PM3VideoOverlayMode_FILTER_OFF (0<<14) - #define PM3VideoOverlayMode_FILTER_FULL (1<<14) - #define PM3VideoOverlayMode_FILTER_PARTIAL (2<<14) - #define PM3VideoOverlayMode_DEINTERLACE_OFF (0<<16) - #define PM3VideoOverlayMode_DEINTERLACE_BOB (1<<16) - #define PM3VideoOverlayMode_PATCHMODE_OFF (0<<18) - #define PM3VideoOverlayMode_PATCHMODE_ON (1<<18) - #define PM3VideoOverlayMode_FLIP_VIDEO (0<<20) - #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA (1<<20) - #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB (2<<20) - #define PM3VideoOverlayMode_MIRROR_MASK (3<<23) - #define PM3VideoOverlayMode_MIRRORX_OFF (0<<23) - #define PM3VideoOverlayMode_MIRRORX_ON (1<<23) - #define PM3VideoOverlayMode_MIRRORY_OFF (0<<24) - #define PM3VideoOverlayMode_MIRRORY_ON (1<<24) +# define PM3VideoOverlayMode_DISABLE (0<<0) +# define PM3VideoOverlayMode_ENABLE (1<<0) +# define PM3VideoOverlayMode_BUFFERSYNC_MANUAL (0<<1) +# define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA (1<<1) +# define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB (2<<1) +# define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL (0<<4) +# define PM3VideoOverlayMode_FIELDPOLARITY_INVERT (1<<4) +# define PM3VideoOverlayMode_PIXELSIZE_8BIT (0<<5) +# define PM3VideoOverlayMode_PIXELSIZE_16BIT (1<<5) +# define PM3VideoOverlayMode_PIXELSIZE_32BIT (2<<5) +# define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_RGB565 ((3<<7)|(1<<12)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_RGB332 ((4<<7)|(1<<12)|(0<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR565 ((3<<7)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_BGR332 ((4<<7)|(0<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_CI8 ((5<<7)|(1<<12)|(0<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_VUY444 ((2<<10)|(1<<12)|(2<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_YUV444 ((2<<10)|(2<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_VUY422 ((1<<10)|(1<<12)|(1<<5)) +# define PM3VideoOverlayMode_COLORFORMAT_YUV422 ((1<<10)|(1<<5)) +# define PM3VideoOverlayMode_COLORORDER_BGR (0<<12) +# define PM3VideoOverlayMode_COLORORDER_RGB (1<<12) +# define PM3VideoOverlayMode_LINEARCOLOREXT_OFF (0<<13) +# define PM3VideoOverlayMode_LINEARCOLOREXT_ON (1<<13) +# define PM3VideoOverlayMode_FILTER_MASK (3<<14) +# define PM3VideoOverlayMode_FILTER_OFF (0<<14) +# define PM3VideoOverlayMode_FILTER_FULL (1<<14) +# define PM3VideoOverlayMode_FILTER_PARTIAL (2<<14) +# define PM3VideoOverlayMode_DEINTERLACE_OFF (0<<16) +# define PM3VideoOverlayMode_DEINTERLACE_BOB (1<<16) +# define PM3VideoOverlayMode_PATCHMODE_OFF (0<<18) +# define PM3VideoOverlayMode_PATCHMODE_ON (1<<18) +# define PM3VideoOverlayMode_FLIP_VIDEO (0<<20) +# define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA (1<<20) +# define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB (2<<20) +# define PM3VideoOverlayMode_MIRROR_MASK (3<<23) +# define PM3VideoOverlayMode_MIRRORX_OFF (0<<23) +# define PM3VideoOverlayMode_MIRRORX_ON (1<<23) +# define PM3VideoOverlayMode_MIRRORY_OFF (0<<24) +# define PM3VideoOverlayMode_MIRRORY_ON (1<<24) #define PM3VideoOverlayFifoControl 0x3110 #define PM3VideoOverlayIndex 0x3118 #define PM3VideoOverlayBase 0x3120 @@ -213,25 +213,25 @@ #define PM3VideoOverlayBase1 0x3128 #define PM3VideoOverlayBase2 0x3130 #define PM3VideoOverlayStride 0x3138 - #define PM3VideoOverlayStride_STRIDE(s) (((s)&0xfff)<<0) +# define PM3VideoOverlayStride_STRIDE(s) (((s)&0xfff)<<0) #define PM3VideoOverlayWidth 0x3140 - #define PM3VideoOverlayWidth_WIDTH(w) (((w)&0xfff)<<0) +# define PM3VideoOverlayWidth_WIDTH(w) (((w)&0xfff)<<0) #define PM3VideoOverlayHeight 0x3148 - #define PM3VideoOverlayHeight_HEIGHT(h) (((h)&0xfff)<<0) +# define PM3VideoOverlayHeight_HEIGHT(h) (((h)&0xfff)<<0) #define PM3VideoOverlayOrigin 0x3150 - #define PM3VideoOverlayOrigin_XORIGIN(x) (((x)&0xfff)<<0) - #define PM3VideoOverlayOrigin_YORIGIN(y) (((y)&0xfff)<<16) +# define PM3VideoOverlayOrigin_XORIGIN(x) (((x)&0xfff)<<0) +# define PM3VideoOverlayOrigin_YORIGIN(y) (((y)&0xfff)<<16) #define PM3VideoOverlayShrinkXDelta 0x3158 - #define PM3VideoOverlayShrinkXDelta_NONE (1<<16) - #define PM3VideoOverlayShrinkXDelta_DELTA(s,d) \ +# define PM3VideoOverlayShrinkXDelta_NONE (1<<16) +# define PM3VideoOverlayShrinkXDelta_DELTA(s,d) \ ((((s)<<16)/(d))&0x0ffffff0) #define PM3VideoOverlayZoomXDelta 0x3160 - #define PM3VideoOverlayZoomXDelta_NONE (1<<16) - #define PM3VideoOverlayZoomXDelta_DELTA(s,d) \ +# define PM3VideoOverlayZoomXDelta_NONE (1<<16) +# define PM3VideoOverlayZoomXDelta_DELTA(s,d) \ ((((s)<<16)/(d))&0x0001fff0) #define PM3VideoOverlayYDelta 0x3168 - #define PM3VideoOverlayYDelta_NONE (1<<16) - #define PM3VideoOverlayYDelta_DELTA(s,d) \ +# define PM3VideoOverlayYDelta_NONE (1<<16) +# define PM3VideoOverlayYDelta_DELTA(s,d) \ ((((s)<<16)/(d))&0x0ffffff0) #define PM3VideoOverlayFieldOffset 0x3170 #define PM3VideoOverlayStatus 0x3178 @@ -249,102 +249,102 @@ #define PM3RD_IndexHigh 0x4028 #define PM3RD_IndexedData 0x4030 #define PM3RD_IndexControl 0x4038 - #define PM3RD_IndexControl_AUTOINCREMENT_ENABLE (1<<0) - #define PM3RD_IndexControl_AUTOINCREMENT_DISABLE (0<<0) +# define PM3RD_IndexControl_AUTOINCREMENT_ENABLE (1<<0) +# define PM3RD_IndexControl_AUTOINCREMENT_DISABLE (0<<0) /* Indirect Registers */ #define PM3RD_MiscControl 0x000 - #define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE (0<<0) - #define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE (1<<0) - #define PM3RD_MiscControl_PIXELDOUBLE_DISABLE (0<<1) - #define PM3RD_MiscControl_PIXELDOUBLE_ENABLE (1<<1) - #define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE (0<<2) - #define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE (1<<2) - #define PM3RD_MiscControl_DIRECTCOLOR_DISABLE (0<<3) - #define PM3RD_MiscControl_DIRECTCOLOR_ENABLE (1<<3) - #define PM3RD_MiscControl_OVERLAY_DISABLE (0<<4) - #define PM3RD_MiscControl_OVERLAY_ENABLE (1<<4) - #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE (0<<5) - #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE (1<<5) - #define PM3RD_MiscControl_VSB_OUTPUT_DISABLE (0<<6) - #define PM3RD_MiscControl_VSB_OUTPUT_ENABLE (1<<6) - #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE (0<<7) - #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE (1<<7) +# define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE (0<<0) +# define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE (1<<0) +# define PM3RD_MiscControl_PIXELDOUBLE_DISABLE (0<<1) +# define PM3RD_MiscControl_PIXELDOUBLE_ENABLE (1<<1) +# define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE (0<<2) +# define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE (1<<2) +# define PM3RD_MiscControl_DIRECTCOLOR_DISABLE (0<<3) +# define PM3RD_MiscControl_DIRECTCOLOR_ENABLE (1<<3) +# define PM3RD_MiscControl_OVERLAY_DISABLE (0<<4) +# define PM3RD_MiscControl_OVERLAY_ENABLE (1<<4) +# define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE (0<<5) +# define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE (1<<5) +# define PM3RD_MiscControl_VSB_OUTPUT_DISABLE (0<<6) +# define PM3RD_MiscControl_VSB_OUTPUT_ENABLE (1<<6) +# define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE (0<<7) +# define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE (1<<7) #define PM3RD_SyncControl 0x001 - #define PM3RD_SyncControl_HSYNC_ACTIVE_LOW (0<<0) - #define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH (1<<0) - #define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE (3<<0) - #define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE (4<<0) - #define PM3RD_SyncControl_HSYNC_TRI_STATE (2<<0) - #define PM3RD_SyncControl_VSYNC_ACTIVE_LOW (0<<3) - #define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH (1<<3) - #define PM3RD_SyncControl_VSYNC_TRI_STATE (2<<3) - #define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE (3<<3) - #define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE (4<<3) - #define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC (0<<6) - #define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH (1<<6) - #define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC (0<<7) - #define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH (1<<7) +# define PM3RD_SyncControl_HSYNC_ACTIVE_LOW (0<<0) +# define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH (1<<0) +# define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE (3<<0) +# define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE (4<<0) +# define PM3RD_SyncControl_HSYNC_TRI_STATE (2<<0) +# define PM3RD_SyncControl_VSYNC_ACTIVE_LOW (0<<3) +# define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH (1<<3) +# define PM3RD_SyncControl_VSYNC_TRI_STATE (2<<3) +# define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE (3<<3) +# define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE (4<<3) +# define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC (0<<6) +# define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH (1<<6) +# define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC (0<<7) +# define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH (1<<7) #define PM3RD_DACControl 0x002 - #define PM3RD_DACControl_DAC_POWER_ON (0<<0) - #define PM3RD_DACControl_DAC_POWER_OFF (1<<0) - #define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE (0<<3) - #define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE (1<<3) - #define PM3RD_DACControl_BLANK_RED_DAC_DISABLE (0<<4) - #define PM3RD_DACControl_BLANK_RED_DAC_ENABLE (1<<4) - #define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE (0<<5) - #define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE (1<<5) - #define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE (0<<6) - #define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE (1<<6) - #define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE (0<<7) - #define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE (1<<7) +# define PM3RD_DACControl_DAC_POWER_ON (0<<0) +# define PM3RD_DACControl_DAC_POWER_OFF (1<<0) +# define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE (0<<3) +# define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE (1<<3) +# define PM3RD_DACControl_BLANK_RED_DAC_DISABLE (0<<4) +# define PM3RD_DACControl_BLANK_RED_DAC_ENABLE (1<<4) +# define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE (0<<5) +# define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE (1<<5) +# define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE (0<<6) +# define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE (1<<6) +# define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE (0<<7) +# define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE (1<<7) #define PM3RD_PixelSize 0x003 - #define PM3RD_PixelSize_24_BIT_PIXELS (4<<0) - #define PM3RD_PixelSize_32_BIT_PIXELS (2<<0) - #define PM3RD_PixelSize_16_BIT_PIXELS (1<<0) - #define PM3RD_PixelSize_8_BIT_PIXELS (0<<0) +# define PM3RD_PixelSize_24_BIT_PIXELS (4<<0) +# define PM3RD_PixelSize_32_BIT_PIXELS (2<<0) +# define PM3RD_PixelSize_16_BIT_PIXELS (1<<0) +# define PM3RD_PixelSize_8_BIT_PIXELS (0<<0) #define PM3RD_ColorFormat 0x004 - #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE (1<<6) - #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE (0<<6) - #define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW (1<<5) - #define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW (0<<5) - #define PM3RD_ColorFormat_COLOR_FORMAT_MASK (0x1f<<0) - #define PM3RD_ColorFormat_8888_COLOR (0<<0) - #define PM3RD_ColorFormat_5551_FRONT_COLOR (1<<0) - #define PM3RD_ColorFormat_4444_COLOR (2<<0) - #define PM3RD_ColorFormat_332_FRONT_COLOR (5<<0) - #define PM3RD_ColorFormat_332_BACK_COLOR (6<<0) - #define PM3RD_ColorFormat_2321_FRONT_COLOR (9<<0) - #define PM3RD_ColorFormat_2321_BACK_COLOR (10<<0) - #define PM3RD_ColorFormat_232_FRONTOFF_COLOR (11<<0) - #define PM3RD_ColorFormat_232_BACKOFF_COLOR (12<<0) - #define PM3RD_ColorFormat_5551_BACK_COLOR (13<<0) - #define PM3RD_ColorFormat_CI8_COLOR (14<<0) - #define PM3RD_ColorFormat_565_FRONT_COLOR (16<<0) - #define PM3RD_ColorFormat_565_BACK_COLOR (17<<0) +# define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE (1<<6) +# define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE (0<<6) +# define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW (1<<5) +# define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW (0<<5) +# define PM3RD_ColorFormat_COLOR_FORMAT_MASK (0x1f<<0) +# define PM3RD_ColorFormat_8888_COLOR (0<<0) +# define PM3RD_ColorFormat_5551_FRONT_COLOR (1<<0) +# define PM3RD_ColorFormat_4444_COLOR (2<<0) +# define PM3RD_ColorFormat_332_FRONT_COLOR (5<<0) +# define PM3RD_ColorFormat_332_BACK_COLOR (6<<0) +# define PM3RD_ColorFormat_2321_FRONT_COLOR (9<<0) +# define PM3RD_ColorFormat_2321_BACK_COLOR (10<<0) +# define PM3RD_ColorFormat_232_FRONTOFF_COLOR (11<<0) +# define PM3RD_ColorFormat_232_BACKOFF_COLOR (12<<0) +# define PM3RD_ColorFormat_5551_BACK_COLOR (13<<0) +# define PM3RD_ColorFormat_CI8_COLOR (14<<0) +# define PM3RD_ColorFormat_565_FRONT_COLOR (16<<0) +# define PM3RD_ColorFormat_565_BACK_COLOR (17<<0) #define PM3RD_CursorMode 0x005 - #define PM3RD_CursorMode_CURSOR_DISABLE (0<<0) - #define PM3RD_CursorMode_CURSOR_ENABLE (1<<0) - #define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123 (0<<2) - #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0 (1<<2) - #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1 (2<<2) - #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2 (3<<2) - #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3 (4<<2) - #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01 (5<<2) - #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23 (6<<2) - #define PM3RD_CursorMode_TYPE_MS (0<<4) - #define PM3RD_CursorMode_TYPE_X (1<<4) - #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE (0<<6) - #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE (1<<6) - #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR (2<<6) - #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR (3<<6) +# define PM3RD_CursorMode_CURSOR_DISABLE (0<<0) +# define PM3RD_CursorMode_CURSOR_ENABLE (1<<0) +# define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123 (0<<2) +# define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0 (1<<2) +# define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1 (2<<2) +# define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2 (3<<2) +# define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3 (4<<2) +# define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01 (5<<2) +# define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23 (6<<2) +# define PM3RD_CursorMode_TYPE_MS (0<<4) +# define PM3RD_CursorMode_TYPE_X (1<<4) +# define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE (0<<6) +# define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE (1<<6) +# define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR (2<<6) +# define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR (3<<6) #define PM3RD_CursorControl 0x006 - #define PM3RD_CursorControl_DOUBLE_X_DISABLED (0<<0) - #define PM3RD_CursorControl_DOUBLE_X_ENABLED (1<<0) - #define PM3RD_CursorControl_DOUBLE_Y_DISABLED (0<<1) - #define PM3RD_CursorControl_DOUBLE_Y_ENABLED (1<<1) - #define PM3RD_CursorControl_READBACK_POS_DISABLED (0<<2) - #define PM3RD_CursorControl_READBACK_POS_ENABLED (1<<2) +# define PM3RD_CursorControl_DOUBLE_X_DISABLED (0<<0) +# define PM3RD_CursorControl_DOUBLE_X_ENABLED (1<<0) +# define PM3RD_CursorControl_DOUBLE_Y_DISABLED (0<<1) +# define PM3RD_CursorControl_DOUBLE_Y_ENABLED (1<<1) +# define PM3RD_CursorControl_READBACK_POS_DISABLED (0<<2) +# define PM3RD_CursorControl_READBACK_POS_ENABLED (1<<2) #define PM3RD_CursorXLow 0x007 #define PM3RD_CursorXHigh 0x008 @@ -354,17 +354,17 @@ #define PM3RD_CursorHotSpotY 0x00c #define PM3RD_OverlayKey 0x00d #define PM3RD_Pan 0x00e - #define PM3RD_Pan_DISABLE (0<<0) - #define PM3RD_Pan_ENABLE (1<<0) - #define PM3RD_Pan_GATE_DISABLE (0<<1) - #define PM3RD_Pan_GATE_ENABLE (1<<1) +# define PM3RD_Pan_DISABLE (0<<0) +# define PM3RD_Pan_ENABLE (1<<0) +# define PM3RD_Pan_GATE_DISABLE (0<<1) +# define PM3RD_Pan_GATE_ENABLE (1<<1) #define PM3RD_Sense 0x00f #define PM3RD_CheckControl 0x018 - #define PM3RD_CheckControl_PIXEL_DISABLED (0<<0) - #define PM3RD_CheckControl_PIXEL_ENABLED (1<<0) - #define PM3RD_CheckControl_LUT_DISABLED (0<<1) - #define PM3RD_CheckControl_LUT_ENABLED (1<<1) +# define PM3RD_CheckControl_PIXEL_DISABLED (0<<0) +# define PM3RD_CheckControl_PIXEL_ENABLED (1<<0) +# define PM3RD_CheckControl_LUT_DISABLED (0<<1) +# define PM3RD_CheckControl_LUT_ENABLED (1<<1) #define PM3RD_CheckPixelRed 0x019 #define PM3RD_CheckPixelGreen 0x01a #define PM3RD_CheckPixelBlue 0x01b @@ -374,19 +374,19 @@ #define PM3RD_Scratch 0x01f #define PM3RD_VideoOverlayControl 0x020 - #define PM3RD_VideoOverlayControl_DISABLE (0<<0) - #define PM3RD_VideoOverlayControl_ENABLE (1<<0) - #define PM3RD_VideoOverlayControl_MODE_MASK (3<<1) - #define PM3RD_VideoOverlayControl_MODE_MAINKEY (0<<1) - #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY (1<<1) - #define PM3RD_VideoOverlayControl_MODE_ALWAYS (2<<1) - #define PM3RD_VideoOverlayControl_MODE_BLEND (3<<1) - #define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED (0<<3) - #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED (1<<3) - #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN (0<<4) - #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER (1<<4) - #define PM3RD_VideoOverlayControl_KEY_COLOR (0<<5) - #define PM3RD_VideoOverlayControl_KEY_ALPHA (1<<5) +# define PM3RD_VideoOverlayControl_DISABLE (0<<0) +# define PM3RD_VideoOverlayControl_ENABLE (1<<0) +# define PM3RD_VideoOverlayControl_MODE_MASK (3<<1) +# define PM3RD_VideoOverlayControl_MODE_MAINKEY (0<<1) +# define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY (1<<1) +# define PM3RD_VideoOverlayControl_MODE_ALWAYS (2<<1) +# define PM3RD_VideoOverlayControl_MODE_BLEND (3<<1) +# define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED (0<<3) +# define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED (1<<3) +# define PM3RD_VideoOverlayControl_BLENDSRC_MAIN (0<<4) +# define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER (1<<4) +# define PM3RD_VideoOverlayControl_KEY_COLOR (0<<5) +# define PM3RD_VideoOverlayControl_KEY_ALPHA (1<<5) #define PM3RD_VideoOverlayXStartLow 0x021 #define PM3RD_VideoOverlayXStartHigh 0x022 #define PM3RD_VideoOverlayYStartLow 0x023 @@ -399,10 +399,10 @@ #define PM3RD_VideoOverlayKeyG 0x02a #define PM3RD_VideoOverlayKeyB 0x02b #define PM3RD_VideoOverlayBlend 0x02c - #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT (0<<6) - #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT (1<<6) - #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT (2<<6) - #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT (3<<6) +# define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT (0<<6) +# define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT (1<<6) +# define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT (2<<6) +# define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT (3<<6) #define PM3RD_DClkSetup1 0x1f0 #define PM3RD_DClkSetup2 0x1f1 @@ -410,17 +410,17 @@ #define PM3RD_KClkSetup2 0x1f3 #define PM3RD_DClkControl 0x200 - #define PM3RD_DClkControl_SOURCE_PLL (0<<4) - #define PM3RD_DClkControl_SOURCE_VSA (1<<4) - #define PM3RD_DClkControl_SOURCE_VSB (2<<4) - #define PM3RD_DClkControl_SOURCE_EXT (3<<4) - #define PM3RD_DClkControl_STATE_RUN (2<<2) - #define PM3RD_DClkControl_STATE_HIGH (1<<2) - #define PM3RD_DClkControl_STATE_LOW (0<<2) - #define PM3RD_DClkControl_LOCKED (1<<1) - #define PM3RD_DClkControl_NOT_LOCKED (0<<1) - #define PM3RD_DClkControl_ENABLE (1<<0) - #define PM3RD_DClkControl_DISABLE (0<<0) +# define PM3RD_DClkControl_SOURCE_PLL (0<<4) +# define PM3RD_DClkControl_SOURCE_VSA (1<<4) +# define PM3RD_DClkControl_SOURCE_VSB (2<<4) +# define PM3RD_DClkControl_SOURCE_EXT (3<<4) +# define PM3RD_DClkControl_STATE_RUN (2<<2) +# define PM3RD_DClkControl_STATE_HIGH (1<<2) +# define PM3RD_DClkControl_STATE_LOW (0<<2) +# define PM3RD_DClkControl_LOCKED (1<<1) +# define PM3RD_DClkControl_NOT_LOCKED (0<<1) +# define PM3RD_DClkControl_ENABLE (1<<0) +# define PM3RD_DClkControl_DISABLE (0<<0) #define PM3RD_DClk0PreScale 0x201 #define PM3RD_DClk0FeedbackScale 0x202 #define PM3RD_DClk0PostScale 0x203 @@ -434,53 +434,53 @@ #define PM3RD_DClk3FeedbackScale 0x20b #define PM3RD_DClk3PostScale 0x20c #define PM3RD_KClkControl 0x20d - #define PM3RD_KClkControl_DISABLE (0<<0) - #define PM3RD_KClkControl_ENABLE (1<<0) - #define PM3RD_KClkControl_NOT_LOCKED (0<<1) - #define PM3RD_KClkControl_LOCKED (1<<1) - #define PM3RD_KClkControl_STATE_LOW (0<<2) - #define PM3RD_KClkControl_STATE_HIGH (1<<2) - #define PM3RD_KClkControl_STATE_RUN (2<<2) - #define PM3RD_KClkControl_STATE_LOW_POWER (3<<2) - #define PM3RD_KClkControl_SOURCE_PCLK (0<<4) - #define PM3RD_KClkControl_SOURCE_HALF_PCLK (1<<4) - #define PM3RD_KClkControl_SOURCE_PLL (2<<4) +# define PM3RD_KClkControl_DISABLE (0<<0) +# define PM3RD_KClkControl_ENABLE (1<<0) +# define PM3RD_KClkControl_NOT_LOCKED (0<<1) +# define PM3RD_KClkControl_LOCKED (1<<1) +# define PM3RD_KClkControl_STATE_LOW (0<<2) +# define PM3RD_KClkControl_STATE_HIGH (1<<2) +# define PM3RD_KClkControl_STATE_RUN (2<<2) +# define PM3RD_KClkControl_STATE_LOW_POWER (3<<2) +# define PM3RD_KClkControl_SOURCE_PCLK (0<<4) +# define PM3RD_KClkControl_SOURCE_HALF_PCLK (1<<4) +# define PM3RD_KClkControl_SOURCE_PLL (2<<4) #define PM3RD_KClkPreScale 0x20e #define PM3RD_KClkFeedbackScale 0x20f #define PM3RD_KClkPostScale 0x210 #define PM3RD_MClkControl 0x211 - #define PM3RD_MClkControl_DISABLE (0<<0) - #define PM3RD_MClkControl_ENABLE (1<<0) - #define PM3RD_MClkControl_NOT_LOCKED (0<<1) - #define PM3RD_MClkControl_LOCKED (1<<1) - #define PM3RD_MClkControl_STATE_LOW (0<<2) - #define PM3RD_MClkControl_STATE_HIGH (1<<2) - #define PM3RD_MClkControl_STATE_RUN (2<<2) - #define PM3RD_MClkControl_STATE_LOW_POWER (3<<2) - #define PM3RD_MClkControl_SOURCE_PCLK (0<<4) - #define PM3RD_MClkControl_SOURCE_HALF_PCLK (1<<4) - #define PM3RD_MClkControl_SOURCE_HALF_EXT (3<<4) - #define PM3RD_MClkControl_SOURCE_EXT (4<<4) - #define PM3RD_MClkControl_SOURCE_HALF_KCLK (5<<4) - #define PM3RD_MClkControl_SOURCE_KCLK (6<<4) +# define PM3RD_MClkControl_DISABLE (0<<0) +# define PM3RD_MClkControl_ENABLE (1<<0) +# define PM3RD_MClkControl_NOT_LOCKED (0<<1) +# define PM3RD_MClkControl_LOCKED (1<<1) +# define PM3RD_MClkControl_STATE_LOW (0<<2) +# define PM3RD_MClkControl_STATE_HIGH (1<<2) +# define PM3RD_MClkControl_STATE_RUN (2<<2) +# define PM3RD_MClkControl_STATE_LOW_POWER (3<<2) +# define PM3RD_MClkControl_SOURCE_PCLK (0<<4) +# define PM3RD_MClkControl_SOURCE_HALF_PCLK (1<<4) +# define PM3RD_MClkControl_SOURCE_HALF_EXT (3<<4) +# define PM3RD_MClkControl_SOURCE_EXT (4<<4) +# define PM3RD_MClkControl_SOURCE_HALF_KCLK (5<<4) +# define PM3RD_MClkControl_SOURCE_KCLK (6<<4) #define PM3RD_MClkPreScale 0x212 #define PM3RD_MClkFeedbackScale 0x213 #define PM3RD_MClkPostScale 0x214 #define PM3RD_SClkControl 0x215 - #define PM3RD_SClkControl_DISABLE (0<<0) - #define PM3RD_SClkControl_ENABLE (1<<0) - #define PM3RD_SClkControl_NOT_LOCKED (0<<1) - #define PM3RD_SClkControl_LOCKED (1<<1) - #define PM3RD_SClkControl_STATE_LOW (0<<2) - #define PM3RD_SClkControl_STATE_HIGH (1<<2) - #define PM3RD_SClkControl_STATE_RUN (2<<2) - #define PM3RD_SClkControl_STATE_LOW_POWER (3<<2) - #define PM3RD_SClkControl_SOURCE_PCLK (0<<4) - #define PM3RD_SClkControl_SOURCE_HALF_PCLK (1<<4) - #define PM3RD_SClkControl_SOURCE_HALF_EXT (3<<4) - #define PM3RD_SClkControl_SOURCE_EXT (4<<4) - #define PM3RD_SClkControl_SOURCE_HALF_KCLK (5<<4) - #define PM3RD_SClkControl_SOURCE_KCLK (6<<4) +# define PM3RD_SClkControl_DISABLE (0<<0) +# define PM3RD_SClkControl_ENABLE (1<<0) +# define PM3RD_SClkControl_NOT_LOCKED (0<<1) +# define PM3RD_SClkControl_LOCKED (1<<1) +# define PM3RD_SClkControl_STATE_LOW (0<<2) +# define PM3RD_SClkControl_STATE_HIGH (1<<2) +# define PM3RD_SClkControl_STATE_RUN (2<<2) +# define PM3RD_SClkControl_STATE_LOW_POWER (3<<2) +# define PM3RD_SClkControl_SOURCE_PCLK (0<<4) +# define PM3RD_SClkControl_SOURCE_HALF_PCLK (1<<4) +# define PM3RD_SClkControl_SOURCE_HALF_EXT (3<<4) +# define PM3RD_SClkControl_SOURCE_EXT (4<<4) +# define PM3RD_SClkControl_SOURCE_HALF_KCLK (5<<4) +# define PM3RD_SClkControl_SOURCE_KCLK (6<<4) #define PM3RD_SClkPreScale 0x216 #define PM3RD_SClkFeedbackScale 0x217 #define PM3RD_SClkPostScale 0x218 @@ -520,10 +520,10 @@ #define PM3ColorDDAModeOr 0xabe8 #define PM3CommandInterrupt 0xa990 #define PM3ConstantColorDDA 0xafb0 - #define PM3ConstantColorDDA_R(r) ((r)&0xff) - #define PM3ConstantColorDDA_G(g) (((g)&0xff)<<8) - #define PM3ConstantColorDDA_B(b) (((b)&0xff)<<16) - #define PM3ConstantColorDDA_A(a) (((a)&0xff)<<24) +# define PM3ConstantColorDDA_R(r) ((r)&0xff) +# define PM3ConstantColorDDA_G(g) (((g)&0xff)<<8) +# define PM3ConstantColorDDA_B(b) (((b)&0xff)<<16) +# define PM3ConstantColorDDA_A(a) (((a)&0xff)<<24) #define PM3ContextData 0x8dd0 #define PM3ContextDump 0x8dc0 #define PM3ContextRestore 0x8dc8 @@ -567,59 +567,59 @@ #define PM3FBDestReadBufferOffset1 0xaea8 #define PM3FBDestReadBufferOffset2 0xaeb0 #define PM3FBDestReadBufferOffset3 0xaeb8 - #define PM3FBDestReadBufferOffset_XOffset(x) ((x)&0xffff) - #define PM3FBDestReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) +# define PM3FBDestReadBufferOffset_XOffset(x) ((x)&0xffff) +# define PM3FBDestReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3FBDestReadBufferWidth0 0xaec0 #define PM3FBDestReadBufferWidth1 0xaec8 #define PM3FBDestReadBufferWidth2 0xaed0 #define PM3FBDestReadBufferWidth3 0xaed8 - #define PM3FBDestReadBufferWidth_Width(w) ((w)&0x0fff) +# define PM3FBDestReadBufferWidth_Width(w) ((w)&0x0fff) #define PM3FBDestReadEnables 0xaee8 #define PM3FBDestReadEnablesAnd 0xad20 #define PM3FBDestReadEnablesOr 0xad28 - #define PM3FBDestReadEnables_E(e) ((e)&0xff) - #define PM3FBDestReadEnables_E0 1<<0 - #define PM3FBDestReadEnables_E1 1<<1 - #define PM3FBDestReadEnables_E2 1<<2 - #define PM3FBDestReadEnables_E3 1<<3 - #define PM3FBDestReadEnables_E4 1<<4 - #define PM3FBDestReadEnables_E5 1<<5 - #define PM3FBDestReadEnables_E6 1<<6 - #define PM3FBDestReadEnables_E7 1<<7 - #define PM3FBDestReadEnables_R(r) (((r)&0xff)<<8) - #define PM3FBDestReadEnables_R0 1<<8 - #define PM3FBDestReadEnables_R1 1<<9 - #define PM3FBDestReadEnables_R2 1<<10 - #define PM3FBDestReadEnables_R3 1<<11 - #define PM3FBDestReadEnables_R4 1<<12 - #define PM3FBDestReadEnables_R5 1<<13 - #define PM3FBDestReadEnables_R6 1<<14 - #define PM3FBDestReadEnables_R7 1<<15 - #define PM3FBDestReadEnables_ReferenceAlpha(a) (((a)&0xff)<<24) +# define PM3FBDestReadEnables_E(e) ((e)&0xff) +# define PM3FBDestReadEnables_E0 1<<0 +# define PM3FBDestReadEnables_E1 1<<1 +# define PM3FBDestReadEnables_E2 1<<2 +# define PM3FBDestReadEnables_E3 1<<3 +# define PM3FBDestReadEnables_E4 1<<4 +# define PM3FBDestReadEnables_E5 1<<5 +# define PM3FBDestReadEnables_E6 1<<6 +# define PM3FBDestReadEnables_E7 1<<7 +# define PM3FBDestReadEnables_R(r) (((r)&0xff)<<8) +# define PM3FBDestReadEnables_R0 1<<8 +# define PM3FBDestReadEnables_R1 1<<9 +# define PM3FBDestReadEnables_R2 1<<10 +# define PM3FBDestReadEnables_R3 1<<11 +# define PM3FBDestReadEnables_R4 1<<12 +# define PM3FBDestReadEnables_R5 1<<13 +# define PM3FBDestReadEnables_R6 1<<14 +# define PM3FBDestReadEnables_R7 1<<15 +# define PM3FBDestReadEnables_ReferenceAlpha(a) (((a)&0xff)<<24) #define PM3FBDestReadMode 0xaee0 #define PM3FBDestReadModeAnd 0xac90 #define PM3FBDestReadModeOr 0xac98 - #define PM3FBDestReadMode_ReadDisable 0<<0 - #define PM3FBDestReadMode_ReadEnable 1<<0 - #define PM3FBDestReadMode_StripePitch(sp) (((sp)&0x7)<<2 - #define PM3FBDestReadMode_StripeHeight(sh) (((sh)&0x7)<<7 - #define PM3FBDestReadMode_Enable0 1<<8 - #define PM3FBDestReadMode_Enable1 1<<9 - #define PM3FBDestReadMode_Enable2 1<<10 - #define PM3FBDestReadMode_Enable3 1<<11 - #define PM3FBDestReadMode_Layout0(l) (((l)&0x3)<<12 - #define PM3FBDestReadMode_Layout1(l) (((l)&0x3)<<14 - #define PM3FBDestReadMode_Layout2(l) (((l)&0x3)<<16 - #define PM3FBDestReadMode_Layout3(l) (((l)&0x3)<<18 - #define PM3FBDestReadMode_Origin0 1<<20 - #define PM3FBDestReadMode_Origin1 1<<21 - #define PM3FBDestReadMode_Origin2 1<<22 - #define PM3FBDestReadMode_Origin3 1<<23 - #define PM3FBDestReadMode_Blocking 1<<24 - #define PM3FBDestReadMode_UseReadEnabled 1<<26 - #define PM3FBDestReadMode_AlphaFiltering 1<<27 +# define PM3FBDestReadMode_ReadDisable 0<<0 +# define PM3FBDestReadMode_ReadEnable 1<<0 +# define PM3FBDestReadMode_StripePitch(sp) (((sp)&0x7)<<2 +# define PM3FBDestReadMode_StripeHeight(sh) (((sh)&0x7)<<7 +# define PM3FBDestReadMode_Enable0 1<<8 +# define PM3FBDestReadMode_Enable1 1<<9 +# define PM3FBDestReadMode_Enable2 1<<10 +# define PM3FBDestReadMode_Enable3 1<<11 +# define PM3FBDestReadMode_Layout0(l) (((l)&0x3)<<12 +# define PM3FBDestReadMode_Layout1(l) (((l)&0x3)<<14 +# define PM3FBDestReadMode_Layout2(l) (((l)&0x3)<<16 +# define PM3FBDestReadMode_Layout3(l) (((l)&0x3)<<18 +# define PM3FBDestReadMode_Origin0 1<<20 +# define PM3FBDestReadMode_Origin1 1<<21 +# define PM3FBDestReadMode_Origin2 1<<22 +# define PM3FBDestReadMode_Origin3 1<<23 +# define PM3FBDestReadMode_Blocking 1<<24 +# define PM3FBDestReadMode_UseReadEnabled 1<<26 +# define PM3FBDestReadMode_AlphaFiltering 1<<27 #define PM3FBHardwareWriteMask 0x8ac0 #define PM3FBSoftwareWriteMask 0x8820 @@ -627,26 +627,26 @@ #define PM3FBSourceData 0x8aa8 #define PM3FBSourceReadBufferAddr 0xaf08 #define PM3FBSourceReadBufferOffset 0xaf10 - #define PM3FBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) - #define PM3FBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) +# define PM3FBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) +# define PM3FBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3FBSourceReadBufferWidth 0xaf18 - #define PM3FBSourceReadBufferWidth_Width(w) ((w)&0x0fff) +# define PM3FBSourceReadBufferWidth_Width(w) ((w)&0x0fff) #define PM3FBSourceReadMode 0xaf00 #define PM3FBSourceReadModeAnd 0xaca0 #define PM3FBSourceReadModeOr 0xaca8 - #define PM3FBSourceReadMode_ReadDisable (0<<0) - #define PM3FBSourceReadMode_ReadEnable (1<<0) - #define PM3FBSourceReadMode_StripePitch(sp) (((sp)&0x7)<<2 - #define PM3FBSourceReadMode_StripeHeight(sh) (((sh)&0x7)<<7 - #define PM3FBSourceReadMode_Layout(l) (((l)&0x3)<<8 - #define PM3FBSourceReadMode_Origin 1<<10 - #define PM3FBSourceReadMode_Blocking 1<<11 - #define PM3FBSourceReadMode_UserTexelCoord 1<<13 - #define PM3FBSourceReadMode_WrapXEnable 1<<14 - #define PM3FBSourceReadMode_WrapYEnable 1<<15 - #define PM3FBSourceReadMode_WrapX(w) (((w)&0xf)<<16 - #define PM3FBSourceReadMode_WrapY(w) (((w)&0xf)<<20 - #define PM3FBSourceReadMode_ExternalSourceData 1<<24 +# define PM3FBSourceReadMode_ReadDisable (0<<0) +# define PM3FBSourceReadMode_ReadEnable (1<<0) +# define PM3FBSourceReadMode_StripePitch(sp) (((sp)&0x7)<<2 +# define PM3FBSourceReadMode_StripeHeight(sh) (((sh)&0x7)<<7 +# define PM3FBSourceReadMode_Layout(l) (((l)&0x3)<<8 +# define PM3FBSourceReadMode_Origin 1<<10 +# define PM3FBSourceReadMode_Blocking 1<<11 +# define PM3FBSourceReadMode_UserTexelCoord 1<<13 +# define PM3FBSourceReadMode_WrapXEnable 1<<14 +# define PM3FBSourceReadMode_WrapYEnable 1<<15 +# define PM3FBSourceReadMode_WrapX(w) (((w)&0xf)<<16 +# define PM3FBSourceReadMode_WrapY(w) (((w)&0xf)<<20 +# define PM3FBSourceReadMode_ExternalSourceData 1<<24 #define PM3FBWriteBufferAddr0 0xb000 #define PM3FBWriteBufferAddr1 0xb008 #define PM3FBWriteBufferAddr2 0xb010 @@ -656,36 +656,36 @@ #define PM3FBWriteBufferOffset1 0xb028 #define PM3FBWriteBufferOffset2 0xb030 #define PM3FBWriteBufferOffset3 0xb038 - #define PM3FBWriteBufferOffset_XOffset(x) ((x)&0xffff) - #define PM3FBWriteBufferOffset_YOffset(y) (((y)&0xffff)<<16) +# define PM3FBWriteBufferOffset_XOffset(x) ((x)&0xffff) +# define PM3FBWriteBufferOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3FBWriteBufferWidth0 0xb040 #define PM3FBWriteBufferWidth1 0xb048 #define PM3FBWriteBufferWidth2 0xb050 #define PM3FBWriteBufferWidth3 0xb058 - #define PM3FBWriteBufferWidth_Width(w) ((w)&0x0fff) +# define PM3FBWriteBufferWidth_Width(w) ((w)&0x0fff) #define PM3FBWriteMode 0x8ab8 #define PM3FBWriteModeAnd 0xacf0 #define PM3FBWriteModeOr 0xacf8 - #define PM3FBWriteMode_WriteDisable 0<<0 - #define PM3FBWriteMode_WriteEnable 1<<0 - #define PM3FBWriteMode_Replicate 1<<4 - #define PM3FBWriteMode_OpaqueSpan 1<<5 - #define PM3FBWriteMode_StripePitch(p) (((p)&0x7)<<6) - #define PM3FBWriteMode_StripeHeight(h) (((h)&0x7)<<9) - #define PM3FBWriteMode_Enable0 1<<12 - #define PM3FBWriteMode_Enable1 1<<13 - #define PM3FBWriteMode_Enable2 1<<14 - #define PM3FBWriteMode_Enable3 1<<15 - #define PM3FBWriteMode_Layout0(l) (((l)&0x3)<<16) - #define PM3FBWriteMode_Layout1(l) (((l)&0x3)<<18) - #define PM3FBWriteMode_Layout2(l) (((l)&0x3)<<20) - #define PM3FBWriteMode_Layout3(l) (((l)&0x3)<<22) - #define PM3FBWriteMode_Origin0 1<<24 - #define PM3FBWriteMode_Origin1 1<<25 - #define PM3FBWriteMode_Origin2 1<<26 - #define PM3FBWriteMode_Origin3 1<<27 +# define PM3FBWriteMode_WriteDisable 0<<0 +# define PM3FBWriteMode_WriteEnable 1<<0 +# define PM3FBWriteMode_Replicate 1<<4 +# define PM3FBWriteMode_OpaqueSpan 1<<5 +# define PM3FBWriteMode_StripePitch(p) (((p)&0x7)<<6) +# define PM3FBWriteMode_StripeHeight(h) (((h)&0x7)<<9) +# define PM3FBWriteMode_Enable0 1<<12 +# define PM3FBWriteMode_Enable1 1<<13 +# define PM3FBWriteMode_Enable2 1<<14 +# define PM3FBWriteMode_Enable3 1<<15 +# define PM3FBWriteMode_Layout0(l) (((l)&0x3)<<16) +# define PM3FBWriteMode_Layout1(l) (((l)&0x3)<<18) +# define PM3FBWriteMode_Layout2(l) (((l)&0x3)<<20) +# define PM3FBWriteMode_Layout3(l) (((l)&0x3)<<22) +# define PM3FBWriteMode_Origin0 1<<24 +# define PM3FBWriteMode_Origin1 1<<25 +# define PM3FBWriteMode_Origin2 1<<26 +# define PM3FBWriteMode_Origin3 1<<27 #define PM3ForegroundColor 0xb0c0 /* ... */ #define PM3GIDMode 0xb538 @@ -700,55 +700,55 @@ #define PM3LBDestReadMode 0xb500 #define PM3LBDestReadModeAnd 0xb580 #define PM3LBDestReadModeOr 0xb588 - #define PM3LBDestReadMode_Disable 0<<0 - #define PM3LBDestReadMode_Enable 1<<0 - #define PM3LBDestReadMode_StripePitch(p) (((p)&0x7)<<2) - #define PM3LBDestReadMode_StripeHeight(h) (((h)&0x7)<<5) - #define PM3LBDestReadMode_Layout 1<<8 - #define PM3LBDestReadMode_Origin 1<<9 - #define PM3LBDestReadMode_UserReadEnables 1<<10 - #define PM3LBDestReadMode_Packed16 1<<11 - #define PM3LBDestReadMode_Width(w) (((w)&0xfff)<<12) +# define PM3LBDestReadMode_Disable 0<<0 +# define PM3LBDestReadMode_Enable 1<<0 +# define PM3LBDestReadMode_StripePitch(p) (((p)&0x7)<<2) +# define PM3LBDestReadMode_StripeHeight(h) (((h)&0x7)<<5) +# define PM3LBDestReadMode_Layout 1<<8 +# define PM3LBDestReadMode_Origin 1<<9 +# define PM3LBDestReadMode_UserReadEnables 1<<10 +# define PM3LBDestReadMode_Packed16 1<<11 +# define PM3LBDestReadMode_Width(w) (((w)&0xfff)<<12) #define PM3LBReadFormat 0x8888 - #define PM3LBReadFormat_DepthWidth(w) (((w)&0x3)<<0) - #define PM3LBReadFormat_StencilWidth(w) (((w)&0xf)<<2) - #define PM3LBReadFormat_StencilPosition(p) (((p)&0x1f)<<6) - #define PM3LBReadFormat_FCPWidth(w) (((w)&0xf)<<11) - #define PM3LBReadFormat_FCPPosition(p) (((p)&0x1f)<<15) - #define PM3LBReadFormat_GIDWidth(w) (((w)&0x7)<<20) - #define PM3LBReadFormat_GIDPosition(p) (((p)&0x1f)<<23) +# define PM3LBReadFormat_DepthWidth(w) (((w)&0x3)<<0) +# define PM3LBReadFormat_StencilWidth(w) (((w)&0xf)<<2) +# define PM3LBReadFormat_StencilPosition(p) (((p)&0x1f)<<6) +# define PM3LBReadFormat_FCPWidth(w) (((w)&0xf)<<11) +# define PM3LBReadFormat_FCPPosition(p) (((p)&0x1f)<<15) +# define PM3LBReadFormat_GIDWidth(w) (((w)&0x7)<<20) +# define PM3LBReadFormat_GIDPosition(p) (((p)&0x1f)<<23) #define PM3LBSourceReadBufferAddr 0xb528 #define PM3LBSourceReadBufferOffset 0xb530 #define PM3LBSourceReadMode 0xb520 #define PM3LBSourceReadModeAnd 0xb5a0 #define PM3LBSourceReadModeOr 0xb5a8 - #define PM3LBSourceReadMode_Enable 1<<0 - #define PM3LBSourceReadMode_StripePitch(p) (((p)&0x7)<<2) - #define PM3LBSourceReadMode_StripeHeight(h) (((h)&0x7)<<5) - #define PM3LBSourceReadMode_Layout 1<<8 - #define PM3LBSourceReadMode_Origin 1<<9 - #define PM3LBSourceReadMode_Packed16 1<<10 - #define PM3LBSourceReadMode_Width(w) (((w)&0xfff)<<11) +# define PM3LBSourceReadMode_Enable 1<<0 +# define PM3LBSourceReadMode_StripePitch(p) (((p)&0x7)<<2) +# define PM3LBSourceReadMode_StripeHeight(h) (((h)&0x7)<<5) +# define PM3LBSourceReadMode_Layout 1<<8 +# define PM3LBSourceReadMode_Origin 1<<9 +# define PM3LBSourceReadMode_Packed16 1<<10 +# define PM3LBSourceReadMode_Width(w) (((w)&0xfff)<<11) #define PM3LBStencil 0x88a8 #define PM3LBWriteBufferAddr 0xb540 #define PM3LBWriteBufferOffset 0xb548 #define PM3LBWriteFormat 0x88c8 - #define PM3LBWriteFormat_DepthWidth(w) (((w)&0x3)<<0) - #define PM3LBWriteFormat_StencilWidth(w) (((w)&0xf)<<2) - #define PM3LBWriteFormat_StencilPosition(p) (((p)&0x1f)<<6) - #define PM3LBWriteFormat_GIDWidth(w) (((w)&0x7)<<20) - #define PM3LBWriteFormat_GIDPosition(p) (((p)&0x1f)<<23) +# define PM3LBWriteFormat_DepthWidth(w) (((w)&0x3)<<0) +# define PM3LBWriteFormat_StencilWidth(w) (((w)&0xf)<<2) +# define PM3LBWriteFormat_StencilPosition(p) (((p)&0x1f)<<6) +# define PM3LBWriteFormat_GIDWidth(w) (((w)&0x7)<<20) +# define PM3LBWriteFormat_GIDPosition(p) (((p)&0x1f)<<23) #define PM3LBWriteMode 0x88c0 #define PM3LBWriteModeAnd 0xac80 #define PM3LBWriteModeOr 0xac88 - #define PM3LBWriteMode_WriteDisable 0<<0 - #define PM3LBWriteMode_WriteEnable 1<<0 - #define PM3LBWriteMode_StripePitch(p) (((p)&0x7)<<3) - #define PM3LBWriteMode_StripeHeight(h) (((h)&0x7)<<6) - #define PM3LBWriteMode_Layout 1<<9 - #define PM3LBWriteMode_Origin 1<<10 - #define PM3LBWriteMode_Packed16 1<<11 - #define PM3LBWriteMode_Width(w) (((w)&0xfff)<<12) +# define PM3LBWriteMode_WriteDisable 0<<0 +# define PM3LBWriteMode_WriteEnable 1<<0 +# define PM3LBWriteMode_StripePitch(p) (((p)&0x7)<<3) +# define PM3LBWriteMode_StripeHeight(h) (((h)&0x7)<<6) +# define PM3LBWriteMode_Layout 1<<9 +# define PM3LBWriteMode_Origin 1<<10 +# define PM3LBWriteMode_Packed16 1<<11 +# define PM3LBWriteMode_Width(w) (((w)&0xfff)<<12) /* ... */ #define PM3LineStippleMode 0x81a8 #define PM3LineStippleModeAnd 0xabc0 @@ -758,16 +758,16 @@ #define PM3LogicalOpMode 0x8828 #define PM3LogicalOpModeAnd 0xace0 #define PM3LogicalOpModeOr 0xace8 - #define PM3LogicalOpMode_Disable (0<<0) - #define PM3LogicalOpMode_Enable (1<<0) - #define PM3LogicalOpMode_LogicOp(op) (((op)&0xf)<<1) - #define PM3LogicalOpMode_UseConstantWriteData_Disable (0<<5) - #define PM3LogicalOpMode_UseConstantWriteData_Enable (1<<5) - #define PM3LogicalOpMode_Background_Disable (0<<6) - #define PM3LogicalOpMode_Background_Enable (1<<6) - #define PM3LogicalOpMode_Background_LogicOp(op) (((op)&0xf)<<7) - #define PM3LogicalOpMode_UseConstantSource_Disable (0<<11) - #define PM3LogicalOpMode_UseConstantSource_Enable (1<<11) +# define PM3LogicalOpMode_Disable (0<<0) +# define PM3LogicalOpMode_Enable (1<<0) +# define PM3LogicalOpMode_LogicOp(op) (((op)&0xf)<<1) +# define PM3LogicalOpMode_UseConstantWriteData_Disable (0<<5) +# define PM3LogicalOpMode_UseConstantWriteData_Enable (1<<5) +# define PM3LogicalOpMode_Background_Disable (0<<6) +# define PM3LogicalOpMode_Background_Enable (1<<6) +# define PM3LogicalOpMode_Background_LogicOp(op) (((op)&0xf)<<7) +# define PM3LogicalOpMode_UseConstantSource_Disable (0<<11) +# define PM3LogicalOpMode_UseConstantSource_Enable (1<<11) /* ... */ #define PM3LUT 0x8e80 @@ -782,70 +782,70 @@ #define PM3LUTTransfer 0x84d8 /* ... */ #define PM3PixelSize 0x80c0 - #define PM3PixelSize_GLOBAL_32BIT (0<<0) - #define PM3PixelSize_GLOBAL_16BIT (1<<0) - #define PM3PixelSize_GLOBAL_8BIT (2<<0) - #define PM3PixelSize_RASTERIZER_32BIT (0<<2) - #define PM3PixelSize_RASTERIZER_16BIT (1<<2) - #define PM3PixelSize_RASTERIZER_8BIT (2<<2) - #define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT (0<<4) - #define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT (1<<4) - #define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT (2<<4) - #define PM3PixelSize_TEXTURE_32BIT (0<<6) - #define PM3PixelSize_TEXTURE_16BIT (1<<6) - #define PM3PixelSize_TEXTURE_8BIT (2<<6) - #define PM3PixelSize_LUT_32BIT (0<<8) - #define PM3PixelSize_LUT_16BIT (1<<8) - #define PM3PixelSize_LUT_8BIT (2<<8) - #define PM3PixelSize_FRAMEBUFFER_32BIT (0<<10) - #define PM3PixelSize_FRAMEBUFFER_16BIT (1<<10) - #define PM3PixelSize_FRAMEBUFFER_8BIT (2<<10) - #define PM3PixelSize_LOGICAL_OP_32BIT (0<<12) - #define PM3PixelSize_LOGICAL_OP_16BIT (1<<12) - #define PM3PixelSize_LOGICAL_OP_8BIT (2<<12) - #define PM3PixelSize_LOCALBUFFER_32BIT (0<<14) - #define PM3PixelSize_LOCALBUFFER_16BIT (1<<14) - #define PM3PixelSize_LOCALBUFFER_8BIT (2<<14) - #define PM3PixelSize_SETUP_32BIT (0<<16) - #define PM3PixelSize_SETUP_16BIT (1<<16) - #define PM3PixelSize_SETUP_8BIT (2<<16) - #define PM3PixelSize_GLOBAL (0<<31) - #define PM3PixelSize_INDIVIDUAL (1<<31) +# define PM3PixelSize_GLOBAL_32BIT (0<<0) +# define PM3PixelSize_GLOBAL_16BIT (1<<0) +# define PM3PixelSize_GLOBAL_8BIT (2<<0) +# define PM3PixelSize_RASTERIZER_32BIT (0<<2) +# define PM3PixelSize_RASTERIZER_16BIT (1<<2) +# define PM3PixelSize_RASTERIZER_8BIT (2<<2) +# define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT (0<<4) +# define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT (1<<4) +# define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT (2<<4) +# define PM3PixelSize_TEXTURE_32BIT (0<<6) +# define PM3PixelSize_TEXTURE_16BIT (1<<6) +# define PM3PixelSize_TEXTURE_8BIT (2<<6) +# define PM3PixelSize_LUT_32BIT (0<<8) +# define PM3PixelSize_LUT_16BIT (1<<8) +# define PM3PixelSize_LUT_8BIT (2<<8) +# define PM3PixelSize_FRAMEBUFFER_32BIT (0<<10) +# define PM3PixelSize_FRAMEBUFFER_16BIT (1<<10) +# define PM3PixelSize_FRAMEBUFFER_8BIT (2<<10) +# define PM3PixelSize_LOGICAL_OP_32BIT (0<<12) +# define PM3PixelSize_LOGICAL_OP_16BIT (1<<12) +# define PM3PixelSize_LOGICAL_OP_8BIT (2<<12) +# define PM3PixelSize_LOCALBUFFER_32BIT (0<<14) +# define PM3PixelSize_LOCALBUFFER_16BIT (1<<14) +# define PM3PixelSize_LOCALBUFFER_8BIT (2<<14) +# define PM3PixelSize_SETUP_32BIT (0<<16) +# define PM3PixelSize_SETUP_16BIT (1<<16) +# define PM3PixelSize_SETUP_8BIT (2<<16) +# define PM3PixelSize_GLOBAL (0<<31) +# define PM3PixelSize_INDIVIDUAL (1<<31) /* ... */ #define PM3Render 0x8038 - #define PM3Render_AreaStipple_Disable (0<<0) - #define PM3Render_AreaStipple_Enable (1<<0) - #define PM3Render_LineStipple_Disable (0<<1) - #define PM3Render_LineStipple_Enable (1<<1) - #define PM3Render_ResetLine_Disable (0<<2) - #define PM3Render_ResetLine_Enable (1<<2) - #define PM3Render_FastFill_Disable (0<<3) - #define PM3Render_FastFill_Enable (1<<3) - #define PM3Render_Primitive_Line (0<<6) - #define PM3Render_Primitive_Trapezoid (1<<6) - #define PM3Render_Primitive_Point (2<<6) - #define PM3Render_Antialias_Disable (0<<8) - #define PM3Render_Antialias_Enable (1<<8) - #define PM3Render_Antialias_SubPixelRes_4x4 (0<<9) - #define PM3Render_Antialias_SubPixelRes_8x8 (1<<9) - #define PM3Render_UsePointTable_Disable (0<<10) - #define PM3Render_UsePointTable_Enable (1<<10) - #define PM3Render_SyncOnbitMask_Disable (0<<11) - #define PM3Render_SyncOnBitMask_Enable (1<<11) - #define PM3Render_SyncOnHostData_Disable (0<<12) - #define PM3Render_SyncOnHostData_Enable (1<<12) - #define PM3Render_Texture_Disable (0<<13) - #define PM3Render_Texture_Enable (1<<13) - #define PM3Render_Fog_Disable (0<<14) - #define PM3Render_Fog_Enable (1<<14) - #define PM3Render_Coverage_Disable (0<<15) - #define PM3Render_Coverage_Enable (1<<15) - #define PM3Render_SubPixelCorrection_Disable (0<<16) - #define PM3Render_SubPixelCorrection_Enable (1<<16) - #define PM3Render_SpanOperation_Disable (0<<18) - #define PM3Render_SpanOperation_Enable (1<<18) - #define PM3Render_FBSourceRead_Disable (0<<27) - #define PM3Render_FBSourceRead_Enable (1<<27) +# define PM3Render_AreaStipple_Disable (0<<0) +# define PM3Render_AreaStipple_Enable (1<<0) +# define PM3Render_LineStipple_Disable (0<<1) +# define PM3Render_LineStipple_Enable (1<<1) +# define PM3Render_ResetLine_Disable (0<<2) +# define PM3Render_ResetLine_Enable (1<<2) +# define PM3Render_FastFill_Disable (0<<3) +# define PM3Render_FastFill_Enable (1<<3) +# define PM3Render_Primitive_Line (0<<6) +# define PM3Render_Primitive_Trapezoid (1<<6) +# define PM3Render_Primitive_Point (2<<6) +# define PM3Render_Antialias_Disable (0<<8) +# define PM3Render_Antialias_Enable (1<<8) +# define PM3Render_Antialias_SubPixelRes_4x4 (0<<9) +# define PM3Render_Antialias_SubPixelRes_8x8 (1<<9) +# define PM3Render_UsePointTable_Disable (0<<10) +# define PM3Render_UsePointTable_Enable (1<<10) +# define PM3Render_SyncOnbitMask_Disable (0<<11) +# define PM3Render_SyncOnBitMask_Enable (1<<11) +# define PM3Render_SyncOnHostData_Disable (0<<12) +# define PM3Render_SyncOnHostData_Enable (1<<12) +# define PM3Render_Texture_Disable (0<<13) +# define PM3Render_Texture_Enable (1<<13) +# define PM3Render_Fog_Disable (0<<14) +# define PM3Render_Fog_Enable (1<<14) +# define PM3Render_Coverage_Disable (0<<15) +# define PM3Render_Coverage_Enable (1<<15) +# define PM3Render_SubPixelCorrection_Disable (0<<16) +# define PM3Render_SubPixelCorrection_Enable (1<<16) +# define PM3Render_SpanOperation_Disable (0<<18) +# define PM3Render_SpanOperation_Enable (1<<18) +# define PM3Render_FBSourceRead_Disable (0<<27) +# define PM3Render_FBSourceRead_Enable (1<<27) #define PM3RasterizerMode 0x80a0 #define PM3RasterizerModeAnd 0xaba0 #define PM3RasterizerModeOr 0xabb8 @@ -922,13 +922,13 @@ #define PM3TextureMapSize 0xb428 #define PM3TextureMapWidth0 0x8580 #define PM3TextureMapWidth1 0x8588 - #define PM3TextureMapWidth_Width(w) ((w&0xfff)<<0) - #define PM3TextureMapWidth_BorderLayout (1<<12) - #define PM3TextureMapWidth_Layout_Linear (0<<13) - #define PM3TextureMapWidth_Layout_Patch64 (1<<13) - #define PM3TextureMapWidth_Layout_Patch32_2 (2<<13) - #define PM3TextureMapWidth_Layout_Patch2 (3<<13) - #define PM3TextureMapWidth_HostTexture (1<<15) +# define PM3TextureMapWidth_Width(w) ((w&0xfff)<<0) +# define PM3TextureMapWidth_BorderLayout (1<<12) +# define PM3TextureMapWidth_Layout_Linear (0<<13) +# define PM3TextureMapWidth_Layout_Patch64 (1<<13) +# define PM3TextureMapWidth_Layout_Patch32_2 (2<<13) +# define PM3TextureMapWidth_Layout_Patch2 (3<<13) +# define PM3TextureMapWidth_HostTexture (1<<15) #define PM3TextureReadMode0 0xb400 #define PM3TextureReadMode0And 0xac30 #define PM3TextureReadMode0Or 0xac38 @@ -938,12 +938,12 @@ /* ... */ #define PM3WaitForCompletion 0x80b8 #define PM3Window 0x8980 - #define PM3Window_ForceLBUpdate 1<<3 - #define PM3Window_LBUpdateSource 1<<4 - #define PM3Window_FrameCount(c) (((c)&0xff)<<9 - #define PM3Window_StencilFCP 1<<17 - #define PM3Window_DepthFCP 1<<18 - #define PM3Window_OverrideWriteFiltering 1<<19 +# define PM3Window_ForceLBUpdate 1<<3 +# define PM3Window_LBUpdateSource 1<<4 +# define PM3Window_FrameCount(c) (((c)&0xff)<<9 +# define PM3Window_StencilFCP 1<<17 +# define PM3Window_DepthFCP 1<<18 +# define PM3Window_OverrideWriteFiltering 1<<19 #define PM3WindowAnd 0xab80 #define PM3WindowOr 0xab88 #define PM3WindowOrigin 0x81c8 @@ -961,58 +961,58 @@ * GLINT Permedia3 2D setup Unit * ***********************************************/ #define PM3Config2D 0xb618 - #define PM3Config2D_OpaqueSpan 1<<0 - #define PM3Config2D_MultiRXBlit 1<<1 - #define PM3Config2D_UserScissorEnable 1<<2 - #define PM3Config2D_FBDestReadEnable 1<<3 - #define PM3Config2D_AlphaBlendEnable 1<<4 - #define PM3Config2D_DitherEnable 1<<5 - #define PM3Config2D_ForegroundROPEnable 1<<6 - #define PM3Config2D_ForegroundROP(rop) (((rop)&0xf)<<7) - #define PM3Config2D_BackgroundROPEnable 1<<11 - #define PM3Config2D_BackgroundROP(rop) (((rop)&0xf)<<12) - #define PM3Config2D_UseConstantSource 1<<16 - #define PM3Config2D_FBWriteEnable 1<<17 - #define PM3Config2D_Blocking 1<<18 - #define PM3Config2D_ExternalSourceData 1<<19 - #define PM3Config2D_LUTModeEnable 1<<20 +# define PM3Config2D_OpaqueSpan 1<<0 +# define PM3Config2D_MultiRXBlit 1<<1 +# define PM3Config2D_UserScissorEnable 1<<2 +# define PM3Config2D_FBDestReadEnable 1<<3 +# define PM3Config2D_AlphaBlendEnable 1<<4 +# define PM3Config2D_DitherEnable 1<<5 +# define PM3Config2D_ForegroundROPEnable 1<<6 +# define PM3Config2D_ForegroundROP(rop) (((rop)&0xf)<<7) +# define PM3Config2D_BackgroundROPEnable 1<<11 +# define PM3Config2D_BackgroundROP(rop) (((rop)&0xf)<<12) +# define PM3Config2D_UseConstantSource 1<<16 +# define PM3Config2D_FBWriteEnable 1<<17 +# define PM3Config2D_Blocking 1<<18 +# define PM3Config2D_ExternalSourceData 1<<19 +# define PM3Config2D_LUTModeEnable 1<<20 #define PM3DownloadGlyphwidth 0xb658 - #define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw)&0xffff) +# define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw)&0xffff) #define PM3DownloadTarget 0xb650 - #define PM3DownloadTarget_TagName(tag) ((tag)&0x1fff) +# define PM3DownloadTarget_TagName(tag) ((tag)&0x1fff) #define PM3GlyphData 0xb660 #define PM3GlyphPosition 0xb608 - #define PM3GlyphPosition_XOffset(x) ((x)&0xffff) - #define PM3GlyphPosition_YOffset(y) (((y)&0xffff)<<16) +# define PM3GlyphPosition_XOffset(x) ((x)&0xffff) +# define PM3GlyphPosition_YOffset(y) (((y)&0xffff)<<16) #define PM3Packed4Pixels 0xb668 #define PM3Packed8Pixels 0xb630 #define PM3Packed16Pixels 0xb638 #define PM3RectanglePosition 0xb600 - #define PM3RectanglePosition_XOffset(x) ((x)&0xffff) - #define PM3RectanglePosition_YOffset(y) (((y)&0xffff)<<16) +# define PM3RectanglePosition_XOffset(x) ((x)&0xffff) +# define PM3RectanglePosition_YOffset(y) (((y)&0xffff)<<16) #define PM3Render2D 0xb640 - #define PM3Render2D_Width(w) ((w)&0x0fff) - #define PM3Render2D_Operation_Normal 0<<12 - #define PM3Render2D_Operation_SyncOnHostData 1<<12 - #define PM3Render2D_Operation_SyncOnBitMask 2<<12 - #define PM3Render2D_Operation_PatchOrderRendering 3<<12 - #define PM3Render2D_FBSourceReadEnable 1<<14 - #define PM3Render2D_SpanOperation 1<<15 - #define PM3Render2D_Height(h) (((h)&0x0fff)<<16) - #define PM3Render2D_XPositive 1<<28 - #define PM3Render2D_YPositive 1<<29 - #define PM3Render2D_AreaStippleEnable 1<<30 - #define PM3Render2D_TextureEnable 1<<31 +# define PM3Render2D_Width(w) ((w)&0x0fff) +# define PM3Render2D_Operation_Normal 0<<12 +# define PM3Render2D_Operation_SyncOnHostData 1<<12 +# define PM3Render2D_Operation_SyncOnBitMask 2<<12 +# define PM3Render2D_Operation_PatchOrderRendering 3<<12 +# define PM3Render2D_FBSourceReadEnable 1<<14 +# define PM3Render2D_SpanOperation 1<<15 +# define PM3Render2D_Height(h) (((h)&0x0fff)<<16) +# define PM3Render2D_XPositive 1<<28 +# define PM3Render2D_YPositive 1<<29 +# define PM3Render2D_AreaStippleEnable 1<<30 +# define PM3Render2D_TextureEnable 1<<31 #define PM3Render2DGlyph 0xb648 - #define PM3Render2DGlyph_Width(w) ((w)&0x7f) - #define PM3Render2DGlyph_Height(h) (((h)&0x7f)<<7) - #define PM3Render2DGlyph_XOffset(x) (((x)&0x1ff)<<14) - #define PM3Render2DGlyph_YOffset(y) (((y)&0x1ff)<<23) +# define PM3Render2DGlyph_Width(w) ((w)&0x7f) +# define PM3Render2DGlyph_Height(h) (((h)&0x7f)<<7) +# define PM3Render2DGlyph_XOffset(x) (((x)&0x1ff)<<14) +# define PM3Render2DGlyph_YOffset(y) (((y)&0x1ff)<<23) #define PM3RenderPatchOffset 0xb610 - #define PM3RenderPatchOffset_XOffset(x) ((x)&0xffff) - #define PM3RenderPatchOffset_YOffset(y) (((y)&0xffff)<<16) +# define PM3RenderPatchOffset_XOffset(x) ((x)&0xffff) +# define PM3RenderPatchOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3RLCount 0xb678 - #define PM3RLCount_Count(c) ((c)&0x0fff) +# define PM3RLCount_Count(c) ((c)&0x0fff) #define PM3RLData 0xb670 /********************************************** @@ -1021,35 +1021,35 @@ #define PM3FillBackgroundColor 0x8330 #define PM3FillConfig2D0 0x8338 #define PM3FillConfig2D1 0x8360 - #define PM3FillConfig2D_OpaqueSpan 1<<0 - #define PM3FillConfig2D_MultiRXBlit 1<<1 - #define PM3FillConfig2D_UserScissorEnable 1<<2 - #define PM3FillConfig2D_FBDestReadEnable 1<<3 - #define PM3FillConfig2D_AlphaBlendEnable 1<<4 - #define PM3FillConfig2D_DitherEnable 1<<5 - #define PM3FillConfig2D_ForegroundROPEnable 1<<6 - #define PM3FillConfig2D_ForegroundROP(rop) (((rop)&0xf)<<7) - #define PM3FillConfig2D_BackgroundROPEnable 1<<11 - #define PM3FillConfig2D_BackgroundROP(rop) (((rop)&0xf)<<12) - #define PM3FillConfig2D_UseConstantSource 1<<16 - #define PM3FillConfig2D_FBWriteEnable 1<<17 - #define PM3FillConfig2D_Blocking 1<<18 - #define PM3FillConfig2D_ExternalSourceData 1<<19 - #define PM3FillConfig2D_LUTModeEnable 1<<20 +# define PM3FillConfig2D_OpaqueSpan 1<<0 +# define PM3FillConfig2D_MultiRXBlit 1<<1 +# define PM3FillConfig2D_UserScissorEnable 1<<2 +# define PM3FillConfig2D_FBDestReadEnable 1<<3 +# define PM3FillConfig2D_AlphaBlendEnable 1<<4 +# define PM3FillConfig2D_DitherEnable 1<<5 +# define PM3FillConfig2D_ForegroundROPEnable 1<<6 +# define PM3FillConfig2D_ForegroundROP(rop) (((rop)&0xf)<<7) +# define PM3FillConfig2D_BackgroundROPEnable 1<<11 +# define PM3FillConfig2D_BackgroundROP(rop) (((rop)&0xf)<<12) +# define PM3FillConfig2D_UseConstantSource 1<<16 +# define PM3FillConfig2D_FBWriteEnable 1<<17 +# define PM3FillConfig2D_Blocking 1<<18 +# define PM3FillConfig2D_ExternalSourceData 1<<19 +# define PM3FillConfig2D_LUTModeEnable 1<<20 #define PM3FillFBDestReadBufferAddr 0x8310 #define PM3FillFBSourceReadBufferAddr 0x8308 #define PM3FillFBSourceReadBufferOffset 0x8340 - #define PM3FillFBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) - #define PM3FillFBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) +# define PM3FillFBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) +# define PM3FillFBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3FillFBWriteBufferAddr 0x8300 #define PM3FillForegroundColor0 0x8328 #define PM3FillForegroundColor1 0x8358 #define PM3FillGlyphPosition 0x8368 - #define PM3FillGlyphPosition_XOffset(x) ((x)&0xffff) - #define PM3FillGlyphPosition_YOffset(y) (((y)&0xffff)<<16) +# define PM3FillGlyphPosition_XOffset(x) ((x)&0xffff) +# define PM3FillGlyphPosition_YOffset(y) (((y)&0xffff)<<16) #define PM3FillRectanglePosition 0x8348 - #define PM3FillRectanglePosition_XOffset(x) ((x)&0xffff) - #define PM3FillRectanglePosition_YOffset(y) (((y)&0xffff)<<16) +# define PM3FillRectanglePosition_XOffset(x) ((x)&0xffff) +# define PM3FillRectanglePosition_YOffset(y) (((y)&0xffff)<<16) #if 0 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i128/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/i128/Imakefile index 30bd22e5e..8c6de7ccb 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i128/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/i128/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/Imakefile,v 1.4 2001/01/24 00:06:19 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/Imakefile,v 1.5 2003/02/17 17:06:42 dawes Exp $ XCOMM XCOMM This is the Imakefile for the I128 driver. XCOMM @@ -20,7 +20,7 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/fb \ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC) \ - -I$(XF86OSSRC)/vbe $(DRIINCLUDES) -I$(SERVERSRC)/render + -I$(XF86SRC)/vbe $(DRIINCLUDES) -I$(SERVERSRC)/render #endif DEFINES = $(DRIDEFINES) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c index 454d1e66a..0cd103697 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c @@ -22,7 +22,7 @@ * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c,v 1.27 2002/06/07 20:45:39 robin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c,v 1.29 2003/02/17 16:08:28 dawes Exp $ */ /* All drivers should typically include these */ @@ -217,6 +217,7 @@ static const char *i2cSymbols[] = { NULL }; +#ifdef XFree86LOADER /* XXX The vbe module isn't currently loaded. */ static const char *vbeSymbols[] = { "VBEInit", @@ -230,6 +231,7 @@ static const char *int10Symbols[] = { "xf86FreeInt10", NULL }; +#endif #ifdef XFree86LOADER @@ -1076,7 +1078,7 @@ I128PreInit(ScrnInfoPtr pScrn, int flags) * Setup the ClockRanges, which describe what clock ranges are available, * and what sort of modes they can be used for. */ - clockRanges = xnfalloc(sizeof(ClockRange)); + clockRanges = xnfcalloc(sizeof(ClockRange),1); clockRanges->next = NULL; clockRanges->minClock = pI128->minClock; clockRanges->maxClock = pI128->maxClock; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c index 6b32011e0..d1a3bb4f6 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c,v 1.7 2000/12/06 01:07:34 robin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c,v 1.8 2003/02/17 16:08:28 dawes Exp $ */ /* * Copyright 1997-2000 by Robin Cutshaw <robin@XFree86.Org> @@ -38,7 +38,6 @@ #include "i128.h" #include "i128reg.h" -void I128EngineDone(ScrnInfoPtr pScrn); void I128BitBlit(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h); void I128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile index d9d365189..a4ede463d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile,v 1.21 2002/09/12 04:08:25 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile,v 1.25 2003/02/17 17:06:42 dawes Exp $ XCOMM XCOMM This is the Imakefile for the i810 driver. XCOMM @@ -27,7 +27,7 @@ DRISRCS = $(I810DRISRCS) $(I830DRISRCS) DRIOBJS = $(I810DRIOBJS) $(I830DRIOBJS) DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \ -I$(XF86OSSRC)/linux/drm/kernel -I$(TOP)/include -DRIDEFINES = $(GLX_DEFINES) $(DRMCOMMANDDEFINES) +DRIDEFINES = $(GLX_DEFINES) #endif #if I830XvSupport @@ -35,7 +35,6 @@ I830SRCS1 = i830_video.c I830OBJS1 = i830_video.o #endif - #if !I830Only I810SRCS = i810_cursor.c i810_accel.c i810_memory.c i810_wmark.c i810_dga.c \ i810_video.c i810_io.c @@ -67,9 +66,10 @@ INCLUDES = -I. -I../../include INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ -I$(XF86SRC)/xaa -I$(XF86SRC)/rac \ + -I$(SERVERSRC)/miext/shadow \ -I$(SERVERSRC)/fb -I$(XF86SRC)/xaa -I$(XF86SRC)/ramdac \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ - -I$(XF86OSSRC)/vbe -I$(XF86SRC)/int10 \ + -I$(XF86SRC)/vbe -I$(XF86SRC)/int10 \ -I$(SERVERSRC)/Xext \ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ -I$(EXTINCSRC) -I$(SERVERSRC)/render \ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/common.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/common.h index 2f3b41fec..5e71cad82 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/common.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/common.h @@ -27,7 +27,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/common.h,v 1.1 2002/09/11 00:29:31 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/common.h,v 1.6 2003/02/06 04:18:04 dawes Exp $ */ /* * Authors: @@ -50,11 +50,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef I830DEBUG #define MARKER() ErrorF("\n### %s:%d: >>> %s <<< ###\n\n", \ __FILE__, __LINE__,__FUNCTION__) -#define DPRINTF DPRINTF_stub +#define DPRINTF I830DPRINTF_stub #else /* #ifdef I830DEBUG */ #define MARKER() -/* this is a real ugle hack to get the compiler to optimize the debugging statements into oblivion */ -#define DPRINTF if(0) DPRINTF_stub +/* this is a real ugly hack to get the compiler to optimize the debugging statements into oblivion */ +#define DPRINTF if(0) I830DPRINTF_stub #endif /* #ifdef I830DEBUG */ #define KB(x) ((x) * 1024) @@ -79,9 +79,10 @@ extern const char *I810vbeSymbols[]; extern const char *I810ddcSymbols[]; extern const char *I810fbSymbols[]; extern const char *I810xaaSymbols[]; +extern const char *I810shadowSymbols[]; -extern void DPRINTF_stub(const char *filename, int line, const char *function, - const char *fmt, ...); +extern void I830DPRINTF_stub(const char *filename, int line, + const char *function, const char *fmt, ...); #ifdef _I830_H_ #define PrintErrorState I830PrintErrorState @@ -151,21 +152,71 @@ extern void DPRINTF_stub(const char *filename, int line, const char *function, } while (_head != _tail); \ } while( 0) +/* + * This is for debugging a potential problem writing the tail pointer + * close to the end of the ring buffer. + */ +#ifndef AVOID_TAIL_END +#define AVOID_TAIL_END 0 +#endif +#ifndef AVOID_SIZE +#define AVOID_SIZE 64 +#endif + +#if AVOID_TAIL_END + #define BEGIN_LP_RING(n) \ unsigned int outring, ringmask; \ volatile unsigned char *virt; \ + unsigned int needed; \ if ((n) & 1) \ ErrorF("BEGIN_LP_RING called with odd argument: %d\n", n); \ if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \ DO_RING_IDLE(); \ - if (RecPtr->LpRing.space < (n) * 4) \ - WaitRingFunc(pScrn, (n) * 4, 0); \ - RecPtr->LpRing.space -= (n) * 4; \ + needed = (n) * 4; \ + if ((RecPtr->LpRing.tail > RecPtr->LpRing.tail_mask - AVOID_SIZE) || \ + (RecPtr->LpRing.tail + needed) > \ + RecPtr->LpRing.tail_mask - AVOID_SIZE) { \ + needed += RecPtr->LpRing.tail_mask + 1 - RecPtr->LpRing.tail; \ + ErrorF("BEGIN_LP_RING: skipping last 64 bytes of " \ + "ring (%d vs %d)\n", needed, (n) * 4); \ + } \ + if (RecPtr->LpRing.space < needed) \ + WaitRingFunc(pScrn, needed, 0); \ + RecPtr->LpRing.space -= needed; \ + outring = RecPtr->LpRing.tail; \ + ringmask = RecPtr->LpRing.tail_mask; \ + virt = RecPtr->LpRing.virtual_start; \ + while (needed > (n) * 4) { \ + ErrorF("BEGIN_LP_RING: putting MI_NOOP at 0x%x (remaining %d)\n", \ + outring, needed - (n) * 4); \ + OUT_RING(MI_NOOP); \ + needed -= 4; \ + } \ if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME); \ + ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME); + +#else /* AVOID_TAIL_END */ + +#define BEGIN_LP_RING(n) \ + unsigned int outring, ringmask; \ + volatile unsigned char *virt; \ + unsigned int needed; \ + if ((n) & 1) \ + ErrorF("BEGIN_LP_RING called with odd argument: %d\n", n); \ + if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \ + DO_RING_IDLE(); \ + needed = (n) * 4; \ + if (RecPtr->LpRing.space < needed) \ + WaitRingFunc(pScrn, needed, 0); \ + RecPtr->LpRing.space -= needed; \ outring = RecPtr->LpRing.tail; \ ringmask = RecPtr->LpRing.tail_mask; \ - virt = RecPtr->LpRing.virtual_start; + virt = RecPtr->LpRing.virtual_start; \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME); + +#endif /* AVOID_TAIL_END */ /* Memory mapped register access macros */ @@ -195,7 +246,7 @@ extern void DPRINTF_stub(const char *filename, int line, const char *function, } while (0) /* To remove all debugging, make sure I810_DEBUG is defined as a - * preprocessor symbol, and equal to zero. + * preprocessor symbol, and equal to zero. */ #if 1 #define I810_DEBUG 0 @@ -231,6 +282,15 @@ extern int I810_DEBUG; #define PCI_CHIP_I815_BRIDGE 0x1130 #endif +#ifndef PCI_CHIP_I855_GM +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I855_GM_BRIDGE 0x3580 +#endif + +#ifndef PCI_CHIP_I865_G +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I865_G_BRIDGE 0x2570 +#endif #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 || \ pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \ @@ -238,14 +298,17 @@ extern int I810_DEBUG; #define IS_I815(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I815) #define IS_I830(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I830_M) #define IS_845G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_845_G) -#define IS_MOBILE(pI810) IS_I830(pI810) +#define IS_I85X(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM) +#define IS_I865G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I865_G) + +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810)) #define GTT_PAGE_SIZE KB(4) #define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) #define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) #define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) #define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) -#define PRIMARY_RINGBUFFER_SIZE KB(64) +#define PRIMARY_RINGBUFFER_SIZE KB(128) #define MIN_SCRATCH_BUFFER_SIZE KB(16) #define MAX_SCRATCH_BUFFER_SIZE KB(64) #define HWCURSOR_SIZE GTT_PAGE_SIZE @@ -259,4 +322,6 @@ extern int I810_DEBUG; #define MAX_DISPLAY_PITCH 2048 #define MAX_DISPLAY_HEIGHT 2048 +#define PIPE_NAME(n) ('A' + (n)) + #endif /* _INTEL_COMMON_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h index a7d1df4d8..128b659a2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h @@ -27,7 +27,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h,v 1.33 2002/10/08 20:15:46 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h,v 1.38 2003/02/26 04:19:36 dawes Exp $ */ /* * Authors: @@ -36,8 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -#define I830DEBUG - #ifndef _I810_H_ #define _I810_H_ @@ -69,9 +67,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I810_NAME "I810" #define I810_DRIVER_NAME "i810" #define I810_MAJOR_VERSION 1 -#define I810_MINOR_VERSION 1 +#define I810_MINOR_VERSION 3 #define I810_PATCHLEVEL 0 + /* HWMC Surfaces */ #define I810_MAX_SURFACES 7 #define I810_MAX_SUBPICTURES 2 @@ -250,6 +249,9 @@ typedef struct _I810Rec { OptionInfoPtr Options; int configured_device; + + Bool showCache; + Bool noAccel; } I810Rec; #define I810PTR(p) ((I810Ptr)((p)->driverPrivate)) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c index 02a921b51..17c24b375 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c @@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c,v 1.14 2002/10/08 20:15:46 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c,v 1.17 2002/11/25 14:04:59 eich Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: @@ -50,7 +50,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86.h" #include "i810.h" -#include "i810_reg.h" static unsigned int i810Rop[16] = { 0x00, /* GXclear */ @@ -390,42 +389,60 @@ void I810SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) { - I810Ptr pI810 = I810PTR(pScrn); - int src, dst; - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - ErrorF("I810SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n", - x1, y1, x2, y2, w, h); - - if (pI810->BR[13] & BR13_PITCH_SIGN_BIT) { - src = (y1 + h - 1) * pScrn->displayWidth * pI810->cpp; - dst = (y2 + h - 1) * pScrn->displayWidth * pI810->cpp; - } else { - src = y1 * pScrn->displayWidth * pI810->cpp; - dst = y2 * pScrn->displayWidth * pI810->cpp; - } - - if (pI810->BR[13] & BR13_RIGHT_TO_LEFT) { - src += (x1 + w - 1) * pI810->cpp + pI810->cpp - 1; - dst += (x2 + w - 1) * pI810->cpp + pI810->cpp - 1; - } else { - src += x1 * pI810->cpp; - dst += x2 * pI810->cpp; - } - - /* SRC_COPY_BLT, p169 */ - { - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); - OUT_RING(pI810->BR[13]); - - OUT_RING((h << 16) | (w * pI810->cpp)); - OUT_RING(pI810->bufferOffset + dst); - - OUT_RING(pI810->BR[13] & 0xFFFF); - OUT_RING(pI810->bufferOffset + src); - ADVANCE_LP_RING(); - } + I810Ptr pI810 = I810PTR(pScrn); + int src, dst; + int w_back = w; + + if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) + ErrorF( "I810SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n", + x1,y1,x2,y2,w,h); + /* + * This works around a bug in the i810 drawing engine. + * This was developed empirically so it may not catch all + * cases. + */ + if ( !(pI810->BR[13] & BR13_RIGHT_TO_LEFT) && (y2 - y1) < 3 + && (y2 - y1) >= 0 && (x2 - x1) <= (w + 4) && (w > 4)) + w = 4; + do { + + if (pI810->BR[13] & BR13_PITCH_SIGN_BIT) { + src = (y1 + h - 1) * pScrn->displayWidth * pI810->cpp; + dst = (y2 + h - 1) * pScrn->displayWidth * pI810->cpp; + } else { + src = y1 * pScrn->displayWidth * pI810->cpp; + dst = y2 * pScrn->displayWidth * pI810->cpp; + } + + if (pI810->BR[13] & BR13_RIGHT_TO_LEFT) { + src += (x1 + w - 1) * pI810->cpp + pI810->cpp - 1; + dst += (x2 + w - 1) * pI810->cpp + pI810->cpp - 1; + } else { + src += x1 * pI810->cpp; + dst += x2 * pI810->cpp; + } + + + /* SRC_COPY_BLT, p169 */ + { + BEGIN_LP_RING(6); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); + OUT_RING( pI810->BR[13]); + + OUT_RING( (h << 16) | (w * pI810->cpp)); + OUT_RING( pI810->bufferOffset + dst); + + OUT_RING( pI810->BR[13] & 0xFFFF); + OUT_RING( pI810->bufferOffset + src); + ADVANCE_LP_RING(); + } + w_back -= w; + if (w_back <= 0) + break; + x2 += w; + x1 += w; + w = w_back; + } while (1); } static void diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h index 25206b493..2a2e21a57 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h @@ -25,7 +25,7 @@ * Converted to common header format: * Jens Owen <jens@tungstengraphics.com> * - * $XFree86$ + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h,v 1.1 2002/09/11 00:29:31 dawes Exp $ * */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_cursor.c index 34e076615..26023f3f9 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_cursor.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_cursor.c @@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_cursor.c,v 1.6 2002/09/11 00:29:31 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_cursor.c,v 1.7 2002/10/30 12:52:17 alanh Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c index a25fc06ea..0abac2bff 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c @@ -34,7 +34,7 @@ * with <TAB> characters expanded at 8-column intervals. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c,v 1.5 2002/09/11 00:29:31 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c,v 1.6 2003/02/26 04:19:36 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -108,7 +108,7 @@ I810DGAInit(ScreenPtr pScreen) currentMode->mode = pMode; currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; - if (pI810->AccelInfoRec) + if (!pI810->noAccel) currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; if (pMode->Flags & V_DBLSCAN) currentMode->flags |= DGA_DOUBLESCAN; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c index 7b1fd4a65..8daeaeac8 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c,v 1.29 2002/10/08 22:14:08 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c,v 1.33 2002/12/10 01:27:04 dawes Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: * @@ -375,7 +375,6 @@ I810DRIScreenInit(ScreenPtr pScreen) { drmVersionPtr version; -#if defined(XFree86LOADER) /* Check the DRM lib version. * drmGetLibVersion was not supported in version 1.0, so check for * symbol first to avoid possible crash or hang. @@ -383,7 +382,6 @@ I810DRIScreenInit(ScreenPtr pScreen) if (xf86LoaderCheckSymbol("drmGetLibVersion")) { version = drmGetLibVersion(pI810->drmSubFD); } else -#endif { /* drmlib version 1.0.0 didn't have the drmGetLibVersion * entry point. Fake it by allocating a version record @@ -395,16 +393,19 @@ I810DRIScreenInit(ScreenPtr pScreen) version->version_patchlevel = 0; } +#define REQ_MAJ 1 +#define REQ_MIN 1 if (version) { - if (version->version_major != 1 || - version->version_minor < 1) { + if (version->version_major != REQ_MAJ || + version->version_minor < REQ_MIN) { /* incompatible drm library version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed because of a version mismatch.\n" - "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n" "[dri] Disabling DRI.\n", version->version_major, - version->version_minor, version->version_patchlevel); + version->version_minor, version->version_patchlevel, + REQ_MAJ, REQ_MIN); drmFreeVersion(version); I810DRICloseScreen(pScreen); return FALSE; @@ -1016,6 +1017,8 @@ I810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("I810DRISwapContext (in)\n"); + if (!pScrn->vtSema) + return; pI810->LockHeld = 1; I810RefreshRing(pScrn); } else if (syncType == DRI_2D_SYNC && diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h index f7f0261f3..cf0532cb5 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h,v 1.8 2002/10/08 20:15:46 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h,v 1.10 2002/12/10 01:27:04 dawes Exp $ */ #ifndef _I810_DRI_ #define _I810_DRI_ @@ -93,7 +93,7 @@ typedef struct { * texture space, and can make informed decisions as to which * areas to kick out. There is no need to choose whether to * kick out your own texture or someone else's - simply eject - * them all in LRU order. + * them all in LRU order. */ I810TexRegionRec texList[I810_NR_TEX_REGIONS + 1]; /* Last elt is sentinal */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c index b8e203897..a057f0d7d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c @@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c,v 1.71 2002/09/11 00:29:32 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c,v 1.80 2003/02/26 04:19:36 dawes Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: @@ -122,6 +122,8 @@ static SymTabRec I810Chipsets[] = { #endif {PCI_CHIP_I830_M, "i830M"}, {PCI_CHIP_845_G, "845G"}, + {PCI_CHIP_I855_GM, "852GM/855GM"}, + {PCI_CHIP_I865_G, "865G"}, {-1, NULL} }; @@ -134,6 +136,8 @@ static PciChipsets I810PciChipsets[] = { #endif {PCI_CHIP_I830_M, PCI_CHIP_I830_M, RES_SHARED_VGA}, {PCI_CHIP_845_G, PCI_CHIP_845_G, RES_SHARED_VGA}, + {PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, RES_SHARED_VGA}, + {PCI_CHIP_I865_G, PCI_CHIP_I865_G, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED } }; @@ -146,6 +150,7 @@ typedef enum { OPTION_DAC_6BIT, OPTION_DRI, OPTION_NO_DDC, + OPTION_SHOW_CACHE, OPTION_XVMC_SURFACES } I810Opts; @@ -157,6 +162,7 @@ static const OptionInfoRec I810Options[] = { {OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SHOW_CACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_XVMC_SURFACES, "XvMCSurfaces", OPTV_INTEGER, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -168,7 +174,6 @@ const char *I810vgahwSymbols[] = { "vgaHWGetHWRec", "vgaHWGetIOBase", "vgaHWGetIndex", - "vgaHWHandleColormaps", "vgaHWInit", "vgaHWLock", "vgaHWMapMem", @@ -189,15 +194,25 @@ const char *I810fbSymbols[] = { }; const char *I810vbeSymbols[] = { - "VBEInit", - "vbeDoEDID", - "vbeFree", - "VBEFindSupportedDepths", + "VBEFreeModeInfo", + "VBEFreeVBEInfo", + "VBEGetModeInfo", "VBEGetModePool", + "VBEGetVBEInfo", + "VBEGetVBEMode", + "VBEInit", + "VBEPrintModes", + "VBESaveRestore", + "VBESetDisplayStart", + "VBESetGetDACPaletteFormat", + "VBESetGetLogicalScanlineLength", + "VBESetGetPaletteData", "VBESetModeNames", "VBESetModeParameters", + "VBESetVBEMode", "VBEValidateModes", - "VBEPrintModes", + "vbeDoEDID", + "vbeFree", NULL }; @@ -224,14 +239,10 @@ const char *I810int10Symbols[] = { }; const char *I810xaaSymbols[] = { - "XAACachePlanarMonoStipple", "XAACreateInfoRec", "XAADestroyInfoRec", "XAAFillSolidRects", "XAAInit", - "XAAOverlayFBfuncs", - "XAAScreenIndex", - "XAAStippleScanlineFuncLSBFirst", NULL }; @@ -254,12 +265,8 @@ static const char *drmSymbols[] = { "drmAgpEnable", "drmAgpFree", "drmAgpRelease", - "drmAvailable", "drmAuthMagic", - "drmCommandNone", - "drmCommandRead", "drmCommandWrite", - "drmCommandWriteRead", "drmCreateContext", "drmCtlInstHandler", "drmCtlUninstHandler", @@ -268,20 +275,15 @@ static const char *drmSymbols[] = { "drmGetInterruptFromBusID", "drmGetLibVersion", "drmGetVersion", - "drmI810CleanupDma", - "drmI810InitDma", - "drmI830CleanupDma", - "drmI830InitDma", NULL }; + static const char *driSymbols[] = { "DRICloseScreen", "DRICreateInfoRec", "DRIDestroyInfoRec", "DRIFinishScreenInit", - "DRIGetContext", - "DRIGetDrawableIndex", "DRIGetSAREAPrivate", "DRILock", "DRIQueryVersion", @@ -290,7 +292,17 @@ static const char *driSymbols[] = { "GlxSetVisualConfigs", NULL }; + +#endif #endif + +#ifdef XF86DRI +const char *I810shadowSymbols[] = { + "shadowInit", + "shadowSetup", + "shadowAdd", + NULL +}; #endif #endif /* I830_ONLY */ @@ -344,7 +356,7 @@ i810Setup(pointer module, pointer opts, int *errmaj, int *errmin) { static Bool setupDone = 0; - /* This module should be loaded only once, but check to be sure. + /* This module should be loaded only once, but check to be sure. */ if (!setupDone) { setupDone = 1; @@ -357,7 +369,9 @@ i810Setup(pointer module, pointer opts, int *errmaj, int *errmin) LoaderRefSymLists(I810vgahwSymbols, I810fbSymbols, I810xaaSymbols, I810ramdacSymbols, #ifdef XF86DRI - drmSymbols, driSymbols, + drmSymbols, + driSymbols, + I810shadowSymbols, #endif I810vbeSymbols, vbeOptionalSymbols, I810ddcSymbols, I810int10Symbols, NULL); @@ -380,7 +394,7 @@ i810Setup(pointer module, pointer opts, int *errmaj, int *errmin) /* * I810GetRec and I810FreeRec -- * - * Private data for the driver is stored in the screen structure. + * Private data for the driver is stored in the screen structure. * These two functions create and destroy that private data. * */ @@ -411,12 +425,12 @@ I810FreeRec(ScrnInfoPtr pScrn) * * Returns the string name for the driver based on the chipset. In this * case it will always be an I810, so we can return a static string. - * + * */ static void I810Identify(int flags) { - xf86PrintChipsets(I810_NAME, "Driver for Intel i810 chipset", + xf86PrintChipsets(I810_NAME, "Driver for Intel Integrated Graphics Chipsets", I810Chipsets); } @@ -460,7 +474,7 @@ I810Probe(DriverPtr drv, int flags) return FALSE; } - /* + /* * This probing is just checking the PCI data the server already * collected. */ @@ -519,11 +533,15 @@ I810Probe(DriverPtr drv, int flags) pScrn->name = I810_NAME; pScrn->Probe = I810Probe; foundScreen = TRUE; - if (pEnt->chipset == PCI_CHIP_I830_M || - pEnt->chipset == PCI_CHIP_845_G) + switch (pEnt->chipset) { + case PCI_CHIP_I830_M: + case PCI_CHIP_845_G: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: I830InitpScrn(pScrn); - else { + break; #ifndef I830_ONLY + default: pScrn->PreInit = I810PreInit; pScrn->ScreenInit = I810ScreenInit; pScrn->SwitchMode = I810SwitchMode; @@ -532,6 +550,7 @@ I810Probe(DriverPtr drv, int flags) pScrn->LeaveVT = I810LeaveVT; pScrn->FreeScreen = I810FreeScreen; pScrn->ValidMode = I810ValidMode; + break; #endif } } @@ -696,6 +715,11 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) if (xf86ReturnOptValBool(pI810->Options, OPTION_DAC_6BIT, FALSE)) pScrn->rgbBits = 6; + if (xf86ReturnOptValBool(pI810->Options, OPTION_SHOW_CACHE, FALSE)) + pI810->showCache = TRUE; + else + pI810->showCache = FALSE; + /* 6-BIT dac isn't reasonable for modes with > 8bpp */ if (xf86ReturnOptValBool(pI810->Options, OPTION_DAC_6BIT, FALSE) && pScrn->bitsPerPixel > 8) { @@ -801,7 +825,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) /* Default to 4MB framebuffer, which is sufficient for all * supported 2d resolutions. If the user has specified a different * size in the XF86Config, use that amount instead. - * + * * Changed to 8 Meg so we can have acceleration by default (Mark). */ pScrn->videoRam = 8192; @@ -942,7 +966,10 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) } xf86LoaderReqSymLists(I810fbSymbols, NULL); - if (!xf86ReturnOptValBool(pI810->Options, OPTION_NOACCEL, FALSE)) { + if (xf86ReturnOptValBool(pI810->Options, OPTION_NOACCEL, FALSE)) + pI810->noAccel = TRUE; + + if (!pI810->noAccel) { if (!xf86LoadSubModule(pScrn, "xaa")) { I810FreeRec(pScrn); return FALSE; @@ -1118,7 +1145,7 @@ DoSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, I810RegPtr i810Reg, vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP); /* - * The port I/O code necessary to read in the extended registers + * The port I/O code necessary to read in the extended registers * into the fields of the vgaI810Rec structure goes here. */ i810Reg->IOControl = hwp->readCrtc(hwp, IO_CTNL); @@ -1289,7 +1316,7 @@ DoRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, I810RegPtr i810Reg, /* * Code to restore any SVGA registers that have been saved/modified - * goes here. Note that it is allowable, and often correct, to + * goes here. Note that it is allowable, and often correct, to * only modify certain bits in a register by a read/modify/write cycle. * * A special case - when using an external clock-setting program, @@ -1323,9 +1350,17 @@ DoRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, I810RegPtr i810Reg, pI810->writeControl(pI810, GRX, ADDRESS_MAPPING, temp); /* Setting the OVRACT Register for video overlay */ - OUTREG(0x6001C, - (i810Reg->OverlayActiveEnd << 16) | i810Reg->OverlayActiveStart); - + { + CARD32 LCD_TV_Control = INREG(LCD_TV_C); + + if(!(LCD_TV_Control & LCD_TV_ENABLE) + || (LCD_TV_Control & LCD_TV_VGAMOD)) { + OUTREG(LCD_TV_OVRACT, + (i810Reg->OverlayActiveEnd << 16) + | i810Reg->OverlayActiveStart); + } + } + /* Turn on DRAM Refresh */ temp = INREG8(DRAM_ROW_CNTL_HI); temp &= ~DRAM_REFRESH_RATE; @@ -1828,7 +1863,7 @@ I810AllocateFront(ScrnInfoPtr pScrn) * Not sure why 256 was initially subtracted from videoRam in the * maxCacheLines calculation, but that was causing a problem * for configurations that have exactly enough Ram for the framebuffer. - * Common code should catch the case where there isn't enough space for + * Common code should catch the case where there isn't enough space for * framebuffer, we'll just check for no space for cache_lines. -jens * */ @@ -2080,7 +2115,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #ifdef XF86DRI if (pI810->directRenderingEnabled) { - /* Now that mi, cfb, drm and others have done their thing, + /* Now that mi, cfb, drm and others have done their thing, * complete the DRI setup. */ pI810->directRenderingEnabled = I810DRIFinishScreenInit(pScreen); @@ -2126,7 +2161,18 @@ I810AdjustFrame(int scrnIndex, int x, int y, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I810Ptr pI810 = I810PTR(pScrn); vgaHWPtr hwp = VGAHWPTR(pScrn); - int Base = (y * pScrn->displayWidth + x) >> 2; + int Base; +#if 1 + if (pI810->showCache) { + int lastline = pI810->FbMapSize / + ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8); + lastline -= pScrn->currentMode->VDisplay; + if (y > 0) + y += pScrn->currentMode->VDisplay; + if (y > lastline) y = lastline; + } +#endif + Base = (y * pScrn->displayWidth + x) >> 2; if (I810_DEBUG & DEBUG_VERBOSE_CURSOR) ErrorF("I810AdjustFrame %d,%d %x\n", x, y, flags); @@ -2140,7 +2186,7 @@ I810AdjustFrame(int scrnIndex, int x, int y, int flags) case 24: /* KW: Need to do 16-pixel alignment for i810, otherwise you * get bad watermark problems. Need to fixup the mouse - * pointer positioning to take this into account. + * pointer positioning to take this into account. */ pI810->CursorOffset = (Base & 0x3) * 4; Base &= ~0x3; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c index 1f6039a67..5efa23a94 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c,v 1.25 2002/09/11 00:29:32 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c,v 1.27 2002/12/10 01:27:05 dawes Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -218,7 +218,7 @@ I810AllocateGARTMemory(ScrnInfoPtr pScrn) * Need to make it less likely that we miss out on this - probably * need to move the frontbuffer away from the 'guarenteed' alignment * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. + * framebuffer to get more alignment 'sweet spots'. */ void I810SetTiledMemory(ScrnInfoPtr pScrn, int nr, unsigned int start, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_reg.h index 0c25e17df..c935982a7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_reg.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_reg.h,v 1.8 2002/09/12 04:08:25 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_reg.h,v 1.13 2003/02/06 04:18:04 dawes Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -36,7 +36,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* I/O register offsets +#ifndef _I810_REG_H +#define _I810_REG_H + +/* I/O register offsets */ #define SRX 0x3C4 /* p208 */ #define GRX 0x3CE /* p213 */ @@ -147,7 +150,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Cursor control registers, pp383-384 */ -/* Desktop (845G) */ +/* Desktop (845G, 865G) */ #define CURSOR_CONTROL 0x70080 #define CURSOR_ENABLE 0x80000000 #define CURSOR_GAMMA_ENABLE 0x40000000 @@ -610,6 +613,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define CS_USE_CTX0 0 #define CS_USE_CTX1 (1<<0) +/* I810 LCD/TV registers */ +#define LCD_TV_HTOTAL 0x60000 +#define LCD_TV_C 0x60018 +#define LCD_TV_OVRACT 0x6001C + +#define LCD_TV_ENABLE (1 << 31) +#define LCD_TV_VGAMOD (1 << 28) + /* I830 CRTC registers */ #define HTOTAL_A 0x60000 #define HBLANK_A 0x60004 @@ -658,7 +669,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ADPA 0x61100 #define ADPA_DAC_ENABLE (1<<31) #define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) #define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) #define ADPA_USE_VGA_HVPOLARITY (1<<15) #define ADPA_SETS_HVPOLARITY 0 #define ADPA_VSYNC_CNTL_DISABLE (1<<11) @@ -671,12 +684,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ADPA_HSYNC_ACTIVE_LOW 0 -#define DV0A 0x61120 -#define DV0A_DISABLE (1<<31) +#define DVOA 0x61120 +#define DVOB 0x61140 +#define DVOC 0x61160 +#define DVO_ENABLE (1<<31) -#define DV0B 0x61140 -#define DV0B_DISABLE (1<<31) +#define DVOA_SRCDIM 0x61124 +#define DVOB_SRCDIM 0x61144 +#define DVOC_SRCDIM 0x61164 +#define LVDS 0x61180 #define PIPEACONF 0x70008 #define PIPEACONF_ENABLE (1<<31) @@ -777,6 +794,21 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I830_RDRAM_ND(x) (((x) & 0x20) >> 5) #define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3) +#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_DISABLED 0x00 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) + +#define I85X_CAPID 0x44 +#define I85X_VARIANT_MASK 0x7 +#define I85X_VARIANT_SHIFT 5 +#define I855_GME 0x0 +#define I855_GM 0x4 +#define I852_GME 0x2 +#define I852_GM 0x5 /* BLT commands */ #define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3)) @@ -863,18 +895,40 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ENABLE_FOG_DENSITY (1<<23) +#define MAX_DISPLAY_PIPES 2 + +typedef enum { + CrtIndex = 0, + TvIndex, + DfpIndex, + LfpIndex, + Tv2Index, + Dfp2Index, + UnknownIndex, + Unknown2Index, + NumDisplayTypes, + NumKnownDisplayTypes = UnknownIndex +} DisplayType; + /* What's connected to the pipes (as reported by the BIOS) */ #define PIPE_ACTIVE_MASK 0xff -#define PIPE_CRT_ACTIVE 0x01 -#define PIPE_TV_ACTIVE 0x02 -#define PIPE_DFP_ACTIVE 0x04 -#define PIPE_LCD_ACTIVE 0x08 /* LFP */ -#define PIPE_TV2_ACTIVE 0x10 -#define PIPE_DFP2_ACTIVE 0x20 -#define PIPE_UNKNOWN_ACTIVE 0xc0 +#define PIPE_CRT_ACTIVE (1 << CrtIndex) +#define PIPE_TV_ACTIVE (1 << TvIndex) +#define PIPE_DFP_ACTIVE (1 << DfpIndex) +#define PIPE_LCD_ACTIVE (1 << LfpIndex) +#define PIPE_TV2_ACTIVE (1 << Tv2Index) +#define PIPE_DFP2_ACTIVE (1 << Dfp2Index) +#define PIPE_UNKNOWN_ACTIVE ((1 << UnknownIndex) | \ + (1 << Unknown2Index)) + +#define PIPE_SIZED_DISP_MASK (PIPE_DFP_ACTIVE | \ + PIPE_LCD_ACTIVE | \ + PIPE_DFP2_ACTIVE) #define PIPE_A_SHIFT 0 #define PIPE_B_SHIFT 8 +#define PIPE_SHIFT(n) ((n) == 0 ? \ + PIPE_A_SHIFT : PIPE_B_SHIFT) /* * Some BIOS scratch area registers. The 845 (and 830?) store the amount @@ -889,6 +943,28 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SWF5 0x71424 #define SWF6 0x71428 +/* + * 855 scratch registers. + */ +#define SWF00 0x70410 +#define SWF01 0x70414 +#define SWF02 0x70418 +#define SWF03 0x7041c +#define SWF04 0x70420 +#define SWF05 0x70424 +#define SWF06 0x70428 + +#define SWF10 SWF0 +#define SWF11 SWF1 +#define SWF12 SWF2 +#define SWF13 SWF3 +#define SWF14 SWF4 +#define SWF15 SWF5 +#define SWF16 SWF6 + +#define SWF30 0x72414 +#define SWF31 0x72418 +#define SWF32 0x7241c /* * Overlay registers. These are overlay registers accessed via MMIO. @@ -913,3 +989,4 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PALETTE_A 0x0a000 #define PALETTE_B 0x0a800 +#endif /* _I810_REG_H */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_wmark.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_wmark.c index f124e5f1d..9a6bdd349 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_wmark.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_wmark.c @@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_wmark.c,v 1.7 2002/09/11 00:29:32 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_wmark.c,v 1.8 2002/10/30 12:52:18 alanh Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h index 42f2d4224..e141931ac 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h @@ -27,7 +27,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h,v 1.3 2002/10/08 20:15:46 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h,v 1.7 2003/01/28 22:47:09 dawes Exp $ */ /* * Authors: @@ -74,32 +74,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* I830 Video BIOS support */ /* - * The mode handling is based upon the VESA driver written by: - * Paulo César Pereira de Andrade <pcpa@conectiva.com.br> + * The mode handling is based upon the VESA driver written by + * Paulo César Pereira de Andrade <pcpa@conectiva.com.br>. */ typedef struct _VESARec { - vbeInfoPtr pVbe; - VbeInfoBlock *vbeInfo; - pointer state, pstate; /* SVGA state */ + /* SVGA state */ + pointer state, pstate; int statePage, stateSize, stateMode; CARD32 *savedPal; + int savedScanlinePitch; xf86MonPtr monitor; - CARD8 saveSWF1; - CARD8 newSWF1; - Bool overrideBIOSMemSize; - Bool useDefaultRefresh; /* - * Don't try to set the refresh rate - * for any modes. - */ - Bool enableDisplays; /* - * Use BIOS call 0x5f64 to explicitly - * enable displays. - */ - Bool useExtendedRefresh; /* - * Use BIOS call 0x5f05 to set the - * refresh rate. - */ + /* Don't try to set the refresh rate for any modes. */ + Bool useDefaultRefresh; } VESARec, *VESAPtr; @@ -118,7 +105,7 @@ typedef struct _I830MemRange *I830MemRangePtr; typedef struct _I830MemRange { long Start; long End; - unsigned long Size; + long Size; unsigned long Physical; unsigned long Offset; /* Offset of AGP-allocated portion */ unsigned long Alignment; @@ -159,12 +146,14 @@ typedef struct _I830Rec { unsigned long FbMapSize; unsigned long TotalVideoRam; I830MemRange StolenMemory; /* pre-allocated memory */ + unsigned long BIOSMemorySize; /* min stolen pool size */ /* These change according to what has been allocated. */ - unsigned long FreeMemory; + long FreeMemory; I830MemRange MemoryAperture; I830MemPool StolenPool; - + unsigned long allocatedMemory; + /* Regions allocated either from the above pools, or from agpgart. */ I830MemRange FrontBuffer; I830MemRange CursorMem; @@ -187,9 +176,12 @@ typedef struct _I830Rec { I830MemRange BufferMem; I830MemRange ContextMem; int TexGranularity; + int drmMinor; + Bool have3DWindows; #endif Bool NeedRingBufferLow; + Bool allowPageFlip; int auxPitch; int auxPitchBits; @@ -208,6 +200,7 @@ typedef struct _I830Rec { EntityInfoPtr pEnt; pciVideoPtr PciInfo; PCITAG PciTag; + CARD8 variant; unsigned int BR[20]; @@ -222,6 +215,7 @@ typedef struct _I830Rec { Bool noAccel; Bool SWCursor; + Bool cursorOn; XAAInfoRecPtr AccelInfoRec; xf86CursorInfoPtr CursorInfoRec; CloseScreenProcPtr CloseScreen; @@ -232,15 +226,16 @@ typedef struct _I830Rec { I830WriteByteFunc writeStandard; I830ReadByteFunc readStandard; - Bool XvEnabled; /* false if I830_XV not defined. */ + Bool XvDisabled; /* Xv disabled in PreInit. */ + Bool XvEnabled; /* Xv enabled for this generation. */ #ifdef I830_XV int colorKey; XF86VideoAdaptorPtr adaptor; Bool overlayOn; #endif - - Bool directRenderingDisabled; /* DRI disabled always. */ + + Bool directRenderingDisabled; /* DRI disabled in PreInit. */ Bool directRenderingEnabled; /* DRI enabled this generation. */ #ifdef XF86DRI @@ -260,16 +255,46 @@ typedef struct _I830Rec { /* Stolen memory support */ Bool StolenOnly; - /* Video BIOS support */ + /* Video BIOS support. */ + vbeInfoPtr pVbe; + VbeInfoBlock *vbeInfo; VESAPtr vesa; + Bool overrideBIOSMemSize; + int saveBIOSMemSize; + int newBIOSMemSize; + Bool useSWF1; + int saveSWF1; + + Bool swfSaved; + CARD32 saveSWF0; + CARD32 saveSWF4; + + /* Use BIOS call 0x5f64 to explicitly enable displays. */ + Bool enableDisplays; + /* Use BIOS call 0x5f05 to set the refresh rate. */ + Bool useExtendedRefresh; + int configuredDevices; + + /* These are indexed by the display types */ + Bool displayAttached[NumDisplayTypes]; + Bool displayPresent[NumDisplayTypes]; + BoxRec displaySize[NumDisplayTypes]; + /* [0] is Pipe A, [1] is Pipe B. */ - int pipeDevices[2]; - Bool pipeEnabled[2]; - BoxRec pipeDisplaySize[2]; + int availablePipes; + int pipeDevices[MAX_DISPLAY_PIPES]; /* [0] is display plane A, [1] is display plane B. */ - int planeEnabled[2]; + Bool pipeEnabled[MAX_DISPLAY_PIPES]; + BoxRec pipeDisplaySize[MAX_DISPLAY_PIPES]; + int planeEnabled[MAX_DISPLAY_PIPES]; + + /* Driver phase/state information */ + Bool starting; + Bool closing; + Bool suspended; + } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) @@ -295,18 +320,19 @@ extern void I830EmitFlush(ScrnInfoPtr pScrn); extern Bool I830DGAInit(ScreenPtr pScreen); +#ifdef I830_XV extern void I830InitVideo(ScreenPtr pScreen); +extern void I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode); +extern void I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode); +#endif #ifdef XF86DRI -extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn); +extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags); extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn); -extern Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool); extern Bool I830DRIScreenInit(ScreenPtr pScreen); extern Bool I830DRIDoMappings(ScreenPtr pScreen); extern void I830DRICloseScreen(ScreenPtr pScreen); extern Bool I830DRIFinishScreenInit(ScreenPtr pScreen); -extern Bool I830InitDma(ScrnInfoPtr pScrn); -extern Bool I830CleanupDma(ScrnInfoPtr pScrn); #endif extern Bool I830AccelInit(ScreenPtr pScreen); extern void I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, @@ -321,8 +347,11 @@ extern void I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, extern void I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); -extern int I830CheckAvailableMemory(ScrnInfoPtr pScrn); -extern Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, Bool initial); +extern void I830ResetAllocations(ScrnInfoPtr pScrn, const int flags); +extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); +extern long I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn); +extern Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags); +extern Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool); extern Bool I830FixupOffsets(ScrnInfoPtr pScrn); extern Bool I830BindGARTMemory(ScrnInfoPtr pScrn); extern Bool I830UnbindGARTMemory(ScrnInfoPtr pScrn); @@ -333,23 +362,34 @@ extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, extern void I830PrintAllRegisters(I830RegPtr i830Reg); extern void I830ReadAllRegisters(I830Ptr pI830, I830RegPtr i830Reg); +extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer); + /* - * 8000KB is the amount reported by VBE when 8MB is reserved. - * 132K of that is used for tables, leaving 8060KB, but VBE reports in - * multiples of 64K so rounding down gives 8000KB. + * 12288 is set as the maximum, chosen because it is enough for + * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. */ -#define I830_MINIMUM_VBIOS_MEM 8000 -#define I830_DEFAULT_VIDEOMEM (MB(8) / 1024) - -/* Flags for I830AllocVidMem() */ -#define FROM_ANYWHERE 0x0000 -#define FROM_POOL_ONLY 0x0001 -#define FROM_NEW_ONLY 0x0002 -#define FROM_MASK 0x000f -#define ALLOCATE_AT_TOP 0x0010 -#define ALLOCATE_AT_BOTTOM 0x0020 -#define FORCE_GAPS 0x0040 -#define NEED_PHYSICAL_ADDR 0x0100 -#define ALIGN_BOTH_ENDS 0x0200 +#define I830_MAXIMUM_VBIOS_MEM 12288 +#define I830_DEFAULT_VIDEOMEM_2D (MB(8) / 1024) +#define I830_DEFAULT_VIDEOMEM_3D (MB(32) / 1024) + +/* Flags for memory allocation function */ +#define FROM_ANYWHERE 0x00000000 +#define FROM_POOL_ONLY 0x00000001 +#define FROM_NEW_ONLY 0x00000002 +#define FROM_MASK 0x0000000f + +#define ALLOCATE_AT_TOP 0x00000010 +#define ALLOCATE_AT_BOTTOM 0x00000020 +#define FORCE_GAPS 0x00000040 + +#define NEED_PHYSICAL_ADDR 0x00000100 +#define ALIGN_BOTH_ENDS 0x00000200 +#define FORCE_LOW 0x00000400 + +#define ALLOC_NO_TILING 0x00001000 +#define ALLOC_INITIAL 0x00002000 + +#define ALLOCATE_DRY_RUN 0x80000000 + #endif /* _I830_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c index dd3360af4..1a071497e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c @@ -32,7 +32,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c,v 1.2 2002/10/08 20:15:46 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c,v 1.4 2002/12/10 01:27:05 dawes Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: @@ -172,7 +172,7 @@ I830Sync(ScrnInfoPtr pScrn) ErrorF("I830Sync\n"); #ifdef XF86DRI - /* VT switching tries to do this. + /* VT switching tries to do this. */ if (!pI830->LockHeld && pI830->directRenderingEnabled) { return; @@ -243,39 +243,10 @@ I830RefreshRing(ScrnInfoPtr pScrn) if (pI830->LpRing.space < 0) pI830->LpRing.space += pI830->LpRing.mem.Size; - pI830->AccelInfoRec->NeedToSync = TRUE; + if (pI830->AccelInfoRec) + pI830->AccelInfoRec->NeedToSync = TRUE; } -#if 0 -/* Emit on gaining VT? - */ -void -I830EmitInvarientState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - BEGIN_LP_RING(10); - - OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); - OUT_RING(GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0); - OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); - OUT_RING(MI_NOOP); - - OUT_RING(GFX_OP_COLOR_CHROMA_KEY); - OUT_RING(CC1_UPDATE_KILL_WRITE | - CC1_DISABLE_KILL_WRITE | - CC1_UPDATE_COLOR_IDX | - CC1_UPDATE_CHROMA_LOW | CC1_UPDATE_CHROMA_HI | 0); - OUT_RING(0); - OUT_RING(0); - -/* OUT_RING( CMD_OP_Z_BUFFER_INFO ); */ -/* OUT_RING( pI830->DepthBuffer.Start | pI830->auxPitchBits); */ - - ADVANCE_LP_RING(); -} -#endif - /* I830 Accel Functions */ static void I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h index ee535fa24..3367bfc16 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h @@ -26,7 +26,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmI830.h,v 1.2 2001/10/04 18:32:29 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.2 2002/12/10 01:27:05 dawes Exp $ */ /* Author: Jeff Hartmann <jhartmann@valinux.com> @@ -93,6 +93,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define I830_UPLOAD_TEXBLEND_MASK 0xf00000 #define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) #define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 +#define I830_UPLOAD_STIPPLE 0x8000000 /* Indices into buf.Setup where various bits of state are mirrored per * context and per buffer. These can be fired at the card as a unit, @@ -145,9 +146,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define I830_CTXREG_MCSB1 16 #define I830_CTX_SETUP_SIZE 17 +/* 1.3: Stipple state + */ +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + /* Texture state (per tex unit) */ - #define I830_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (6 dwords) */ #define I830_TEXREG_MI1 1 #define I830_TEXREG_MI2 2 @@ -160,6 +166,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ #define I830_TEX_SETUP_SIZE 10 +/* New version. Kernel auto-detects. + */ +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S0 1 +#define I830_TEXREG_TM0S1 2 +#define I830_TEXREG_TM0S2 3 +#define I830_TEXREG_TM0S3 4 +#define I830_TEXREG_TM0S4 5 +#define I830_TEXREG_NOP0 6 /* noop */ +#define I830_TEXREG_NOP1 7 /* noop */ +#define I830_TEXREG_NOP2 8 /* noop */ +#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */ +#define __I830_TEX_SETUP_SIZE 10 + + #define I830_FRONT 0x1 #define I830_BACK 0x2 #define I830_DEPTH 0x4 @@ -176,6 +197,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_SWAP 0x06 #define DRM_I830_COPY 0x07 #define DRM_I830_DOCOPY 0x08 +#define DRM_I830_FLIP 0x09 +#define DRM_I830_IRQ_EMIT 0x0a +#define DRM_I830_IRQ_WAIT 0x0b +#define DRM_I830_GETPARAM 0x0c +#define DRM_I830_SETPARAM 0x0d #endif /* _I830_DEFINES_ */ @@ -234,4 +260,29 @@ typedef struct { int granted; } drmI830DMA; +typedef struct drm_i830_irq_emit { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct drm_i830_irq_wait { + int irq_seq; +} drmI830IrqWait; + +typedef struct drm_i830_getparam { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 + + +typedef struct drm_i830_setparam { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 + + + #endif /* _I830_DRM_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c index e163732cc..419fd5837 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c @@ -2,6 +2,7 @@ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright © 2002 David Dawes All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a @@ -25,7 +26,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c,v 1.2 2002/09/12 22:25:18 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c,v 1.6 2002/12/18 15:49:01 dawes Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: @@ -43,6 +44,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Keith Whitwell <keith@tungstengraphics.com> + * David Dawes <dawes@tungstengraphics.com> * */ @@ -206,10 +208,13 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) OUTREG(CURSOR_A_POSITION, temp); - if (hide) - pI830->CursorInfoRec->HideCursor(pScrn); - else if (show) - pI830->CursorInfoRec->ShowCursor(pScrn); + if (pI830->cursorOn) { + if (hide) + pI830->CursorInfoRec->HideCursor(pScrn); + else if (show) + pI830->CursorInfoRec->ShowCursor(pScrn); + pI830->cursorOn = TRUE; + } } static void @@ -224,6 +229,7 @@ I830ShowCursor(ScrnInfoPtr pScrn) " Value of CursorMem.Start is %x ", pI830->CursorMem.Physical, pI830->CursorMem.Start); + pI830->cursorOn = TRUE; if (IS_MOBILE(pI830)) { temp = INREG(CURSOR_A_CONTROL); temp &= ~CURSOR_MODE; @@ -246,6 +252,7 @@ I830HideCursor(ScrnInfoPtr pScrn) DPRINTF(PFX, "I830HideCursor\n"); + pI830->cursorOn = FALSE; if (IS_MOBILE(pI830)) { temp = INREG(CURSOR_A_CONTROL); temp &= ~CURSOR_MODE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c index 584ef0204..bb4c103a1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c @@ -34,7 +34,7 @@ * with <TAB> characters expanded at 8-column intervals. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c,v 1.3 2003/02/26 04:11:23 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -108,7 +108,7 @@ I830DGAInit(ScreenPtr pScreen) currentMode->mode = pMode; currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; - if (pI830->AccelInfoRec) + if (!pI830->noAccel) currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; if (pMode->Flags & V_DBLSCAN) currentMode->flags |= DGA_DOUBLESCAN; @@ -280,9 +280,9 @@ I830_OpenFramebuffer(ScrnInfoPtr pScrn, MARKER(); *name = NULL; /* no special device */ - *mem = (unsigned char *)pI830->LinearAddr; - *size = pI830->FbMapSize; - *offset = pScrn->fbOffset; + *mem = (unsigned char *)(pI830->LinearAddr + pScrn->fbOffset); + *size = pI830->FrontBuffer.Size; + *offset = 0; *flags = DGA_NEED_ROOT; DPRINTF(PFX, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c index ce0479c8c..cf171a9b8 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c,v 1.6 2002/10/08 22:14:08 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c,v 1.12 2003/02/08 21:26:57 dawes Exp $ */ /************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. @@ -41,8 +41,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* - * Authors: Jeff Hartmann <jhartmann@valinux.com> + * Authors: Jeff Hartmann <jhartmann@valinux.com> * David Dawes <dawes@tungstengraphics.com> + * Keith Whitwell <keith@tungstengraphics.com> */ /* @@ -66,6 +67,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86Pci.h" #include "windowstr.h" +#include "shadow.h" #include "GL/glxtokens.h" @@ -91,11 +93,20 @@ static void I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); static void I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index); +static Bool I830DRICloseFullScreen(ScreenPtr pScreen); +static Bool I830DRIOpenFullScreen(ScreenPtr pScreen); +static void I830DRITransitionTo2d(ScreenPtr pScreen); +static void I830DRITransitionTo3d(ScreenPtr pScreen); +static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen); +static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen); + +static void I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); + extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig * configs, void **configprivs); -Bool +static Bool I830CleanupDma(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); @@ -113,7 +124,7 @@ I830CleanupDma(ScrnInfoPtr pScrn) return TRUE; } -Bool +static Bool I830InitDma(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); @@ -155,6 +166,25 @@ I830InitDma(ScrnInfoPtr pScrn) } static Bool +I830SetParam(ScrnInfoPtr pScrn, int param, int value) +{ + I830Ptr pI830 = I830PTR(pScrn); + drmI830SetParam sp; + + memset(&sp, 0, sizeof(sp)); + sp.param = param; + sp.value = value; + + if (drmCommandWrite(pI830->drmSubFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 SetParam Failed\n"); + return FALSE; + } + + return TRUE; +} + + +static Bool I830InitVisualConfigs(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -462,6 +492,12 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->InitBuffers = I830DRIInitBuffers; pDRIInfo->MoveBuffers = I830DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->OpenFullScreen = I830DRIOpenFullScreen; + pDRIInfo->CloseFullScreen = I830DRICloseFullScreen; + pDRIInfo->TransitionTo2d = I830DRITransitionTo2d; + pDRIInfo->TransitionTo3d = I830DRITransitionTo3d; + pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d; + pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d; if (!DRIScreenInit(pScreen, pDRIInfo, &pI830->drmSubFD)) { xf86DrvMsg(pScreen->myNum, X_ERROR, @@ -477,7 +513,6 @@ I830DRIScreenInit(ScreenPtr pScreen) { drmVersionPtr version; -#if defined(XFree86LOADER) /* Check the DRM lib version. * drmGetLibVersion was not supported in version 1.0, so check for * symbol first to avoid possible crash or hang. @@ -485,7 +520,6 @@ I830DRIScreenInit(ScreenPtr pScreen) if (xf86LoaderCheckSymbol("drmGetLibVersion")) { version = drmGetLibVersion(pI830->drmSubFD); } else -#endif { /* drmlib version 1.0.0 didn't have the drmGetLibVersion * entry point. Fake it by allocating a version record @@ -497,16 +531,19 @@ I830DRIScreenInit(ScreenPtr pScreen) version->version_patchlevel = 0; } +#define REQ_MAJ 1 +#define REQ_MIN 1 if (version) { - if (version->version_major != 1 || - version->version_minor < 1) { + if (version->version_major != REQ_MAJ || + version->version_minor < REQ_MIN) { /* incompatible drm library version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I830DRIScreenInit failed because of a version mismatch.\n" - "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n" "[dri] Disabling DRI.\n", version->version_major, - version->version_minor, version->version_patchlevel); + version->version_minor, version->version_patchlevel, + REQ_MAJ, REQ_MIN); drmFreeVersion(version); I830DRICloseScreen(pScreen); return FALSE; @@ -517,11 +554,11 @@ I830DRIScreenInit(ScreenPtr pScreen) /* Check the i830 DRM version */ version = drmGetVersion(pI830->drmSubFD); if (version) { - if (version->version_major != 1 || version->version_minor < 2) { + if (version->version_major != 1 || version->version_minor < 3) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] %s failed because of a version mismatch.\n" - "[dri] i830.o kernel module version is %d.%d.%d but version 1.2 or greater is needed.\n" + "[dri] i830.o kernel module version is %d.%d.%d but version 1.3 or greater is needed.\n" "[dri] Disabling DRI.\n", "I830DRIScreenInit", version->version_major, @@ -530,6 +567,7 @@ I830DRIScreenInit(ScreenPtr pScreen) drmFreeVersion(version); return FALSE; } + pI830->drmMinor = version->version_minor; drmFreeVersion(version); } } @@ -648,6 +686,11 @@ I830DRIDoMappings(ScreenPtr pScreen) I830InitDma(pScrn); + if (pI830->PciInfo->chipType != PCI_CHIP_845_G && + pI830->PciInfo->chipType != PCI_CHIP_I830_M) { + I830SetParam(pScrn, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); + } + /* Okay now initialize the dma engine */ if (!pI830DRI->irq) { pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD, @@ -668,6 +711,7 @@ I830DRIDoMappings(ScreenPtr pScreen) #endif } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] dma control initialized, using IRQ %d\n", pI830DRI->irq); @@ -758,10 +802,22 @@ Bool I830DRIFinishScreenInit(ScreenPtr pScreen) { I830SAREARec *sPriv = (I830SAREARec *) DRIGetSAREAPrivate(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, "I830DRIFinishScreenInit\n"); memset(sPriv, 0, sizeof(sPriv)); + + /* Have shadow run only while there is 3d active. + */ + if (pI830->allowPageFlip && pI830->drmMinor >= 3) { + shadowSetup(pScreen); + shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0); + } + else + pI830->allowPageFlip = 0; + return DRIFinishScreenInit(pScreen); } @@ -841,7 +897,7 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) /* This routine is a modified form of XAADoBitBlt with the calls to * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source * instead of destination. My origin is upside down so the ydir cases - * are reversed. + * are reversed. */ static void I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, @@ -1003,7 +1059,7 @@ I830EmitInvarientState(ScrnInfoPtr pScrn) I830DRIPtr pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate; CARD32 ctx_addr, temp; - BEGIN_LP_RING(128-4); + BEGIN_LP_RING(128-2); ctx_addr = pI830->ContextMem.Start; /* Align to a 2k boundry */ @@ -1219,6 +1275,7 @@ I830EmitInvarientState(ScrnInfoPtr pScrn) TEX_STREAM_COORD_SET(3) | ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3)); +#if 0 OUT_RING(STATE3D_MAP_FILTER_CMD | MAP_UNIT(0) | ENABLE_CHROMA_KEY_PARAMS | @@ -1325,6 +1382,7 @@ I830EmitInvarientState(ScrnInfoPtr pScrn) MAP_UNIT(3) | ENABLE_MAX_MIP_LVL | ENABLE_MIN_MIP_LVL | LOD_MAX(0) | LOD_MIN(0)); +#endif OUT_RING(STATE3D_MAP_COORD_TRANSFORM); OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0)); @@ -1422,6 +1480,191 @@ I830EmitInvarientState(ScrnInfoPtr pScrn) OUT_RING(MAGIC_W_STATE_DWORD1); OUT_RING(0x3f800000 /* 1.0 in IEEE float */ ); +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) + + OUT_RING(GFX_OP_STIPPLE); + OUT_RING(0); + ADVANCE_LP_RING(); } +/* Fullscreen hooks. The DRI fullscreen mode can probably be removed + * as it adds little or nothing above the mechanism below. (and isn't + * widely used) + */ +static Bool +I830DRIOpenFullScreen(ScreenPtr pScreen) +{ + return TRUE; +} + +static Bool +I830DRICloseFullScreen(ScreenPtr pScreen) +{ + return TRUE; +} + + + +/* Use callbacks from dri.c to support pageflipping mode for a single + * 3d context without need for any specific full-screen extension. + * + * Also see tdfx driver for example of using these callbacks to + * allocate and free 3d-specific memory on demand. + */ + + + + + +/* Use the miext/shadow module to maintain a list of dirty rectangles. + * These are blitted to the back buffer to keep both buffers clean + * during page-flipping when the 3d application isn't fullscreen. + * + * Unlike most use of the shadow code, both buffers are in video + * memory. + * + * An alternative to this would be to organize for all on-screen + * drawing operations to be duplicated for the two buffers. That + * might be faster, but seems like a lot more work... + */ + + +/* This should be done *before* XAA syncs, + * Otherwise will have to sync again??? + */ +static void +I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + RegionPtr damage = &pBuf->damage; + int i, num = REGION_NUM_RECTS(damage); + BoxPtr pbox = REGION_RECTS(damage); + I830SAREARec *pSAREAPriv = DRIGetSAREAPrivate(pScreen); + int cmd, br13; + + /* Don't want to do this when no 3d is active and pages are + * right-way-round : + */ + if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) + return; + + br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); + + if (pScrn->bitsPerPixel == 32) { + cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + br13 |= 3 << 24; + } else { + cmd = (XY_SRC_COPY_BLT_CMD); + br13 |= 1 << 24; + } + + for (i = 0 ; i < num ; i++, pbox++) { + BEGIN_LP_RING(8); + OUT_RING(cmd); + OUT_RING(br13); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING((pbox->y2 << 16) | pbox->x2); + OUT_RING(pI830->BackBuffer.Start); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING(br13 & 0xffff); + OUT_RING(pI830->FrontBuffer.Start); + ADVANCE_LP_RING(); + } +} + + +static void +I830EnablePageFlip(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + I830SAREARec *pSAREAPriv = DRIGetSAREAPrivate(pScreen); + + pSAREAPriv->pf_enabled = pI830->allowPageFlip; + pSAREAPriv->pf_active = 0; + + if (pI830->allowPageFlip) { + int br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); + + BEGIN_LP_RING(8); + if (pScrn->bitsPerPixel == 32) { + OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + br13 |= 3 << 24; + } else { + OUT_RING(XY_SRC_COPY_BLT_CMD); + br13 |= 1 << 24; + } + + OUT_RING(br13); + OUT_RING(0); + OUT_RING((pScrn->virtualY << 16) | pScrn->virtualX); + OUT_RING(pI830->BackBuffer.Start); + OUT_RING(0); + OUT_RING(br13 & 0xffff); + OUT_RING(pI830->FrontBuffer.Start); + ADVANCE_LP_RING(); + + pSAREAPriv->pf_active = 1; + } +} + +static void +I830DisablePageFlip(ScreenPtr pScreen) +{ + I830SAREARec *pSAREAPriv = DRIGetSAREAPrivate(pScreen); + + pSAREAPriv->pf_active = 0; +} + + +static void +I830DRITransitionSingleToMulti3d(ScreenPtr pScreen) +{ + /* Tell the clients not to pageflip. How? + * -- Field in sarea, plus bumping the window counters. + * -- DRM needs to cope with Front-to-Back swapbuffers. + */ + I830DisablePageFlip(pScreen); +} + +static void +I830DRITransitionMultiToSingle3d(ScreenPtr pScreen) +{ + /* Let the remaining 3d app start page flipping again. + */ + I830EnablePageFlip(pScreen); +} + + +static void +I830DRITransitionTo3d(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + I830EnablePageFlip(pScreen); + pI830->have3DWindows = 1; +} + + +static void +I830DRITransitionTo2d(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + I830SAREARec *sPriv = (I830SAREARec *) DRIGetSAREAPrivate(pScreen); + + /* Shut down shadowing if we've made it back to the front page: + */ + if (sPriv->pf_current_page == 0) { + I830DisablePageFlip(pScreen); + } + + pI830->have3DWindows = 0; +} + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h index bf406c5ba..b60c72019 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.3 2002/09/11 00:29:32 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.5 2002/12/10 01:27:05 dawes Exp $ */ #ifndef _I830_DRI_H #define _I830_DRI_H @@ -9,7 +9,7 @@ #define I830_MAX_DRAWABLES 256 #define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 0 +#define I830_MINOR_VERSION 3 #define I830_PATCHLEVEL 0 #define I830_REG_SIZE 0x80000 @@ -115,6 +115,32 @@ typedef struct _I830SAREA { int ctxOwner; /* last context to upload state */ int vertex_prim; + + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; /* is pageflipping active right now? */ + int pf_current_page; /* which buffer is being displayed? */ + + int perf_boxes; /* performance boxes to be displayed */ + + /* Here's the state for texunits 2,3: + */ + unsigned int TexState2[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState2[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed2; + + unsigned int TexState3[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState3[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed3; + + unsigned int StippleState[I830_STP_SETUP_SIZE]; } I830SAREARec, *I830SAREAPtr; +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c index ced137311..073f8eb6f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c,v 1.17 2002/10/16 21:13:47 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c,v 1.27 2003/02/14 17:12:42 dawes Exp $ */ /************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. @@ -105,6 +105,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * 07/2002 David Dawes + * - Add Intel(R) 855GM/852GM support. + */ +/* + * 07/2002 David Dawes * - Cleanup code formatting. * - Improve VESA mode selection, and fix refresh rate selection. * - Don't duplicate functions provided in 4.2 vbe modules. @@ -127,8 +131,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * 08/2002 Alan Hourihane and David Dawes * - Add XVideo support. */ +/* + * 10/2002 David Dawes + * - Add Intel(R) 865G support. + */ + -#define DEBUG +#ifndef PRINT_MODE_INFO +#define PRINT_MODE_INFO 0 +#endif #include "xf86.h" #include "xf86_ansic.h" @@ -163,12 +174,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. static SymTabRec I830BIOSChipsets[] = { {PCI_CHIP_I830_M, "i830"}, {PCI_CHIP_845_G, "845G"}, + {PCI_CHIP_I855_GM, "852GM/855GM"}, + {PCI_CHIP_I865_G, "865G"}, {-1, NULL} }; static PciChipsets I830BIOSPciChipsets[] = { {PCI_CHIP_I830_M, PCI_CHIP_I830_M, RES_SHARED_VGA}, {PCI_CHIP_845_G, PCI_CHIP_845_G, RES_SHARED_VGA}, + {PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, RES_SHARED_VGA}, + {PCI_CHIP_I865_G, PCI_CHIP_I865_G, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED} }; @@ -183,18 +198,20 @@ typedef enum { OPTION_SW_CURSOR, OPTION_CACHE_LINES, OPTION_DRI, + OPTION_PAGEFLIP, OPTION_XVIDEO, OPTION_VIDEO_KEY, OPTION_COLOR_KEY, OPTION_STRETCH, OPTION_CENTER } I830Opts; - + static OptionInfoRec I830BIOSOptions[] = { {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_CACHE_LINES, "CacheLines", OPTV_INTEGER, {0}, FALSE}, {OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, TRUE}, + {OPTION_PAGEFLIP, "PageFlip", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_XVIDEO, "XVideo", OPTV_BOOLEAN, {0}, TRUE}, {OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, {OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE}, @@ -219,8 +236,8 @@ static Bool OffsetFrame = FALSE; #ifdef I830DEBUG void -DPRINTF_stub(const char *filename, int line, const char *function, - const char *fmt, ...) +I830DPRINTF_stub(const char *filename, int line, const char *function, + const char *fmt, ...) { va_list ap; @@ -234,8 +251,8 @@ DPRINTF_stub(const char *filename, int line, const char *function, } #else /* #ifdef I830DEBUG */ void -DPRINTF_stub(const char *filename, int line, const char *function, - const char *fmt, ...) +I830DPRINTF_stub(const char *filename, int line, const char *function, + const char *fmt, ...) { /* do nothing */ } @@ -280,7 +297,6 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn) pI830 = I830PTR(pScrn); mode = pScrn->modes; - pVesa = pI830->vesa; if (mode) { do { @@ -296,14 +312,18 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn) } while (mode && mode != pScrn->modes); } - if (pVesa->vbeInfo) - VBEFreeVBEInfo(pVesa->vbeInfo); - if (pVesa->pVbe) - vbeFree(pVesa->pVbe); + if (pI830->vbeInfo) + VBEFreeVBEInfo(pI830->vbeInfo); + if (pI830->pVbe) + vbeFree(pI830->pVbe); + + pVesa = pI830->vesa; if (pVesa->monitor) xfree(pVesa->monitor); if (pVesa->savedPal) xfree(pVesa->savedPal); + xfree(pVesa); + xfree(pScrn->driverPrivate); pScrn->driverPrivate = NULL; } @@ -319,155 +339,497 @@ I830BIOSProbeDDC(ScrnInfoPtr pScrn, int index) ConfiguredMonitor = vbeDoEDID(pVbe, NULL); } +/* Various extended video BIOS functions. */ +static const int refreshes[] = { + 43, 56, 60, 70, 72, 75, 85, 100, 120 +}; +static const int nrefreshes = sizeof(refreshes) / sizeof(refreshes[0]); + static Bool -I830DetectDisplayDevice(ScrnInfoPtr pScrn) +Check5fStatus(ScrnInfoPtr pScrn, int func, int ax) { - I830Ptr pI830; - vbeInfoPtr pVbe; - int pipe, n; + if (ax == 0x005f) + return TRUE; + else if (ax == 0x015f) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Extended BIOS function 0x%04x failed.\n", func); + return FALSE; + } else if ((ax & 0xff) != 0x5f) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Extended BIOS function 0x%04x not supported.\n", func); + return FALSE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Extended BIOS function 0x%04x returns 0x%04x.\n", + func, ax & 0xffff); + return FALSE; + } +} - pI830 = I830PTR(pScrn); - pVbe = pI830->vesa->pVbe; +#if 0 +static int +BitToRefresh(int bits) +{ + int i; + + for (i = 0; i < nrefreshes; i++) + if (bits & (1 << i)) + return refreshes[i]; + return 0; +} + +static int +GetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh, int *availRefresh) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + + DPRINTF(PFX, "GetRefreshRate\n"); + + /* Only 8-bit mode numbers are supported. */ + if (mode & 0x100) + return 0; + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f05; + pVbe->pInt10->bx = (mode & 0xff) | 0x100; + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (Check5fStatus(pScrn, 0x5f05, pVbe->pInt10->ax)) { + if (availRefresh) + *availRefresh = pVbe->pInt10->bx; + return BitToRefresh(pVbe->pInt10->cx); + } else + return 0; +} +#endif + +static int +SetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh) +{ + int i; + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + + DPRINTF(PFX, "SetRefreshRate: mode 0x%x, refresh: %d\n", mode, refresh); + + /* Only 8-bit mode numbers are supported. */ + if (mode & 0x100) + return 0; + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f05; + pVbe->pInt10->bx = mode & 0xff; + + for (i = nrefreshes - 1; i >= 0; i--) { + /* + * Look for the highest value that the requested (refresh + 2) is + * greater than or equal to. + */ + if (refreshes[i] <= (refresh + 2)) + break; + } + /* i can be 0 if the requested refresh was higher than the max. */ + if (i == 0) { + if (refresh >= refreshes[nrefreshes - 1]) + i = nrefreshes - 1; + } + DPRINTF(PFX, "Setting refresh rate to %dHz for mode 0x%02x\n", + refreshes[i], mode & 0xff); + pVbe->pInt10->cx = 1 << i; + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (Check5fStatus(pScrn, 0x5f05, pVbe->pInt10->ax)) + return refreshes[i]; + else + return 0; +} + +static Bool +GetModeSupport(ScrnInfoPtr pScrn, int modePipeA, int modePipeB, + int devicesPipeA, int devicesPipeB, int *maxBandwidth, + int *bandwidthPipeA, int *bandwidthPipeB) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + + DPRINTF(PFX, "GetModeSupport: modes 0x%x, 0x%x, devices: 0x%x, 0x%x\n", + modePipeA, modePipeB, devicesPipeA, devicesPipeB); + + /* Only 8-bit mode numbers are supported. */ + if ((modePipeA & 0x100) || (modePipeB & 0x100)) + return 0; + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f28; + pVbe->pInt10->bx = (modePipeA & 0xff) | ((modePipeB & 0xff) << 8); + if ((devicesPipeA & 0x80) || (devicesPipeB & 0x80)) + pVbe->pInt10->cx = 0x8000; + else + pVbe->pInt10->cx = (devicesPipeA & 0xff) | ((devicesPipeB & 0xff) << 8); + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (Check5fStatus(pScrn, 0x5f28, pVbe->pInt10->ax)) { + if (maxBandwidth) + *maxBandwidth = pVbe->pInt10->cx; + if (bandwidthPipeA) + *bandwidthPipeA = pVbe->pInt10->dx & 0xffff; + /* XXX For XFree86 4.2.0 and earlier, ->dx is truncated to 16 bits. */ + if (bandwidthPipeB) + *bandwidthPipeB = (pVbe->pInt10->dx >> 16) & 0xffff; + return TRUE; + } else + return FALSE; +} + +static int +GetLFPCompMode(ScrnInfoPtr pScrn) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + + DPRINTF(PFX, "GetLFPCompMode\n"); + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f61; + pVbe->pInt10->bx = 0x100; + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (Check5fStatus(pScrn, 0x5f61, pVbe->pInt10->ax)) + return pVbe->pInt10->cx & 0xffff; + else + return -1; +} + +#if 0 +static Bool +SetLFPCompMode(ScrnInfoPtr pScrn, int compMode) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + + DPRINTF(PFX, "SetLFPCompMode: compMode %d\n", compMode); + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f61; + pVbe->pInt10->bx = 0; + pVbe->pInt10->cx = compMode; + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + return Check5fStatus(pScrn, 0x5f61, pVbe->pInt10->ax); +} +#endif + +static int +GetDisplayDevices(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + vbeInfoPtr pVbe = pI830->pVbe; + + DPRINTF(PFX, "GetDisplayDevices\n"); + +#if 0 + { + CARD32 temp; + ErrorF("ADPA is 0x%08x\n", INREG(ADPA)); + ErrorF("DVOA is 0x%08x\n", INREG(DVOA)); + ErrorF("DVOB is 0x%08x\n", INREG(DVOB)); + ErrorF("DVOC is 0x%08x\n", INREG(DVOC)); + ErrorF("LVDS is 0x%08x\n", INREG(LVDS)); + temp = INREG(DVOA_SRCDIM); + ErrorF("DVOA_SRCDIM is 0x%08x (%d x %d)\n", temp, + (temp >> 12) & 0xfff, temp & 0xfff); + temp = INREG(DVOB_SRCDIM); + ErrorF("DVOB_SRCDIM is 0x%08x (%d x %d)\n", temp, + (temp >> 12) & 0xfff, temp & 0xfff); + temp = INREG(DVOC_SRCDIM); + ErrorF("DVOC_SRCDIM is 0x%08x (%d x %d)\n", temp, + (temp >> 12) & 0xfff, temp & 0xfff); + ErrorF("SWF0 is 0x%08x\n", INREG(SWF0)); + ErrorF("SWF4 is 0x%08x\n", INREG(SWF4)); + } +#endif pVbe->pInt10->num = 0x10; pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x0100; + pVbe->pInt10->bx = 0x100; + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) + return pVbe->pInt10->cx & 0xffff; + else + return -1; +} - if (pVbe->pInt10->ax != 0x005f) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Failed to detect active display devices\n"); +static Bool +SetDisplayDevices(ScrnInfoPtr pScrn, int devices) +{ + I830Ptr pI830 = I830PTR(pScrn); + vbeInfoPtr pVbe = pI830->pVbe; + CARD32 temp; + + DPRINTF(PFX, "SetDisplayDevices: devices 0x%x\n", devices); + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f64; + pVbe->pInt10->bx = 0x1; + pVbe->pInt10->cx = devices; + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) + return TRUE; + else { + ErrorF("Writing config directly to SWF0\n"); + temp = INREG(SWF0); + OUTREG(SWF0, (temp & ~(0xffff)) | (devices & 0xffff)); + ErrorF("SetDisplayDevices failed. devices is 0x%x instead of 0x%x\n", + GetDisplayDevices(pScrn), devices); return FALSE; } +} - pI830->configuredDevices = pVbe->pInt10->cx; +#if 0 +static Bool +GetDevicePresence(ScrnInfoPtr pScrn, Bool *required, int *attached, + int *encoderPresent) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - /* Check for active devices on pipes A and B */ - for (n = 0; n < 2; n++) { - int shift; + DPRINTF(PFX, "GetDevicePresence\n"); - if (n == 0) - shift = PIPE_A_SHIFT; - else - shift = PIPE_B_SHIFT; + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f64; + pVbe->pInt10->bx = 0x200; - pipe = ((pVbe->pInt10->cx >> shift) & PIPE_ACTIVE_MASK); - if (pipe) { - pI830->pipeEnabled[n] = TRUE; - pI830->pipeDevices[n] = pipe; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Currently active displays on Pipe %c:\n", 'A' + n); - if (pipe & PIPE_CRT_ACTIVE) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tCRT\n"); + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { + if (required) + *required = ((pVbe->pInt10->bx & 0x1) == 0); + if (attached) + *attached = (pVbe->pInt10->cx >> 8) & 0xff; + if (encoderPresent) + *encoderPresent = pVbe->pInt10->cx & 0xff; + return TRUE; + } else + return FALSE; +} +#endif + +static Bool +GetDisplayInfo(ScrnInfoPtr pScrn, int device, Bool *attached, Bool *present, + short *x, short *y) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; - if (pipe & PIPE_TV_ACTIVE) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tTV child device\n"); + DPRINTF(PFX, "GetDisplayInfo: device: 0x%x\n", device); - if (pipe & PIPE_DFP_ACTIVE) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tDFP child device\n"); + switch (device & 0xff) { + case 0x01: + case 0x02: + case 0x04: + case 0x08: + case 0x10: + case 0x20: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "GetDisplayInfo: invalid device: 0x%x\n", device & 0xff); + return FALSE; + } - if (pipe & PIPE_LCD_ACTIVE) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "\tLFP (Local Flat Panel) child device\n"); + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f64; + pVbe->pInt10->bx = 0x300; + pVbe->pInt10->cx = device & 0xff; + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) { + if (attached) + *attached = ((pVbe->pInt10->bx & 0x2) != 0); + if (present) + *present = ((pVbe->pInt10->bx & 0x1) != 0); + if (pVbe->pInt10->cx != (device & 0xff)) { + if (y) { + *y = pVbe->pInt10->cx & 0xffff; + } + if (x) { + *x = (pVbe->pInt10->cx >> 16) & 0xffff; + } + } + return TRUE; + } else + return FALSE; +} + +/* + * Returns a string matching the device corresponding to the first bit set + * in "device". savedDevice is then set to device with that bit cleared. + * Subsequent calls with device == -1 will use savedDevice. + */ + +static const char *displayDevices[] = { + "CRT", + "TV", + "DFP (digital flat panel)", + "LFP (local flat panel)", + "TV2 (second TV)", + "DFP2 (second digital flat panel)", + NULL +}; + +static const char * +DeviceToString(int device) +{ + static int savedDevice = -1; + static int bit = 0; + const char *name; + + if (device == -1) { + device = savedDevice; + bit = 0; + } + + if (device == -1) + return NULL; + + while (displayDevices[bit]) { + if (device & (1 << bit)) { + name = displayDevices[bit]; + savedDevice = device & ~(1 << bit); + bit++; + return name; + } + bit++; + } + return NULL; +} + +static void +PrintDisplayDeviceInfo(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + int pipe, n; + int displays; + + DPRINTF(PFX, "PrintDisplayDeviceInfo\n"); + + displays = pI830->configuredDevices; + if (displays == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "No active display devices.\n"); + return; + } - if (pipe & PIPE_TV2_ACTIVE) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tSecond TV child device\n"); + /* Check for active devices connected to each display pipe. */ + for (n = 0; n < pI830->availablePipes; n++) { + pipe = ((displays >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK); + if (pipe) { + const char *name; - if (pipe & PIPE_DFP2_ACTIVE) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tSecond DFP child device\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Currently active displays on Pipe %c:\n", PIPE_NAME(n)); + name = DeviceToString(pipe); + do { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t%s\n", name); + name = DeviceToString(-1); + } while (name); if (pipe & PIPE_UNKNOWN_ACTIVE) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tSome unknown display devices may also be present\n"); - /* If a non-CRT device is attached, get its resolution. */ - - pI830->pipeDisplaySize[n].x1 = pI830->pipeDisplaySize[n].y1 = 0; - pI830->pipeDisplaySize[n].x2 = pI830->pipeDisplaySize[n].y2 = 4096; - if (pipe & ~PIPE_CRT_ACTIVE) { - static const unsigned char devices[] = { - PIPE_DFP_ACTIVE, - PIPE_LCD_ACTIVE, - PIPE_DFP2_ACTIVE - }; - int numdevs = sizeof(devices) / sizeof(devices[0]); - int i, x, y; - - for (i = 0; i < numdevs; i++) { - if (!(pipe & devices[i])) - continue; - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x0300; - pVbe->pInt10->cx = devices[i] << shift; - - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - - if (pVbe->pInt10->ax != 0x005f) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Get Display Device failed for %c:0x%x\n", - 'A' + n, devices[i]); - } else { - if (pVbe->pInt10->bx & 0x02) { - x = (pVbe->pInt10->cx >> 16) & 0xffff; - y = (pVbe->pInt10->cx & 0xffff); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Size of device %c:0x%x is %d x %d\n", - 'A' + n, devices[i], x, y); - if (x < pI830->pipeDisplaySize[n].x2) - pI830->pipeDisplaySize[n].x2 = x; - if (y < pI830->pipeDisplaySize[n].y2) - pI830->pipeDisplaySize[n].y2 = y; - } - } - } - } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No active displays on Pipe %c.\n", 'A' + n); + "No active displays on Pipe %c.\n", PIPE_NAME(n)); } - if (pI830->pipeDisplaySize[n].x2 == 4096) - pI830->pipeDisplaySize[n].x2 = 0; - if (pI830->pipeDisplaySize[n].y2 == 4096) - pI830->pipeDisplaySize[n].y2 = 0; - /* It seems that only x might be reported, so pick the best y. */ - if (pI830->pipeDisplaySize[n].x2 != 0 && - pI830->pipeDisplaySize[n].y2 == 0) { - switch (pI830->pipeDisplaySize[n].x2) { - case 1280: - pI830->pipeDisplaySize[n].y2 = 1024; - break; - default: - pI830->pipeDisplaySize[n].y2 = - pI830->pipeDisplaySize[n].x2 * 3 / 4; - break; - } - } if (pI830->pipeDisplaySize[n].x2 != 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Lowest common panel size for pipe %c is %d x %d\n", - 'A' + n, pI830->pipeDisplaySize[n].x2, + PIPE_NAME(n), pI830->pipeDisplaySize[n].x2, pI830->pipeDisplaySize[n].y2); } else if (pI830->pipeEnabled[n] && pipe & ~PIPE_CRT_ACTIVE) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No display size information available for pipe %c.\n", - 'A' + n); + PIPE_NAME(n)); + } + } +} + +static void +GetPipeSizes(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + int pipe, n; + DisplayType i; + + DPRINTF(PFX, "GetPipeSizes\n"); + + + for (n = 0; n < pI830->availablePipes; n++) { + pipe = (pI830->configuredDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK; + pI830->pipeDisplaySize[n].x1 = pI830->pipeDisplaySize[n].y1 = 0; + pI830->pipeDisplaySize[n].x2 = pI830->pipeDisplaySize[n].y2 = 4096; + for (i = 0; i < NumKnownDisplayTypes; i++) { + if (pipe & (1 << i) & PIPE_SIZED_DISP_MASK) { + if (pI830->displaySize[i].x2 != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Size of device %s is %d x %d\n", + displayDevices[i], + pI830->displaySize[i].x2, + pI830->displaySize[i].y2); + if (pI830->displaySize[i].x2 < pI830->pipeDisplaySize[n].x2) + pI830->pipeDisplaySize[n].x2 = pI830->displaySize[i].x2; + if (pI830->displaySize[i].y2 < pI830->pipeDisplaySize[n].y2) + pI830->pipeDisplaySize[n].y2 = pI830->displaySize[i].y2; + } + } } + + if (pI830->pipeDisplaySize[n].x2 == 4096) + pI830->pipeDisplaySize[n].x2 = 0; + if (pI830->pipeDisplaySize[n].y2 == 4096) + pI830->pipeDisplaySize[n].y2 = 0; } +} + +static Bool +I830DetectDisplayDevice(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + int pipe, n; + DisplayType i; + + for (i = 0; i < NumKnownDisplayTypes; i++) { + if (GetDisplayInfo(pScrn, 1 << i, &pI830->displayAttached[i], + &pI830->displayPresent[i], + &pI830->displaySize[i].x2, + &pI830->displaySize[i].y2)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Display Info: %s: attached: %s, present: %s, size: " + "(%d,%d)\n", displayDevices[i], + BOOLTOSTRING(pI830->displayAttached[i]), + BOOLTOSTRING(pI830->displayPresent[i]), + pI830->displaySize[i].x2, pI830->displaySize[i].y2); + } + } + + pI830->configuredDevices = GetDisplayDevices(pScrn); + if (pI830->configuredDevices == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Failed to detect active display devices\n"); + return FALSE; + } + + /* Check for active devices connected to each display pipe. */ + for (n = 0; n < pI830->availablePipes; n++) { + pipe = ((pI830->configuredDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK); + if (pipe) { + pI830->pipeEnabled[n] = TRUE; + } + } + + GetPipeSizes(pScrn); + PrintDisplayDeviceInfo(pScrn); #if 0 /* A quick hack to change the set of enabled devices. */ - pI830->configuredDevices = PIPE_CRT_ACTIVE; - /* Turn on the configured displays */ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x0001; - pVbe->pInt10->cx = (CARD16)pI830->configuredDevices; - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - - if (pVbe->pInt10->ax != 0x005f) { + enabledDevices = PIPE_CRT_ACTIVE; + if (!SetDisplayDevices(pScrn, enabledDevices)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch to configured display devices\n"); } @@ -479,19 +841,34 @@ I830DetectDisplayDevice(ScrnInfoPtr pScrn) static int I830DetectMemory(ScrnInfoPtr pScrn) { - I830Ptr pI830; - vbeInfoPtr pVbe; + I830Ptr pI830 = I830PTR(pScrn); PCITAG bridge; CARD16 gmch_ctrl; int memsize = 0; - int local = 0; - - pI830 = I830PTR(pScrn); - pVbe = pI830->vesa->pVbe; bridge = pciTag(0, 0, 0); /* This is always the host bridge */ gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL); + if (IS_I85X(pI830) || IS_I865G(pI830)) + { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + memsize = MB(1) - KB(132); + break; + case I855_GMCH_GMS_STOLEN_4M: + memsize = MB(4) - KB(132); + break; + case I855_GMCH_GMS_STOLEN_8M: + memsize = MB(8) - KB(132); + break; + case I855_GMCH_GMS_STOLEN_16M: + memsize = MB(16) - KB(132); + break; + case I855_GMCH_GMS_STOLEN_32M: + memsize = MB(32) - KB(132); + break; + } + } else { switch (gmch_ctrl & I830_GMCH_GMS_MASK) { case I830_GMCH_GMS_STOLEN_512: @@ -504,27 +881,15 @@ I830DetectMemory(ScrnInfoPtr pScrn) memsize = MB(8) - KB(132); break; case I830_GMCH_GMS_LOCAL: - /* - * I'd like to use the VGA controller registers here, but - * MMIOBase isn't yet, so for now, we'll just use the - * BIOS instead... - */ - /* - * XXX Local memory isn't really handled elsewhere. - * is it valid for the 830 and/or 845G? - */ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f10; - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - memsize = pVbe->pInt10->cx * KB(1); - local = 1; + memsize = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Local memory found, but won't be used.\n"); break; } } if (memsize > 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "detected %dK %s memory.\n", memsize / 1024, - local ? "local" : "stolen"); + "detected %d kB stolen memory.\n", memsize / 1024); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n"); } @@ -596,61 +961,174 @@ I830UnmapMem(ScrnInfoPtr pScrn) return TRUE; } +#ifndef HAVE_GET_PUT_BIOSMEMSIZE +#define HAVE_GET_PUT_BIOSMEMSIZE 1 +#endif + +#if HAVE_GET_PUT_BIOSMEMSIZE /* - * These three functions use a BIOS scratch register that holds the BIOS's - * view of the (pre-reserved) memory size. + * Tell the BIOS how much video memory is available. The BIOS call used + * here won't always be available. */ -static void +static Bool +PutBIOSMemSize(ScrnInfoPtr pScrn, int memSize) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + + DPRINTF(PFX, "PutBIOSMemSize: %d kB\n", memSize / 1024); + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f11; + pVbe->pInt10->bx = 0; + pVbe->pInt10->cx = memSize / GTT_PAGE_SIZE; + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + return Check5fStatus(pScrn, 0x5f11, pVbe->pInt10->ax); +} + +/* + * This reports what the previous VBEGetVBEInfo() found. Be sure to call + * VBEGetVBEInfo() after changing the BIOS memory size view. If + * a separate BIOS call is added for this, it can be put here. Only + * return a valid value if the funtionality for PutBIOSMemSize() + * is available. + */ +static int +GetBIOSMemSize(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + int memSize = KB(pI830->vbeInfo->TotalMemory * 64); + + DPRINTF(PFX, "GetBIOSMemSize\n"); + + if (PutBIOSMemSize(pScrn, memSize)) + return memSize; + else + return -1; +} +#endif + +/* + * These three functions allow the video BIOS's view of the available video + * memory to be changed. This is currently implemented only for the 830 + * and 845G, which can do this via a BIOS scratch register that holds the + * BIOS's view of the (pre-reserved) memory size. If another mechanism + * is available in the future, it can be plugged in here. + * + * The mapping used for the 830/845G scratch register's low 4 bits is: + * + * 320k => 0 + * 832k => 1 + * 8000k => 8 + * + * The "unusual" values are the 512k, 1M, 8M pre-reserved memory, less + * overhead, rounded down to the BIOS-reported 64k granularity. + */ + +static Bool SaveBIOSMemSize(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - VESAPtr pVesa = pI830->vesa; + + DPRINTF(PFX, "SaveBIOSMemSize\n"); + + pI830->useSWF1 = FALSE; + +#if HAVE_GET_PUT_BIOSMEMSIZE + if ((pI830->saveBIOSMemSize = GetBIOSMemSize(pScrn)) != -1) + return TRUE; +#endif if (IS_I830(pI830) || IS_845G(pI830)) { - pVesa->saveSWF1 = INREG(SWF1) & 0x0f; + pI830->useSWF1 = TRUE; + pI830->saveSWF1 = INREG(SWF1) & 0x0f; + + /* + * This is for sample purposes only. pI830->saveBIOSMemSize isn't used + * when pI830->useSWF1 is TRUE. + */ + switch (pI830->saveSWF1) { + case 0: + pI830->saveBIOSMemSize = KB(320); + break; + case 1: + pI830->saveBIOSMemSize = KB(832); + break; + case 8: + pI830->saveBIOSMemSize = KB(8000); + break; + default: + pI830->saveBIOSMemSize = 0; + break; + } + return TRUE; } + return FALSE; } static void RestoreBIOSMemSize(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - VESAPtr pVesa = pI830->vesa; - Bool mapped = (pI830->MMIOBase != NULL); CARD32 swf1; - if (!pVesa || !pVesa->overrideBIOSMemSize) + DPRINTF(PFX, "RestoreBIOSMemSize\n"); + + if (!pI830->overrideBIOSMemSize) return; - if ((IS_I830(pI830) || IS_845G(pI830))) { - if (!mapped) - I830MapMMIO(pScrn); +#if HAVE_GET_PUT_BIOSMEMSIZE + if (!pI830->useSWF1) { + PutBIOSMemSize(pScrn, pI830->saveBIOSMemSize); + return; + } +#endif + + if ((IS_I830(pI830) || IS_845G(pI830)) && pI830->useSWF1) { swf1 = INREG(SWF1); swf1 &= ~0x0f; - swf1 |= (pVesa->saveSWF1 & 0x0f); + swf1 |= (pI830->saveSWF1 & 0x0f); OUTREG(SWF1, swf1); - if (!mapped) - I830UnmapMMIO(pScrn); } } static void -SetBIOSMemSize(ScrnInfoPtr pScrn) +SetBIOSMemSize(ScrnInfoPtr pScrn, int newSize) { I830Ptr pI830 = I830PTR(pScrn); - VESAPtr pVesa = pI830->vesa; - Bool mapped = (pI830->MMIOBase != NULL); CARD32 swf1; + Bool mapped; + + DPRINTF(PFX, "SetBIOSMemSize: %d kB\n", newSize / 1024); - if (!pVesa || !pVesa->overrideBIOSMemSize) + if (!pI830->overrideBIOSMemSize) return; - if (IS_I830(pI830) || IS_845G(pI830)) { +#if HAVE_GET_PUT_BIOSMEMSIZE + if (!pI830->useSWF1) { + PutBIOSMemSize(pScrn, newSize); + return; + } +#endif + + if ((IS_I830(pI830) || IS_845G(pI830)) && pI830->useSWF1) { + CARD32 newSWF1; + + /* Need MMIO access here. */ + mapped = (pI830->MMIOBase != NULL); if (!mapped) I830MapMMIO(pScrn); + + if (newSize <= KB(832)) + newSWF1 = 1; + else + newSWF1 = 8; + swf1 = INREG(SWF1); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Before: SWF1 is 0x%08x\n", swf1); swf1 &= ~0x0f; - swf1 |= (pVesa->newSWF1 & 0x0f); + swf1 |= (newSWF1 & 0x0f); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "After: SWF1 is 0x%08x\n", swf1); OUTREG(SWF1, swf1); if (!mapped) I830UnmapMMIO(pScrn); @@ -705,7 +1183,15 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, static void PreInitCleanup(ScrnInfoPtr pScrn) { + I830Ptr pI830 = I830PTR(pScrn); + RestoreBIOSMemSize(pScrn); + if (pI830->swfSaved) { + OUTREG(SWF0, pI830->saveSWF0); + OUTREG(SWF4, pI830->saveSWF4); + } + if (pI830->MMIOBase) + I830UnmapMMIO(pScrn); I830BIOSFreeRec(pScrn); } @@ -716,14 +1202,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) I830Ptr pI830; MessageType from; rgb defaultWeight = { 0, 0, 0 }; - VESAPtr pVesa; vbeInfoPtr pVbe; - DisplayModePtr p, *pp, tmp; EntityInfoPtr pEnt; - int mem; + int mem, memsize; int flags24; - int i = 0; + int i, n; pointer pDDCModule, pVBEModule; + Bool enable; + const char *chipname; if (pScrn->numEntities != 1) return FALSE; @@ -817,19 +1303,56 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) /* We have to use PIO to probe, because we haven't mapped yet. */ I830SetPIOAccess(pI830); - pVesa = pI830->vesa; - pVesa->useDefaultRefresh = FALSE; - /* Initialize VBE record */ - - if ((pVesa->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) { + if ((pI830->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VBE initialization failed.\n"); return FALSE; } - pVbe = pVesa->pVbe; + switch (pI830->PciInfo->chipType) { + case PCI_CHIP_I830_M: + chipname = "830M"; + break; + case PCI_CHIP_845_G: + chipname = "845G"; + break; + case PCI_CHIP_I855_GM: + /* Check capid register to find the chipset variant */ + pI830->variant = (pciReadLong(pI830->PciTag, I85X_CAPID) + >> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK; + switch (pI830->variant) { + case I855_GM: + chipname = "855GM"; + break; + case I855_GME: + chipname = "855GME"; + break; + case I852_GM: + chipname = "852GM"; + break; + case I852_GME: + chipname = "852GME"; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Unknown 852GM/855GM variant: 0x%x)\n", pI830->variant); + chipname = "852GM/855GM (unknown variant)"; + break; + } + break; + case PCI_CHIP_I865_G: + chipname = "865G"; + break; + default: + chipname = "unknown chipset"; + break; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Integrated Graphics Chipset: Intel(R) %s\n", chipname); + + pVbe = pI830->pVbe; - pVesa->vbeInfo = VBEGetVBEInfo(pVbe); + pI830->vbeInfo = VBEGetVBEInfo(pVbe); /* Set the Chipset and ChipRev, allowing config file entries to override. */ if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) { @@ -892,6 +1415,22 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", (unsigned long)pI830->MMIOAddr); + /* Some of the probing needs MMIO access, so map it here. */ + I830MapMMIO(pScrn); + +#if 1 + pI830->saveSWF0 = INREG(SWF0); + pI830->saveSWF4 = INREG(SWF4); + pI830->swfSaved = TRUE; + + /* Set "extended desktop" */ + OUTREG(SWF0, pI830->saveSWF0 | (1 << 21)); + + /* Set "driver loaded", "OS unknown", "APM 1.2" */ + OUTREG(SWF4, (pI830->saveSWF4 & ~((3 << 19) | (7 << 16))) | + (1 << 23) | (2 << 16)); +#endif + if (IS_I830(pI830) || IS_845G(pI830)) { PCITAG bridge; CARD16 gmch_ctrl; @@ -904,6 +1443,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->FbMapSize = 0x4000000; } } + else { + /* 128MB aperture for later chips */ + pI830->FbMapSize = 0x8000000; + } /* * Get the pre-allocated (stolen) memory size. @@ -913,40 +1456,18 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->StolenMemory.End = pI830->StolenMemory.Size; /* Sanity check: compare with what the BIOS thinks. */ - if (pVesa->vbeInfo->TotalMemory != pI830->StolenMemory.Size / 1024 / 64) { + if (pI830->vbeInfo->TotalMemory != pI830->StolenMemory.Size / 1024 / 64) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Detected stolen memory (%dKB) doesn't match what the BIOS" - " reports (%dKB)\n", - pI830->StolenMemory.Size / 1024 / 64 * 64, - pVesa->vbeInfo->TotalMemory * 64); - } - - /* - * The "VideoRam" config file parameter specifies the total amount of - * memory that will be used/allocated. When agpgart support isn't - * available (StolenOnly == TRUE), this is limited to the amount of - * pre-allocated ("stolen") memory. - */ - - /* - * Default to I830_DEFAULT_VIDEOMEM (8192KB). - */ - if (!pI830->pEnt->device->videoRam) { - from = X_DEFAULT; - pScrn->videoRam = I830_DEFAULT_VIDEOMEM; - } else { - from = X_CONFIG; - pScrn->videoRam = pI830->pEnt->device->videoRam; + "Detected stolen memory (%d kB) doesn't match what the BIOS" + " reports (%d kB)\n", + ROUND_DOWN_TO(pI830->StolenMemory.Size / 1024, 64), + pI830->vbeInfo->TotalMemory * 64); } /* Find the maximum amount of agpgart memory available. */ mem = I830CheckAvailableMemory(pScrn); pI830->StolenOnly = FALSE; - DPRINTF(PFX, - "Available memory: %dk\n" - "Requested memory: %dk\n", mem, pScrn->videoRam); - if (mem <= 0) { if (pI830->StolenMemory.Size <= 0) { /* Shouldn't happen. */ @@ -964,41 +1485,135 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) mem = 0; pI830->StolenOnly = TRUE; } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { + pI830->noAccel = TRUE; + } + if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { + pI830->SWCursor = TRUE; + } + + pI830->directRenderingDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); + +#ifdef XF86DRI + if (!pI830->directRenderingDisabled) { + if (pI830->noAccel || pI830->SWCursor) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " + "needs HW cursor and 2D acceleration.\n"); + pI830->directRenderingDisabled = TRUE; + } else if (pScrn->depth != 16 && pScrn->depth != 24) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " + "runs only at depths 16 and 24.\n"); + pI830->directRenderingDisabled = TRUE; + } + } +#endif + + /* + * The "VideoRam" config file parameter specifies the total amount of + * memory that will be used/allocated. When agpgart support isn't + * available (StolenOnly == TRUE), this is limited to the amount of + * pre-allocated ("stolen") memory. + */ + + /* + * Default to I830_DEFAULT_VIDEOMEM_2D (8192KB) for 2D-only, + * or I830_DEFAULT_VIDEOMEM_3D (32768KB) for 3D. If the stolen memory + * amount is higher, default to it rounded up to the nearest MB. This + * guarantees that by default there will be at least some run-time + * space for things that need a physical address. + */ + if (!pI830->pEnt->device->videoRam) { + from = X_DEFAULT; +#ifdef XF86DRI + if (!pI830->directRenderingDisabled) + pScrn->videoRam = I830_DEFAULT_VIDEOMEM_3D; + else +#endif + pScrn->videoRam = I830_DEFAULT_VIDEOMEM_2D; + if (pI830->StolenMemory.Size / 1024 > pScrn->videoRam) + pScrn->videoRam = ROUND_TO(pI830->StolenMemory.Size / 1024, 1024); + } else { + from = X_CONFIG; + pScrn->videoRam = pI830->pEnt->device->videoRam; + } + + DPRINTF(PFX, + "Available memory: %dk\n" + "Requested memory: %dk\n", mem, pScrn->videoRam); + + if (mem + (pI830->StolenMemory.Size / 1024) < pScrn->videoRam) { pScrn->videoRam = mem + (pI830->StolenMemory.Size / 1024); from = X_PROBED; if (mem + (pI830->StolenMemory.Size / 1024) < pI830->pEnt->device->videoRam) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam reduced to %dK\n", pScrn->videoRam); + "VideoRAM reduced to %d kByte " + "(limited to available sysmem)\n", pScrn->videoRam); } } + + if (pScrn->videoRam > pI830->FbMapSize / 1024) { + pScrn->videoRam = pI830->FbMapSize / 1024; + if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRam reduced to %d kByte (limited to aperture size)\n", + pScrn->videoRam); + } + if (mem > 0) { /* * If the reserved (BIOS accessible) memory is less than the desired - * mimimum, try to increase it. We only know how to do this for the - * 845G (and 830?) so far. + * amount, try to increase it. So far this is only implemented for + * the 845G and 830, but those details are handled in SetBIOSMemSize(). + * + * The BIOS-accessible amount is only important for setting video + * modes. The maximum amount we try to set is limited to what would + * be enough for 1920x1440 with a 2048 pitch. + * + * If ALLOCATE_ALL_BIOSMEM is enabled in i830_memory.c, all of the + * BIOS-aware memory will get allocated. If it isn't then it may + * not be, and in that case there is an assumption that the video + * BIOS won't attempt to access memory beyond what is needed for + * modes that are actually used. ALLOCATE_ALL_BIOSMEM is enabled by + * default. */ - if (IS_I830(pI830) || IS_845G(pI830)) { - if (pVesa->vbeInfo->TotalMemory * 64 < pScrn->videoRam && - pVesa->vbeInfo->TotalMemory * 64 < I830_MINIMUM_VBIOS_MEM) { - CARD32 swf1; - - I830MapMMIO(pScrn); - SaveBIOSMemSize(pScrn); - swf1 = INREG(SWF1); - ErrorF("Before: SWF1 is 0x%08x\n", swf1); - pVesa->newSWF1 = 0x08; - pVesa->overrideBIOSMemSize = TRUE; - SetBIOSMemSize(pScrn); - swf1 = INREG(SWF1); - ErrorF("After: SWF1 is 0x%08x\n", swf1); - VBEFreeVBEInfo(pVesa->vbeInfo); - vbeFree(pVesa->pVbe); - pVesa->pVbe = VBEInit(NULL, pI830->pEnt->index); - pVbe = pVesa->pVbe; - pVesa->vbeInfo = VBEGetVBEInfo(pVbe); - I830UnmapMMIO(pScrn); + + /* Try to keep HW cursor and Overlay amounts separate from this. */ + int reserve = (HWCURSOR_SIZE + OVERLAY_SIZE) / 1024; + + if (pScrn->videoRam - reserve >= I830_MAXIMUM_VBIOS_MEM) + pI830->newBIOSMemSize = KB(I830_MAXIMUM_VBIOS_MEM); + else + pI830->newBIOSMemSize = + KB(ROUND_DOWN_TO(pScrn->videoRam - reserve, 64)); + + if (pI830->vbeInfo->TotalMemory * 64 < pI830->newBIOSMemSize / 1024) { + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Will attempt to tell the BIOS that there is " + "%d kB VideoRAM\n", pI830->newBIOSMemSize / 1024); + + if (SaveBIOSMemSize(pScrn)) { + pI830->overrideBIOSMemSize = TRUE; + SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); + + VBEFreeVBEInfo(pI830->vbeInfo); + vbeFree(pI830->pVbe); + pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); + pVbe = pI830->pVbe; + pI830->vbeInfo = VBEGetVBEInfo(pVbe); + + pI830->BIOSMemorySize = KB(pI830->vbeInfo->TotalMemory * 64); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS now sees %d kB VideoRAM\n", + pI830->BIOSMemorySize / 1024); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS view of memory size can't be changed " + "(this is not an error).\n"); } } } @@ -1008,25 +1623,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam); pI830->TotalVideoRam = KB(pScrn->videoRam); - if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { - pI830->noAccel = TRUE; - } - if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { - pI830->SWCursor = TRUE; - } - - pI830->directRenderingDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); - -#ifdef XF86DRI - if (!pI830->directRenderingDisabled) { - if (pI830->noAccel || pI830->SWCursor) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " - "needs HW cursor and 2D acceleration.\n"); - pI830->directRenderingDisabled = TRUE; - } + /* + * If the requested videoRam amount is less than the stolen memory size, + * reduce the stolen memory size accordingly. + */ + if (pI830->StolenMemory.Size > pI830->TotalVideoRam) { + pI830->StolenMemory.Size = pI830->TotalVideoRam; + pI830->StolenMemory.End = pI830->TotalVideoRam; } -#endif if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, &(pI830->CacheLines))) { @@ -1036,6 +1640,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->CacheLines = -1; } + pI830->XvDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); + #ifdef I830_XV if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, &(pI830->colorKey))) { @@ -1053,7 +1660,16 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n", pI830->colorKey); #endif - + + pI830->allowPageFlip = FALSE; + enable = xf86ReturnOptValBool(pI830->Options, OPTION_PAGEFLIP, FALSE); +#ifdef XF86DRI + if (!pI830->directRenderingDisabled) { + pI830->allowPageFlip = enable; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "page flipping %s\n", + enable ? "enabled" : "disabled"); + } +#endif /* Check if the HW cursor needs physical address. */ if (IS_MOBILE(pI830)) @@ -1061,6 +1677,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) else pI830->CursorNeedsPhysical = FALSE; + /* Force ring buffer to be in low memory for the 845G. */ + if (IS_845G(pI830)) + pI830->NeedRingBufferLow = TRUE; + /* * XXX If we knew the pre-initialised GTT format for certain, we could * probably figure out the physical address even in the StolenOnly case. @@ -1077,6 +1697,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) */ if (!pI830->SWCursor) pScrn->videoRam -= (HWCURSOR_SIZE / 1024); + if (!pI830->XvDisabled) + pScrn->videoRam -= (OVERLAY_SIZE / 1024); if (!pI830->noAccel) { pScrn->videoRam -= (PRIMARY_RINGBUFFER_SIZE / 1024); pScrn->videoRam -= (MIN_SCRATCH_BUFFER_SIZE / 1024); @@ -1096,6 +1718,13 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } + if (IS_MOBILE(pI830)) + pI830->availablePipes = 2; + else + pI830->availablePipes = 1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", + pI830->availablePipes, pI830->availablePipes > 1 ? "s" : ""); + if (!I830DetectDisplayDevice(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't detect display devices.\n"); @@ -1106,16 +1735,19 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) if ((pDDCModule = xf86LoadSubModule(pScrn, "ddc")) == NULL) { PreInitCleanup(pScrn); return FALSE; - } else { - if ((pVesa->monitor = vbeDoEDID(pVbe, pDDCModule)) != NULL) { - xf86PrintEDID(pVesa->monitor); - } - xf86UnloadSubModule(pDDCModule); } + if ((pI830->vesa->monitor = vbeDoEDID(pVbe, pDDCModule)) != NULL) { + xf86PrintEDID(pI830->vesa->monitor); + } + if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL) + xf86SetDDCproperties(pScrn, pI830->vesa->monitor); + xf86UnloadSubModule(pDDCModule); + /* XXX Move this to a header. */ #define VIDEO_BIOS_SCRATCH 0x18 +#if 1 /* * XXX This should be in ScreenInit/EnterVT. PreInit should not leave the * state changed. @@ -1132,28 +1764,29 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) */ pI830->writeControl(pI830, GRX, VIDEO_BIOS_SCRATCH, gr18); } +#endif - if ((pScrn->monitor->DDC = pVesa->monitor) != NULL) - xf86SetDDCproperties(pScrn, pVesa->monitor); - - for (i = 0; i < 2; i++) { - if (pI830->pipeDevices[i] & (PIPE_ACTIVE_MASK & ~PIPE_CRT_ACTIVE)) { + for (i = 0; i < pI830->availablePipes; i++) { + int pipe = + (pI830->configuredDevices >> PIPE_SHIFT(i)) & PIPE_ACTIVE_MASK; + if (pipe & ~PIPE_CRT_ACTIVE) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "A non-CRT device is attached to pipe %c.\n" "\tNo refresh rate overrides will be attempted.\n", - 'A' + i); - pVesa->useDefaultRefresh = TRUE; + PIPE_NAME(i)); + pI830->vesa->useDefaultRefresh = TRUE; } + /* + * Some desktop platforms might not have 0x5f05, so useExtendedRefresh + * would need to be set to FALSE for those cases. + */ + if (!pI830->vesa->useDefaultRefresh) + pI830->useExtendedRefresh = TRUE; } - /* - * Some desktop platforms might not have 0x5f05. - */ - pVesa->useExtendedRefresh = !pVesa->useDefaultRefresh; - if (pVesa->useExtendedRefresh) { + if (pI830->useExtendedRefresh) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Will use BIOS call 0x5f05 to set non-default refresh " - "rates.\n"); + "Will use BIOS call 0x5f05 to set refresh rates for CRTs.\n"); } /* @@ -1161,71 +1794,39 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) * using 0x5f05, or when not overriding the default refresh rate. * Also, 0x5f64 doesn't work correctly in i830 platforms. */ - pVesa->enableDisplays = !IS_I830(pI830) && - (pVesa->useDefaultRefresh || - pVesa->useExtendedRefresh); - if (pVesa->enableDisplays) { + pI830->enableDisplays = !IS_I830(pI830) && pI830->useExtendedRefresh; + + if (pI830->enableDisplays) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Will use BIOS call 0x5f64 to enable displays.\n"); } /* - * XXX This code is different from the previous 830/845 code because - * it uses a new VBE module function (if present, or a local copy of - * it if not) to get the list of modes. It then uses the 5f28 extended - * function as a final check if it's valid for the current display - * device. + * Limit videoram available for mode selection to what the video + * BIOS can see. */ + if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64)) + memsize = pI830->vbeInfo->TotalMemory * 64; + else + memsize = pScrn->videoRam; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Maximum space available for video modes: %d kByte\n", memsize); /* - * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS functions. - * For that reason it's important to set only V_MODETYPE_VGA in the - * flags for VBEGetModePool(). + * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS + * functions. For that reason it's important to set only + * V_MODETYPE_VGA in the flags for VBEGetModePool(). */ - pScrn->modePool = VBEGetModePool(pScrn, pVbe, pVesa->vbeInfo, + pScrn->modePool = VBEGetModePool(pScrn, pVbe, pI830->vbeInfo, V_MODETYPE_VGA); - if (pScrn->modePool == NULL) { + if (!pScrn->modePool) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No Video BIOS modes for chosen depth.\n"); PreInitCleanup(pScrn); return FALSE; } -#if 1 - pp = &(pScrn->modePool); - p = pScrn->modePool; - while (p) { - VbeModeInfoData *data = (VbeModeInfoData *) p->Private; - - if (!(data->mode & 0x100)) { - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f28; - pVbe->pInt10->bx = 0x8000 | (data->mode & 0x7f); - pVbe->pInt10->cx = 0x8000; /* Current display device */ - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - } - tmp = p->next; - if (!(data->mode & 0x100) && pVbe->pInt10->ax != 0x005f) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "BIOS mode %x is rejected by 0x5f28.\n", data->mode); - xfree(p->Private); - *pp = p->next; - xfree(p); - } else { - pp = &(p->next); - } - p = tmp; - } -#endif - - if (pScrn->modePool == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No Video BIOS modes suitable for the display.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - VBESetModeNames(pScrn->modePool); /* @@ -1235,69 +1836,151 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) * there's code in vesa/vesa.c. */ + /* XXX Need to get relevant modes and virtual parameters. */ + /* Do the mode validation without regard to special scanline pitches. */ + n = VBEValidateModes(pScrn, NULL, pScrn->display->modes, NULL, + NULL, 0, MAX_DISPLAY_PITCH, 1, + 0, MAX_DISPLAY_HEIGHT, + pScrn->display->virtualX, + pScrn->display->virtualY, + memsize, LOOKUP_BEST_REFRESH); + if (n <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + xf86PruneDriverModes(pScrn); + + pScrn->currentMode = pScrn->modes; + + if (pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); + PreInitCleanup(pScrn); + return FALSE; + } + #ifndef USE_PITCHES -#define USE_PITCHES 0 +#define USE_PITCHES 1 #endif - { -#if USE_PITCHES + /* + * If DRI is potentially usable, check if there is enough memory available + * for it, and if there's also enough to allow tiling to be enabled. + */ +#if defined(XF86DRI) + if (!pI830->directRenderingDisabled) { + int savedDisplayWidth = pScrn->displayWidth; + int memNeeded = 0; /* Good pitches to allow tiling. Don't care about pitches < 256. */ - int i830_pitches[] = { + static const int pitches[] = { 128 * 2, 128 * 4, 128 * 8, 128 * 16, + 128 * 32, + 128 * 64, 0 - }; -#endif + }; - int memsize; - int *linePitches = NULL; +#ifdef I830_XV + /* + * Set this so that the overlay allocation is factored in when + * appropriate. + */ + pI830->XvEnabled = !pI830->XvDisabled; +#endif -#if USE_PITCHES && defined(XF86DRI) - if (!pI830->directRenderingDisabled) - linePitches = i830_pitches; + for (i = 0; pitches[i] != 0; i++) { +#if USE_PITCHES + if (pitches[i] >= pScrn->displayWidth) { + pScrn->displayWidth = pitches[i]; + break; + } +#else + if (pitches[i] == pScrn->displayWidth) + break; #endif + } /* - * Limit videoram available for mode selection to what the video - * BIOS can see. + * If the displayWidth is a tilable pitch, test if there's enough + * memory available to enable tiling. */ - if (pScrn->videoRam > (pVesa->vbeInfo->TotalMemory * 64)) - memsize = pVesa->vbeInfo->TotalMemory * 64; - else - memsize = pScrn->videoRam; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Maximum space available for video modes: %d Kbyte\n", - memsize); - - i = VBEValidateModes(pScrn, NULL, pScrn->display->modes, NULL, - linePitches, 0, MAX_DISPLAY_PITCH, 1, - 0, MAX_DISPLAY_HEIGHT, - pScrn->display->virtualX, - pScrn->display->virtualY, - memsize, LOOKUP_BEST_REFRESH); - } - - if (i <= 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes\n"); - PreInitCleanup(pScrn); - return FALSE; - } - - xf86PruneDriverModes(pScrn); - - pScrn->currentMode = pScrn->modes; - - if (pScrn->modes == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes\n"); - PreInitCleanup(pScrn); - return FALSE; + if (pScrn->displayWidth == pitches[i]) { + I830ResetAllocations(pScrn, 0); + if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) && + I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN)) { + memNeeded = I830GetExcessMemoryAllocations(pScrn); + if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { + if (memNeeded > 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%d kBytes additional video memory is " + "required to\n\tenable tiling mode for DRI.\n", + (memNeeded + 1023) / 1024); + } + if (pI830->MemoryAperture.Size < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Allocation with DRI tiling enabled would " + "exceed the\n" + "\tmemory aperture size (%d kB) by %d kB.\n" + "\tReduce VideoRam amount to avoid this!\n", + pI830->FbMapSize / 1024, + -pI830->MemoryAperture.Size / 1024); + } + pScrn->displayWidth = savedDisplayWidth; + pI830->allowPageFlip = FALSE; + } else if (pScrn->displayWidth != savedDisplayWidth) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Increasing the scanline pitch to allow tiling mode " + "(%d -> %d).\n", + savedDisplayWidth, pScrn->displayWidth); + } + } else { + memNeeded = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unexpected dry run allocation failure (1).\n"); + } + } + if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { + /* + * Tiling can't be enabled. Check if there's enough memory for DRI + * without tiling. + */ + I830ResetAllocations(pScrn, 0); + if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) && + I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_NO_TILING)) { + memNeeded = I830GetExcessMemoryAllocations(pScrn); + if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { + if (memNeeded > 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%d kBytes additional video memory is required " + "to enable DRI.\n", + (memNeeded + 1023) / 1024); + } + if (pI830->MemoryAperture.Size < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Allocation with DRI enabled would " + "exceed the\n" + "\tmemory aperture size (%d kB) by %d kB.\n" + "\tReduce VideoRam amount to avoid this!\n", + pI830->FbMapSize / 1024, + -pI830->MemoryAperture.Size / 1024); + } + pI830->directRenderingDisabled = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unexpected dry run allocation failure (2).\n"); + } + } } +#endif VBEPrintModes(pScrn); - if (!pVesa->useDefaultRefresh) { + if (!pI830->vesa->useDefaultRefresh) { /* * This sets the parameters for the VBE modes according to the best * usable parameters from the Monitor sections modes (usually the @@ -1311,6 +1994,13 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) /* PreInit shouldn't leave any state changes, so restore this. */ RestoreBIOSMemSize(pScrn); + /* Don't need MMIO access anymore. */ + if (pI830->swfSaved) { + OUTREG(SWF0, pI830->saveSWF0); + OUTREG(SWF4, pI830->saveSWF4); + } + I830UnmapMMIO(pScrn); + /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); @@ -1343,9 +2033,19 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr); xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr); - VBEFreeVBEInfo(pVesa->vbeInfo); + VBEFreeVBEInfo(pI830->vbeInfo); vbeFree(pVbe); +#if defined(XF86DRI) + if (!pI830->directRenderingDisabled) { + if (!xf86LoadSubModule(pScrn, "shadow")) { + PreInitCleanup(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(I810shadowSymbols, NULL); + } +#endif + return TRUE; } @@ -1404,18 +2104,20 @@ CheckInheritedState(ScrnInfoPtr pScrn) * whoever gets control next should do. */ static void -ResetState(ScrnInfoPtr pScrn) +ResetState(ScrnInfoPtr pScrn, Bool flush) { I830Ptr pI830 = I830PTR(pScrn); int i; unsigned long temp; + DPRINTF(PFX, "ResetState: flush is %s\n", BOOLTOSTRING(flush)); + /* Reset the fence registers to 0 */ for (i = 0; i < 8; i++) OUTREG(FENCE + i * 4, 0); /* Flush the ring buffer (if enabled), then disable it. */ - if (pI830->AccelInfoRec != NULL) { + if (pI830->AccelInfoRec != NULL && flush) { temp = INREG(LP_RING + RING_LEN); if (temp & 1) { I830RefreshRing(pScrn); @@ -1438,6 +2140,8 @@ SetFenceRegs(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); int i; + DPRINTF(PFX, "SetFenceRegs\n"); + for (i = 0; i < 8; i++) { OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]); if (I810_DEBUG & DEBUG_VERBOSE_VGA) @@ -1451,6 +2155,8 @@ SetRingRegs(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); unsigned int itemp; + DPRINTF(PFX, "SetRingRegs\n"); + if (pI830->noAccel) return; @@ -1479,6 +2185,7 @@ SetRingRegs(ScrnInfoPtr pScrn) itemp = (pI830->LpRing.mem.Size - 4096) & I830_RING_NR_PAGES; itemp |= (RING_NO_REPORT | RING_VALID); OUTREG(LP_RING + RING_LEN, itemp); + I830RefreshRing(pScrn); } /* @@ -1491,6 +2198,7 @@ SetHWOperatingState(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, "SetHWOperatingState\n"); + if (!pI830->noAccel) SetRingRegs(pScrn); SetFenceRegs(pScrn); @@ -1502,14 +2210,25 @@ static Bool SaveHWState(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - VESAPtr pVesa = pI830->vesa; - vbeInfoPtr pVbe = pVesa->pVbe; + vbeInfoPtr pVbe = pI830->pVbe; vgaHWPtr hwp = VGAHWPTR(pScrn); vgaRegPtr vgaReg = &hwp->SavedReg; + VbeModeInfoBlock *modeInfo; + VESAPtr pVesa; DPRINTF(PFX, "SaveHWState\n"); + + pVesa = pI830->vesa; /* Make sure we save at least this information in case of failure. */ - VBEGetVBEMode(pVesa->pVbe, &pVesa->stateMode); + VBEGetVBEMode(pVbe, &pVesa->stateMode); + modeInfo = VBEGetModeInfo(pVbe, pVesa->stateMode); + pVesa->savedScanlinePitch = 0; + if (modeInfo) { + if (VBE_MODE_GRAPHICS(modeInfo)) { + VBEGetLogicalScanline(pVbe, &pVesa->savedScanlinePitch, NULL, NULL); + } + VBEFreeModeInfo(modeInfo); + } vgaHWUnlock(hwp); vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS); @@ -1517,23 +2236,42 @@ SaveHWState(ScrnInfoPtr pScrn) #ifndef I845G_VBE_WORKAROUND #define I845G_VBE_WORKAROUND 1 #endif + + pVesa = pI830->vesa; /* This save/restore method doesn't work for 845G BIOS */ - /* XXX If it's fixed in production versions, this could be removed. */ + /* + * XXX If it's fixed in production versions, this could be removed. + * + * KW: This may have been because of the behaviour I've found on my + * board: The 'save' command actually modifies the interrupt + * registers, turning off the irq & breaking the kernel module + * behaviour. + */ if (!I845G_VBE_WORKAROUND || !IS_845G(pI830)) { + CARD16 imr = INREG16(IMR); + CARD16 ier = INREG16(IER); + CARD16 hwstam = INREG16(HWSTAM); + if (!VBESaveRestore(pVbe, MODE_SAVE, &pVesa->state, &pVesa->stateSize, &pVesa->statePage)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "SaveHWState: VBESaveRestore(MODE_SAVE) failed\n"); + "SaveHWState: VBESaveRestore(MODE_SAVE) failed.\n"); return FALSE; } + + OUTREG16(IMR, imr); + OUTREG16(IER, ier); + OUTREG16(HWSTAM, hwstam); } + pVesa->savedPal = VBESetGetPaletteData(pVbe, FALSE, 0, 256, - NULL, FALSE, FALSE); + NULL, FALSE, FALSE); if (!pVesa->savedPal) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "SaveHWState: VBESetGetPaletteData(GET) failed\n"); + "SaveHWState: VBESetGetPaletteData(GET) failed.\n"); return FALSE; } + return TRUE; } @@ -1541,14 +2279,47 @@ static Bool RestoreHWState(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - VESAPtr pVesa = pI830->vesa; - vbeInfoPtr pVbe = pVesa->pVbe; + vbeInfoPtr pVbe = pI830->pVbe; vgaHWPtr hwp = VGAHWPTR(pScrn); vgaRegPtr vgaReg = &hwp->SavedReg; + VESAPtr pVesa; Bool restored = FALSE; DPRINTF(PFX, "RestoreHWState\n"); + + pVesa = pI830->vesa; + + /* + * Workaround for text mode restoration with some flat panels. + * Temporarily program a 640x480 mode before switching back to + * text mode. + */ + if (pVesa->useDefaultRefresh) { + int mode = 0; + + switch (pScrn->depth) { + case 8: + mode = 0x30; + break; + case 15: + mode = 0x40; + break; + case 16: + mode = 0x41; + break; + case 24: + mode = 0x50; + break; + } + mode |= (1 << 15) | (1 << 14); + I830VESASetVBEMode(pScrn, mode, NULL); + } + if (pVesa->state && pVesa->stateSize) { + CARD16 imr = INREG16(IMR); + CARD16 ier = INREG16(IER); + CARD16 hwstam = INREG16(HWSTAM); + /* Make a copy of the state. Don't rely on it not being touched. */ if (!pVesa->pstate) { pVesa->pstate = xalloc(pVesa->stateSize); @@ -1556,14 +2327,18 @@ RestoreHWState(ScrnInfoPtr pScrn) memcpy(pVesa->pstate, pVesa->state, pVesa->stateSize); } restored = VBESaveRestore(pVbe, MODE_RESTORE, &pVesa->state, - &pVesa->stateSize, &pVesa->statePage); + &pVesa->stateSize, &pVesa->statePage); if (!restored) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "RestoreHWState: VBESaveRestore failed\n"); + "RestoreHWState: VBESaveRestore failed.\n"); } /* Copy back */ if (pVesa->pstate) memcpy(pVesa->state, pVesa->pstate, pVesa->stateSize); + + OUTREG16(IMR, imr); + OUTREG16(IER, ier); + OUTREG16(HWSTAM, hwstam); } /* If that failed, restore the original mode. */ if (!restored) { @@ -1572,6 +2347,8 @@ RestoreHWState(ScrnInfoPtr pScrn) "the saved state\n"); I830VESASetVBEMode(pScrn, pVesa->stateMode, NULL); } + if (pVesa->savedScanlinePitch) + VBESetLogicalScanline(pVbe, pVesa->savedScanlinePitch); if (pVesa->savedPal) VBESetGetPaletteData(pVbe, TRUE, 0, 256, pVesa->savedPal, FALSE, TRUE); @@ -1581,63 +2358,48 @@ RestoreHWState(ScrnInfoPtr pScrn) return TRUE; } +#ifndef USE_VBE +#define USE_VBE 1 +#endif + static Bool I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block) { - I830Ptr pI830; - Bool ret; - -#ifdef DEBUGSWF - CARD32 swf, offset; -#endif + I830Ptr pI830 = I830PTR(pScrn); - pI830 = I830PTR(pScrn); -#ifdef DEBUGSWF - for (offset = SWF00; offset <= SWF06; offset += 4) { - swf = INREG(offset); - ErrorF("SWF0%d is 0x%08x\n", (offset - SWF00) / 4, swf); - } - for (offset = SWF10; offset <= SWF16; offset += 4) { - swf = INREG(offset); - ErrorF("SWF1%d is 0x%08x\n", (offset - SWF10) / 4, swf); - } - for (offset = SWF30; offset <= SWF32; offset += 4) { - swf = INREG(offset); - ErrorF("SWF3%d is 0x%08x\n", (offset - SWF30) / 4, swf); - } -#endif DPRINTF(PFX, "Setting mode 0x%.8x\n", mode); - ret = VBESetVBEMode(pI830->vesa->pVbe, mode, block); -#ifdef DEBUGSWF - for (offset = SWF00; offset <= SWF06; offset += 4) { - swf = INREG(offset); - ErrorF("SWF0%d is 0x%08x\n", (offset - SWF00) / 4, swf); - } - for (offset = SWF10; offset <= SWF16; offset += 4) { - swf = INREG(offset); - ErrorF("SWF1%d is 0x%08x\n", (offset - SWF10) / 4, swf); - } - for (offset = SWF30; offset <= SWF32; offset += 4) { - swf = INREG(offset); - ErrorF("SWF3%d is 0x%08x\n", (offset - SWF30) / 4, swf); +#if USE_VBE + return VBESetVBEMode(pI830->pVbe, mode, block); +#else + { + vbeInfoPtr pVbe = pI830->pVbe; + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x80 | (mode & 0x7f); + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + pVbe->pInt10->ax = 0x0f00; + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if ((pVbe->pInt10->ax & 0x7f) == (mode & 0x7f)) + return TRUE; + else + return FALSE; } #endif - return ret; } static Bool I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) { - I830Ptr pI830; - VESAPtr pVesa; - vbeInfoPtr pVbe; + I830Ptr pI830 = I830PTR(pScrn); + vbeInfoPtr pVbe = pI830->pVbe; VbeModeInfoData *data; - int mode; + int mode, i; CARD32 planeA, planeB, temp; + int refresh = 60; +#ifdef XF86DRI + Bool didLock = FALSE; +#endif - pI830 = I830PTR(pScrn); - pVesa = pI830->vesa; - pVbe = pI830->vesa->pVbe; + DPRINTF(PFX, "I830VESASetMode\n"); data = (VbeModeInfoData *) pMode->Private; @@ -1645,9 +2407,10 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) mode = data->mode | (1 << 15) | (1 << 14); #ifdef XF86DRI - if (pI830->directRenderingEnabled) { + if (pI830->directRenderingEnabled && !pI830->LockHeld) { DRILock(screenInfo.screens[pScrn->scrnIndex], 0); pI830->LockHeld = 1; + didLock = TRUE; } #endif @@ -1655,33 +2418,19 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) #define MODESWITCH_RESET_STATE 0 #endif #if MODESWITCH_RESET_STATE - ResetState(pScrn); + ResetState(pScrn, TRUE); #endif /* XXX Add macros for the various mode parameter bits. */ - if (pVesa->useDefaultRefresh) + if (pI830->vesa->useDefaultRefresh) mode &= ~(1 << 11); -#if 0 - /* Turn on the configured displays */ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x0001; - pVbe->pInt10->cx = (CARD16)pI830->configuredDevices; - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - - if (pVbe->pInt10->ax != 0x005f) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to switch to configured display devices\n"); - } -#endif - if (I830VESASetVBEMode(pScrn, mode, data->block) == FALSE) { if ((data->block && (mode & (1 << 11))) && I830VESASetVBEMode(pScrn, (mode & ~(1 << 11)), NULL) == TRUE) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Set VBE Mode rejected this modeline. " + "Set VBE Mode rejected this modeline.\n\t" "Trying standard mode instead!\n"); DPRINTF(PFX, "OOPS!\n"); xfree(data->block); @@ -1693,13 +2442,20 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) } } + /* + * The BIOS may not set a scanline pitch that would require more video + * memory than it's aware of. We check for this later, and set it + * explicitly if necessary. + */ if (data->data->XResolution != pScrn->displayWidth) VBESetLogicalScanline(pVbe, pScrn->displayWidth); - if (pScrn->bitsPerPixel >= 8 && pVesa->vbeInfo->Capabilities[0] & 0x01) + if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) VBESetGetDACPaletteFormat(pVbe, 8); /* + * XXX This location of this isn't correct. + * * Turn on the configured displays. This has the effect of resetting * the default refresh rates to values that the configured displays * can handle. This seems to be the safest way to make sure that this @@ -1710,14 +2466,8 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) * * XXX Need to test an 830 with a LFP. */ - if (pVesa->enableDisplays) { - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f64; - pVbe->pInt10->bx = 0x0001; - pVbe->pInt10->cx = (CARD16)pI830->configuredDevices; - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - - if (pVbe->pInt10->ax != 0x005f) { + if (pI830->enableDisplays) { + if (!SetDisplayDevices(pScrn, pI830->configuredDevices)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch to configured display devices\n"); } @@ -1725,46 +2475,20 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) /* * When it's OK to set better than default refresh rates, set them here. - * NOTE: pVesa->useDefaultRefresh is used redundantly here and in some - * other places. That redundancy may be removed one day. For now, - * keep it to be safe. */ - if (pVesa->useExtendedRefresh && !pVesa->useDefaultRefresh && + if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh && (mode & (1 << 11)) && data && data->data && data->block) { - static const int refreshes[] = { - 43, 56, 60, 70, 72, 75, 85, 100, 120 - }; - int i, nrefreshes = sizeof(refreshes) / sizeof(refreshes[0]); - - for (i = nrefreshes - 1; i >= 0; i--) { - /* - * Look for the highest value that the requested (refresh + 2) is - * greater than or equal to. - */ - if (refreshes[i] <= (data->block->RefreshRate / 100 + 2)) - break; - } - /* i can be 0 if the requested refresh was higher than the max. */ - if (i == 0) { - if (data->block->RefreshRate / 100 >= refreshes[nrefreshes - 1]) - i = nrefreshes - 1; - } - DPRINTF(PFX, "Setting refresh rate to %dHz for mode %d\n", - refreshes[i], mode & 0xff); - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x5f05; - pVbe->pInt10->bx = mode & 0xff; - pVbe->pInt10->cx = 1 << i; - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); - - if (pVbe->pInt10->ax != 0x5f) { + refresh = SetRefreshRate(pScrn, mode, data->block->RefreshRate / 100); + if (!refresh) { + refresh = 60; xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to set refresh rate to %dHz.\n", - refreshes[i]); + data->block->RefreshRate / 100); } } + /* XXX Fix plane A with pipe A, and plane B with pipe B. */ planeA = INREG(DSPACNTR); planeB = INREG(DSPBCNTR); @@ -1806,7 +2530,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) temp = INREG(DSPABASE); OUTREG(DSPABASE, temp); } - if (pI830->pipeEnabled[1]) { + if (pI830->planeEnabled[1]) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n"); planeB |= DISPLAY_PLANE_ENABLE; OUTREG(DSPBCNTR, planeB); @@ -1828,13 +2552,87 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08x\n", temp); } +#if PRINT_MODE_INFO + /* Print out some CRTC/display information. */ + temp = INREG(HTOTAL_A); + ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff, + (temp >> 16) & 0xfff); + temp = INREG(HBLANK_A); + ErrorF("Horiz blank start: %d, Horiz blank end: %d\n", temp & 0xfff, + (temp >> 16) & 0xfff); + temp = INREG(HSYNC_A); + ErrorF("Horiz sync start: %d, Horiz sync end: %d\n", temp & 0xfff, + (temp >> 16) & 0xfff); + temp = INREG(VTOTAL_A); + ErrorF("Vert active: %d, Vert total: %d\n", temp & 0x7ff, + (temp >> 16) & 0xfff); + temp = INREG(VBLANK_A); + ErrorF("Vert blank start: %d, Vert blank end: %d\n", temp & 0xfff, + (temp >> 16) & 0xfff); + temp = INREG(VSYNC_A); + ErrorF("Vert sync start: %d, Vert sync end: %d\n", temp & 0xfff, + (temp >> 16) & 0xfff); + temp = INREG(PIPEASRC); + ErrorF("Image size: %dx%d (%dx%d)\n", + (temp >> 16) & 0x7ff, temp & 0x7ff, + (((temp >> 16) & 0x7ff) + 1), ((temp & 0x7ff) + 1)); + ErrorF("Pixel multiply is %d\n", (planeA >> 20) & 0x3); + temp = INREG(DSPABASE); + ErrorF("Plane A start offset is %d\n", temp); + temp = INREG(DSPASTRIDE); + ErrorF("Plane A stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp); +#endif + + for (i = 0; i < MAX_DISPLAY_PIPES; i++) { + CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE; + CARD32 basereg = i ? DSPBBASE : DSPABASE; + + if (!pI830->planeEnabled[i]) + continue; + + temp = INREG(stridereg); + if (temp / pI830->cpp != pScrn->displayWidth) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(i), + temp / pI830->cpp, pScrn->displayWidth); + OUTREG(stridereg, pScrn->displayWidth * pI830->cpp); + /* Trigger update */ + temp = INREG(basereg); + OUTREG(basereg, temp); + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n", + pMode->HDisplay * pMode->VDisplay * refresh / 1000000); + + { + int maxBandwidth, bandwidthA, bandwidthB; + + if (GetModeSupport(pScrn, 0x80, 0x80, 0x80, 0x80, + &maxBandwidth, &bandwidthA, &bandwidthB)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "maxBandwidth is %d Mbyte/s, " + "pipe bandwidths are %d Mbyte/s, %d Mbyte/s\n", + maxBandwidth, bandwidthA, bandwidthB); + } + } + + { + int ret; + + ret = GetLFPCompMode(pScrn); + if (ret != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "LFP compensation mode: 0x%x\n", ret); + } + } + #if MODESWITCH_RESET_STATE - ResetState(pScrn); + ResetState(pScrn, TRUE); SetHWOperatingState(pScrn); #endif #ifdef XF86DRI - if (pI830->directRenderingEnabled) { + if (pI830->directRenderingEnabled && didLock) { DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); pI830->LockHeld = 0; } @@ -2078,7 +2876,6 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) ScrnInfoPtr pScrn; vgaHWPtr hwp; I830Ptr pI830; - VESAPtr pVesa; VisualPtr visual; #ifdef XF86DRI Bool driDisabled; @@ -2086,18 +2883,19 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); - pVesa = pI830->vesa; hwp = VGAHWPTR(pScrn); + pI830->starting = TRUE; + /* * If we're changing the BIOS's view of the video memory size, do that * first, then re-initialise the VBE information. */ - SetBIOSMemSize(pScrn); - pVesa->pVbe = VBEInit(NULL, pI830->pEnt->index); - if (!pVesa->pVbe) + pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); + SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); + if (!pI830->pVbe) return FALSE; - pVesa->vbeInfo = VBEGetVBEInfo(pVesa->pVbe); + pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); miClearVisualTypes(); if (!xf86SetDefaultVisual(pScrn, -1)) @@ -2115,10 +2913,8 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!miSetPixmapDepths()) return FALSE; - pI830->XvEnabled = - xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); - #ifdef I830_XV + pI830->XvEnabled = !pI830->XvDisabled; if (pI830->XvEnabled) { if (pI830->noAccel || pI830->StolenOnly) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Xv is disabled because it " @@ -2130,22 +2926,9 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - /* Allocate 2D memory */ - pI830->FreeMemory = pI830->TotalVideoRam - pI830->StolenMemory.Size; - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = pI830->FbMapSize; - pI830->MemoryAperture.Size = pI830->FbMapSize - pI830->StolenMemory.Size; - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; + I830ResetAllocations(pScrn, 0); - /* - * Force ring buffer to be in low memory for the 845G. - */ - if (IS_845G(pI830)) - pI830->NeedRingBufferLow = TRUE; - - I830Allocate2DMemory(pScrn, TRUE); + I830Allocate2DMemory(pScrn, ALLOC_INITIAL); if (!pI830->noAccel) { if (pI830->LpRing.mem.Size == 0) { @@ -2157,7 +2940,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } if (!pI830->SWCursor) { - if (pI830->CursorMem.Key == -1) { + if (pI830->CursorMem.Size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling HW cursor because the cursor memory " "allocation failed.\n"); @@ -2203,17 +2986,15 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - driDisabled = !pI830->directRenderingEnabled; if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIScreenInit(pScreen); if (pI830->directRenderingEnabled) - if (!(pI830->directRenderingEnabled = I830Allocate3DMemory(pScrn))) + if (!(pI830->directRenderingEnabled = I830Allocate3DMemory(pScrn, 0))) I830DRICloseScreen(pScreen); - - + #else pI830->directRenderingEnabled = FALSE; #endif @@ -2222,7 +3003,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * After the 3D allocations have been done, see if there's any free space * that can be added to the framebuffer allocation. */ - I830Allocate2DMemory(pScrn, FALSE); + I830Allocate2DMemory(pScrn, 0); DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n"); if (!I830DoPoolAllocation(pScrn, &(pI830->StolenPool))) @@ -2252,7 +3033,10 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!vgaHWMapMem(pScrn)) return FALSE; - DPRINTF(PFX, "assert( if(!I830BISEnterVT(scrnIndex, 0)) )\n"); + /* Clear SavedReg */ + memset(&pI830->SavedReg, 0, sizeof(pI830->SavedReg)); + + DPRINTF(PFX, "assert( if(!I830BIOSEnterVT(scrnIndex, 0)) )\n"); if (!I830BIOSEnterVT(scrnIndex, 0)) return FALSE; @@ -2344,14 +3128,8 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pI830->directRenderingEnabled) { pI830->directRenderingOpen = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Enabled\n"); - /* What about doing this on EnterVT too? */ /* Setup 3D engine */ -#if 1 I830EmitInvarientState(pScrn); -#endif -#if 0 - I830EmitInvarientState2(pScrn); -#endif } else { if (driDisabled) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Disabled\n"); @@ -2373,6 +3151,10 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830_dump_registers(pScrn); #endif #endif + + pI830->starting = FALSE; + pI830->closing = FALSE; + pI830->suspended = FALSE; return TRUE; } @@ -2383,11 +3165,14 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags) I830Ptr pI830; vbeInfoPtr pVbe; static int xoffset = 0, yoffset = 0; - static unsigned long adjustGeneration = 0; + static int adjustGeneration = -1; pScrn = xf86Screens[scrnIndex]; pI830 = I830PTR(pScrn); - pVbe = pI830->vesa->pVbe; + pVbe = pI830->pVbe; + + DPRINTF(PFX, "I830BIOSAdjustFrame: y = %d (+ %d), x = %d (+ %d)\n", + x, xoffset, y, yoffset); /* Calculate the offsets once per server generation. */ if (adjustGeneration != serverGeneration) { @@ -2396,8 +3181,6 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags) yoffset = (pScrn->fbOffset / pI830->cpp) / pScrn->displayWidth; } - DPRINTF(PFX, "y = %d (+ %d), x = %d (+ %d)\n", x, xoffset, y, yoffset); - if (OffsetFrame) { y = (pI830->FbMemBox.y2 - pScrn->currentMode->VDisplay); ErrorF("AdjustFrame: OffsetFrame is set, setting y to %d\n", y); @@ -2419,6 +3202,34 @@ I830BIOSFreeScreen(int scrnIndex, int flags) vgaHWFreeHWRec(xf86Screens[scrnIndex]); } +#ifndef SAVERESTORE_HWSTATE +#define SAVERESTORE_HWSTATE 0 +#endif + +#if SAVERESTORE_HWSTATE +static void +SaveHWOperatingState(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + I830RegPtr save = &pI830->SavedReg; + + DPRINTF(PFX, "SaveHWOperatingState\n"); + + return; +} + +static void +RestoreHWOperatingState(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + I830RegPtr save = &pI830->SavedReg; + + DPRINTF(PFX, "RestoreHWOperatingState\n"); + + return; +} +#endif + static void I830BIOSLeaveVT(int scrnIndex, int flags) { @@ -2437,7 +3248,12 @@ I830BIOSLeaveVT(int scrnIndex, int flags) } #endif - ResetState(pScrn); +#if SAVERESTORE_HWSTATE + if (!pI830->closing) + SaveHWOperatingState(pScrn); +#endif + + ResetState(pScrn, TRUE); RestoreHWState(pScrn); RestoreBIOSMemSize(pScrn); I830UnbindGARTMemory(pScrn); @@ -2451,7 +3267,7 @@ I830BIOSEnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); - static unsigned long SaveGeneration = 0; + static int SaveGeneration = -1; DPRINTF(PFX, "Enter VT\n"); @@ -2459,7 +3275,8 @@ I830BIOSEnterVT(int scrnIndex, int flags) return FALSE; CheckInheritedState(pScrn); - SetBIOSMemSize(pScrn); + SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); + /* * Only save state once per server generation since that's what most * drivers do. Could change this to save state at each VT enter. @@ -2468,9 +3285,9 @@ I830BIOSEnterVT(int scrnIndex, int flags) SaveGeneration = serverGeneration; SaveHWState(pScrn); } - ResetState(pScrn); + ResetState(pScrn, FALSE); SetHWOperatingState(pScrn); - + #if 1 /* Clear the framebuffer */ memset(pI830->FbBase + pScrn->fbOffset, 0, @@ -2479,16 +3296,30 @@ I830BIOSEnterVT(int scrnIndex, int flags) if (!I830VESASetMode(pScrn, pScrn->currentMode)) return FALSE; +#ifdef I830_XV + I830VideoSwitchModeAfter(pScrn, pScrn->currentMode); +#endif - ResetState(pScrn); + ResetState(pScrn, TRUE); SetHWOperatingState(pScrn); pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); +#if SAVERESTORE_HWSTATE + RestoreHWOperatingState(pScrn); +#endif + #ifdef XF86DRI if (pI830->directRenderingEnabled) { - DPRINTF(PFX, "calling dri unlock\n"); - DRIUnlock(screenInfo.screens[scrnIndex]); + if (!pI830->starting) { + I830EmitInvarientState(pScrn); + I830RefreshRing(pScrn); + I830Sync(pScrn); + DO_RING_IDLE(); + + DPRINTF(PFX, "calling dri unlock\n"); + DRIUnlock(screenInfo.screens[scrnIndex]); + } pI830->LockHeld = 0; } #endif @@ -2502,20 +3333,20 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) int _head; int _tail; - I830Ptr pI830; ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - int ret; + I830Ptr pI830 = I830PTR(pScrn); + int ret = TRUE; - pI830 = I830PTR(pScrn); + DPRINTF(PFX, "I830BIOSSwitchMode: mode == %p\n", mode); - if (!pI830->noAccel && (1 || IS_845G(pI830))) { /*Stops head pointer freezes for 845G */ + /* Stops head pointer freezes for 845G */ + if (!pI830->noAccel && (1 || IS_845G(pI830))) { do { _head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; _tail = INREG(LP_RING + RING_TAIL) & I830_TAIL_MASK; DELAY(1000); } while (_head != _tail); } - DPRINTF(PFX, "mode == %p\n", mode); #if 0 OffsetFrame = !OffsetFrame; @@ -2528,10 +3359,20 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) #if BINDUNBIND I830UnbindGARTMemory(pScrn); #endif - ret = I830VESASetMode(xf86Screens[scrnIndex], mode); +#ifdef I830_XV + /* Give the video overlay code a chance to see the new mode. */ + I830VideoSwitchModeBefore(pScrn, mode); +#endif + if (!I830VESASetMode(pScrn, mode)) + ret = FALSE; +#ifdef I830_XV + /* Give the video overlay code a chance to see the new mode. */ + I830VideoSwitchModeAfter(pScrn, mode); +#endif #if BINDUNBIND I830BindGARTMemory(pScrn); #endif + return ret; } @@ -2545,7 +3386,7 @@ I830BIOSSaveScreen(ScreenPtr pScreen, int mode) DPRINTF(PFX, "I830BIOSSaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on)); - for (i = 0; i < 2; i++) { + for (i = 0; i < MAX_DISPLAY_PIPES; i++) { if (i == 0) { ctrl = DSPACNTR; base = DSPABASE; @@ -2566,11 +3407,12 @@ I830BIOSSaveScreen(ScreenPtr pScreen, int mode) } } - if (pI830->CursorInfoRec) { + if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) { if (on) pI830->CursorInfoRec->ShowCursor(pScrn); else pI830->CursorInfoRec->HideCursor(pScrn); + pI830->cursorOn = TRUE; } return TRUE; @@ -2582,7 +3424,7 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) { I830Ptr pI830 = I830PTR(pScrn); - vbeInfoPtr pVbe = pI830->vesa->pVbe; + vbeInfoPtr pVbe = pI830->pVbe; if (xf86LoaderCheckSymbol("VBEDPMSSet")) { VBEDPMSSet(pVbe, PowerManagementMode); @@ -2615,6 +3457,7 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen) I830Ptr pI830 = I830PTR(pScrn); XAAInfoRecPtr infoPtr = pI830->AccelInfoRec; + pI830->closing = TRUE; #ifdef XF86DRI if (pI830->directRenderingOpen) { pI830->directRenderingOpen = FALSE; @@ -2650,6 +3493,7 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen) xf86GARTCloseScreen(scrnIndex); pScrn->vtSema = FALSE; + pI830->closing = FALSE; pScreen->CloseScreen = pI830->CloseScreen; return (*pScreen->CloseScreen) (scrnIndex, pScreen); } @@ -2667,6 +3511,66 @@ I830ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) return MODE_OK; } +#ifndef SUSPEND_SLEEP +#define SUSPEND_SLEEP 0 +#endif +#ifndef RESUME_SLEEP +#define RESUME_SLEEP 0 +#endif + +/* + * This function is only required if we need to do anything differently from + * DoApmEvent() in common/xf86PM.c, including if we want to see events other + * than suspend/resume. + */ +static Bool +I830PMEvent(int scrnIndex, pmEvent event, Bool undo) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + I830Ptr pI830 = I830PTR(pScrn); + + DPRINTF(PFX, "Enter VT, event %d, undo: %s\n", event, BOOLTOSTRING(undo)); + + switch(event) { + case XF86_APM_SYS_SUSPEND: + case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend?*/ + case XF86_APM_USER_SUSPEND: + case XF86_APM_SYS_STANDBY: + case XF86_APM_USER_STANDBY: + if (!undo && !pI830->suspended) { + pScrn->LeaveVT(scrnIndex, 0); + pI830->suspended = TRUE; + sleep(SUSPEND_SLEEP); + } else if (undo && pI830->suspended) { + sleep(RESUME_SLEEP); + pScrn->EnterVT(scrnIndex, 0); + pI830->suspended = FALSE; + } + break; + case XF86_APM_STANDBY_RESUME: + case XF86_APM_NORMAL_RESUME: + case XF86_APM_CRITICAL_RESUME: + if (pI830->suspended) { + sleep(RESUME_SLEEP); + pScrn->EnterVT(scrnIndex, 0); + pI830->suspended = FALSE; + /* + * Turn the screen saver off when resuming. This seems to be + * needed to stop xscreensaver kicking in (when used). + * + * XXX DoApmEvent() should probably call this just like + * xf86VTSwitch() does. Maybe do it here only in 4.2 + * compatibility mode. + */ + SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); + } + break; + default: + ErrorF("I830PMEvent: received APM event %d\n", event); + } + return TRUE; +} + void I830InitpScrn(ScrnInfoPtr pScrn) { @@ -2678,4 +3582,5 @@ I830InitpScrn(ScrnInfoPtr pScrn) pScrn->LeaveVT = I830BIOSLeaveVT; pScrn->FreeScreen = I830BIOSFreeScreen; pScrn->ValidMode = I830ValidMode; + pScrn->PMEvent = I830PMEvent; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c index 3a2a61816..16693d4aa 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c,v 1.3 2002/10/16 21:13:47 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c,v 1.6 2003/02/08 02:26:56 dawes Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -65,6 +65,7 @@ AllocFromPool(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, { I830Ptr pI830 = I830PTR(pScrn); unsigned long needed, start, end; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); if (!result || !pool || !size) return 0; @@ -85,7 +86,7 @@ AllocFromPool(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, end = ROUND_DOWN_TO(pool->Free.End, alignment); else end = pool->Free.End; - + start = ROUND_DOWN_TO(end - size, alignment); needed = pool->Free.End - start; } @@ -93,12 +94,20 @@ AllocFromPool(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, if (needed > pool->Free.Size) { unsigned long extra; /* See if the pool can be grown. */ - if (pI830->StolenOnly) + if (pI830->StolenOnly && !dryrun) return 0; extra = needed - pool->Free.Size; extra = ROUND_TO_PAGE(extra); - if (extra > pI830->FreeMemory) + if (extra > pI830->FreeMemory) { + if (dryrun) + pI830->FreeMemory = extra; + else + return 0; + } + + if (!dryrun && (extra > pI830->MemoryAperture.Size)) return 0; + pool->Free.Size += extra; pool->Free.End += extra; pool->Total.Size += extra; @@ -131,6 +140,7 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, unsigned long size, I830Ptr pI830 = I830PTR(pScrn); unsigned long start, end; unsigned long newApStart, newApEnd; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); if (!result || !size) return 0; @@ -142,8 +152,12 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, unsigned long size, return 0; } - if (size > pI830->FreeMemory) - return 0; + if (size > pI830->FreeMemory) { + if (dryrun) + pI830->FreeMemory = size; + else + return 0; + } /* Calculate offset */ if (flags & ALLOCATE_AT_BOTTOM) { @@ -163,19 +177,22 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, unsigned long size, newApStart = pI830->MemoryAperture.Start; newApEnd = start; } - if (newApStart > newApEnd) - return 0; - if (flags & NEED_PHYSICAL_ADDR) { - result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, - &(result->Physical)); - } else { - result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); - } + if (!dryrun) { + if (newApStart > newApEnd) + return 0; - if (result->Key == -1) - return 0; + if (flags & NEED_PHYSICAL_ADDR) { + result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, + &(result->Physical)); + } else { + result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); + } + if (result->Key == -1) + return 0; + } + pI830->allocatedMemory += size; pI830->MemoryAperture.Start = newApStart; pI830->MemoryAperture.End = newApEnd; pI830->MemoryAperture.Size = newApEnd - newApStart; @@ -196,6 +213,7 @@ I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, unsigned long size, unsigned long alignment, int flags) { I830Ptr pI830 = I830PTR(pScrn); + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); if (!result) return 0; @@ -212,11 +230,12 @@ I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, case FROM_POOL_ONLY: return AllocFromPool(pScrn, result, pool, size, alignment, flags); case FROM_NEW_ONLY: - if (pI830->StolenOnly || (pI830->FreeMemory <= 0)) + if (!dryrun && (pI830->StolenOnly || (pI830->FreeMemory <= 0))) return 0; return AllocFromAGP(pScrn, result, size, alignment, flags); case FROM_ANYWHERE: - if (!(flags & ALLOCATE_AT_BOTTOM) && (pI830->FreeMemory >= size)) + if ((!(flags & ALLOCATE_AT_BOTTOM) && (pI830->FreeMemory >= size)) || + (flags & NEED_PHYSICAL_ADDR)) return AllocFromAGP(pScrn, result, size, alignment, flags); else return AllocFromPool(pScrn, result, pool, size, alignment, flags); @@ -227,11 +246,13 @@ I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, } static Bool -AllocateRingBuffer(ScrnInfoPtr pScrn, Bool forceLow) +AllocateRingBuffer(ScrnInfoPtr pScrn, int flags) { I830Ptr pI830 = I830PTR(pScrn); unsigned long size, alloced; - int flags; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; /* Clear ring buffer info */ memset(&(pI830->LpRing), 0, sizeof(pI830->LpRing)); @@ -242,36 +263,40 @@ AllocateRingBuffer(ScrnInfoPtr pScrn, Bool forceLow) /* Ring buffer */ size = PRIMARY_RINGBUFFER_SIZE; - if (forceLow) - flags = FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM; + if (flags & FORCE_LOW) + flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM; else - flags = FROM_ANYWHERE | ALLOCATE_AT_TOP; + flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP; alloced = I830AllocVidMem(pScrn, &(pI830->LpRing.mem), &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags); if (alloced < size) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Ring Buffer space\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate Ring Buffer space\n"); + } return FALSE; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for the ring buffer at 0x%x\n", - alloced / 1024, pI830->LpRing.mem.Start); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for the ring buffer at 0x%x\n", s, + alloced / 1024, pI830->LpRing.mem.Start); pI830->LpRing.tail_mask = pI830->LpRing.mem.Size - 1; return TRUE; } #ifdef I830_XV /* - * Note, the forceLow argument is currently not used or supported. + * Note, the FORCE_LOW flag is currently not used or supported. */ static Bool -AllocateOverlay(ScrnInfoPtr pScrn, Bool forceLow) +AllocateOverlay(ScrnInfoPtr pScrn, int flags) { I830Ptr pI830 = I830PTR(pScrn); unsigned long size, alloced; - int flags; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; /* Clear overlay info */ memset(&(pI830->OverlayMem), 0, sizeof(pI830->OverlayMem)); @@ -287,10 +312,10 @@ AllocateOverlay(ScrnInfoPtr pScrn, Bool forceLow) */ size = OVERLAY_SIZE; - if (forceLow) - flags = FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM | NEED_PHYSICAL_ADDR; + if (flags & FORCE_LOW) + flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM | NEED_PHYSICAL_ADDR; else - flags = FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR; + flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR; alloced = I830AllocVidMem(pScrn, &(pI830->OverlayMem), &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags); @@ -299,20 +324,21 @@ AllocateOverlay(ScrnInfoPtr pScrn, Bool forceLow) * XXX For testing only. Don't enable this unless you know how to set * physBase. */ - if (forceLow) { - ErrorF("AllocateOverlay() doesn't support setting forceLow\n"); + if (flags & FORCE_LOW) { + ErrorF("AllocateOverlay() doesn't support setting FORCE_LOW\n"); return FALSE; } - if (alloced < size) { + if (!dryrun && (alloced < size)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate Overlay register space.\n"); /* This failure isn't fatal. */ } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for Overlay registers at 0x%x (0x%08x).\n", - alloced / 1024, pI830->OverlayMem.Start, - pI830->OverlayMem.Physical); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for Overlay registers at 0x%x " + "(0x%08x).\n", s, + alloced / 1024, pI830->OverlayMem.Start, + pI830->OverlayMem.Physical); } return TRUE; } @@ -334,186 +360,240 @@ GetFreeSpace(ScrnInfoPtr pScrn) return extra; } +static Bool +IsTileable(int pitch) +{ + /* + * Allow tiling for pitches that are a power of 2 multiple of 128 bytes, + * up to 64 * 128 (= 8192) bytes. + */ + switch (pitch) { + case 128 * 1: + case 128 * 2: + case 128 * 4: + case 128 * 8: + case 128 * 16: + case 128 * 32: + case 128 * 64: + return TRUE; + default: + return FALSE; + } +} + /* * Allocate memory for 2D operation. This includes the (front) framebuffer, * ring buffer, scratch memory, HW cursor. */ Bool -I830Allocate2DMemory(ScrnInfoPtr pScrn, Bool initial) +I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); unsigned long size, alloced; - int flags; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + Bool tileable; + int align, alignflags; - DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n", BOOLTOSTRING(initial)); + DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n", + BOOLTOSTRING(flags & ALLOC_INITIAL)); if (!pI830->StolenOnly && (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AGP GART support is either not available or cannot be used.\n" - "\tMake sure your kernel has agpgart support or has the\n" - "\tagpgart module loaded.\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "AGP GART support is either not available or cannot " + "be used.\n" + "\tMake sure your kernel has agpgart support or has the\n" + "\tagpgart module loaded.\n"); + } return FALSE; } - { - /* - * The I830 is slightly different from the I830/I815, it has no - * dcache and it has stolen memory by default in its gtt. All - * additional memory must go after it. - */ - DPRINTF(PFX, - "size == %luk (%lu bytes == pScrn->videoRam)\n" - "pI830->StolenSize == %luk (%lu bytes)\n", - pScrn->videoRam, pScrn->videoRam * 1024, - pI830->StolenPool.Free.Size / 1024, - pI830->StolenPool.Free.Size); + /* + * The I830 is slightly different from the I830/I815, it has no + * dcache and it has stolen memory by default in its gtt. All + * additional memory must go after it. + */ - if (initial) { - unsigned long minspace, avail, lineSize; - int cacheLines, maxCacheLines; + DPRINTF(PFX, + "size == %luk (%lu bytes == pScrn->videoRam)\n" + "pI830->StolenSize == %luk (%lu bytes)\n", + pScrn->videoRam, pScrn->videoRam * 1024, + pI830->StolenPool.Free.Size / 1024, + pI830->StolenPool.Free.Size); - if (pI830->NeedRingBufferLow) - AllocateRingBuffer(pScrn, TRUE); + if (flags & ALLOC_INITIAL) { + unsigned long minspace, avail, lineSize; + int cacheLines, maxCacheLines; - /* Clear everything first. */ - memset(&(pI830->FbMemBox), 0, sizeof(pI830->FbMemBox)); - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; + if (pI830->NeedRingBufferLow) + AllocateRingBuffer(pScrn, flags | FORCE_LOW); - pI830->FbMemBox.x1 = 0; - pI830->FbMemBox.x2 = pScrn->displayWidth; - pI830->FbMemBox.y1 = 0; - pI830->FbMemBox.y2 = pScrn->virtualY; + /* Clear everything first. */ + memset(&(pI830->FbMemBox), 0, sizeof(pI830->FbMemBox)); + memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); + pI830->FrontBuffer.Key = -1; - /* - * Calculate how much framebuffer memory to allocate. For the - * initial allocation, calculate a reasonable minimum. This is - * enough for the virtual screen size, plus some pixmap cache - * space. - */ + pI830->FbMemBox.x1 = 0; + pI830->FbMemBox.x2 = pScrn->displayWidth; + pI830->FbMemBox.y1 = 0; + pI830->FbMemBox.y2 = pScrn->virtualY; - lineSize = pScrn->displayWidth * pI830->cpp; - minspace = lineSize * pScrn->virtualY; - avail = pScrn->videoRam * 1024; - maxCacheLines = (avail - minspace) / lineSize; - /* This shouldn't happen. */ - if (maxCacheLines < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal Error: " - "maxCacheLines < 0 in I830Allocate2DMemory()\n"); - maxCacheLines = 0; - } - if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY)) - maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY; + /* + * Calculate how much framebuffer memory to allocate. For the + * initial allocation, calculate a reasonable minimum. This is + * enough for the virtual screen size, plus some pixmap cache + * space. + */ - if (pI830->CacheLines >= 0) { - cacheLines = pI830->CacheLines; - } else { + lineSize = pScrn->displayWidth * pI830->cpp; + minspace = lineSize * pScrn->virtualY; + avail = pScrn->videoRam * 1024; + maxCacheLines = (avail - minspace) / lineSize; + /* This shouldn't happen. */ + if (maxCacheLines < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal Error: " + "maxCacheLines < 0 in I830Allocate2DMemory()\n"); + maxCacheLines = 0; + } + if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY)) + maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY; + + if (pI830->CacheLines >= 0) { + cacheLines = pI830->CacheLines; + } else { #if 1 - /* Make sure there is enough for two DVD sized YUV buffers */ - cacheLines = (pScrn->depth == 24) ? 256 : 384; - if (pScrn->displayWidth <= 1024) - cacheLines *= 2; + /* Make sure there is enough for two DVD sized YUV buffers */ + cacheLines = (pScrn->depth == 24) ? 256 : 384; + if (pScrn->displayWidth <= 1024) + cacheLines *= 2; #else - /* - * Make sure there is enough for two DVD sized YUV buffers. - * Make that 1.5MB, which is around what was allocated with - * the old algorithm - */ - cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth; + /* + * Make sure there is enough for two DVD sized YUV buffers. + * Make that 1.5MB, which is around what was allocated with + * the old algorithm + */ + cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth; #endif + } + if (cacheLines > maxCacheLines) + cacheLines = maxCacheLines; + + pI830->FbMemBox.y2 += cacheLines; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocating at least %d scanlines for pixmap cache\n", + s, cacheLines); + + tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && + IsTileable(pScrn->displayWidth * pI830->cpp); + if (tileable) { + align = KB(512); + alignflags = ALIGN_BOTH_ENDS; + } else { + align = KB(64); + alignflags = 0; + } + + size = lineSize * (pScrn->virtualY + cacheLines); + size = ROUND_TO_PAGE(size); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sInitial framebuffer allocation size: %d kByte\n", s, + size / 1024); + alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), + &(pI830->StolenPool), size, align, + flags | alignflags | + FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate framebuffer.\n"); } - if (cacheLines > maxCacheLines) - cacheLines = maxCacheLines; + return FALSE; + } + } else { + unsigned long lineSize; + unsigned long extra = 0; + unsigned long maxFb = 0; - pI830->FbMemBox.y2 += cacheLines; + /* + * XXX Need to "free" up any 3D allocations if the DRI ended up + * and make them available for 2D. The best way to do this would + * be position all of those regions contiguously at the end of the + * StolenPool. + */ + extra = GetFreeSpace(pScrn); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocating at least %d scanlines for pixmap cache\n", - cacheLines); - size = lineSize * (pScrn->virtualY + cacheLines); - size = ROUND_TO_PAGE(size); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Initial framebuffer allocation size: %d kByte\n", - size / 1024); - alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), - &(pI830->StolenPool), size, KB(64), - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { + if (extra == 0) + return TRUE; + + maxFb = pI830->FrontBuffer.Size + extra; + lineSize = pScrn->displayWidth * pI830->cpp; + maxFb = ROUND_DOWN_TO(maxFb, lineSize); + if (maxFb > lineSize * MAX_DISPLAY_HEIGHT) + maxFb = lineSize * MAX_DISPLAY_HEIGHT; + if (maxFb > pI830->FrontBuffer.Size) { + unsigned long oldsize; + /* + * Sanity check -- the fb should be the last thing allocated at + * the bottom of the stolen pool. + */ + if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate framebuffer\n"); + "Internal error in I830Allocate2DMemory():\n\t" + "Framebuffer isn't the last allocation at the bottom" + " of StolenPool\n\t(%x != %x).\n", + pI830->FrontBuffer.End, + pI830->StolenPool.Free.Start); return FALSE; } - } else { - unsigned long lineSize; - unsigned long extra = 0; - unsigned long maxFb = 0; - /* - * XXX Need to "free" up any 3D allocations if the DRI ended up - * and make them available for 2D. The best way to do this would - * be position all of those regions contiguously at the end of the - * StolenPool. + * XXX Maybe should have a "Free" function. This should be + * the only place where a region is resized, and we know that + * the fb is always at the bottom of the aperture/stolen pool, + * and is the only region that is allocated bottom-up. + * Allowing for more general realloction would require a smarter + * allocation system. */ - extra = GetFreeSpace(pScrn); - - if (extra == 0) - return TRUE; - - maxFb = pI830->FrontBuffer.Size + extra; - lineSize = pScrn->displayWidth * pI830->cpp; - maxFb = ROUND_DOWN_TO(maxFb, lineSize); - if (maxFb > lineSize * MAX_DISPLAY_HEIGHT) - maxFb = lineSize * MAX_DISPLAY_HEIGHT; - if (maxFb > pI830->FrontBuffer.Size) { - unsigned long oldsize; - /* - * Sanity check -- the fb should be the last thing allocated at - * the bottom of the stolen pool. - */ - if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal error in I830Allocate2DMemory():\n\t" - "Framebuffer isn't the last allocation at the bottom" - " of StolenPool\n\t(%x != %x).\n", - pI830->FrontBuffer.End, - pI830->StolenPool.Free.Start); - return FALSE; - } - /* - * XXX Maybe should have a "Free" function. This should be - * the only place where a region is resized, and we know that - * the fb is always at the bottom of the aperture/stolen pool, - * and is the only region that is allocated bottom-up. - * Allowing for more general realloction would require a smarter - * allocation system. - */ - oldsize = pI830->FrontBuffer.Size; - pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size; - pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Updated framebuffer allocation size from %d " - "to %d kByte\n", oldsize / 1024, maxFb / 1024); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Updated pixmap cache from %d scanlines to %d " - "scanlines\n", - oldsize / lineSize - pScrn->virtualY, - maxFb / lineSize - pScrn->virtualY); - pI830->FbMemBox.y2 = maxFb / lineSize; - alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), - &(pI830->StolenPool), maxFb, KB(64), - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < maxFb) { + oldsize = pI830->FrontBuffer.Size; + pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size; + pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sUpdated framebuffer allocation size from %d " + "to %d kByte\n", s, oldsize / 1024, maxFb / 1024); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sUpdated pixmap cache from %d scanlines to %d " + "scanlines\n", s, + oldsize / lineSize - pScrn->virtualY, + maxFb / lineSize - pScrn->virtualY); + pI830->FbMemBox.y2 = maxFb / lineSize; + tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && + IsTileable(pScrn->displayWidth * pI830->cpp); + if (tileable) { + align = KB(512); + alignflags = ALIGN_BOTH_ENDS; + } else { + align = KB(64); + alignflags = 0; + } + alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), + &(pI830->StolenPool), maxFb, align, + flags | alignflags | + FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + if (alloced < maxFb) { + if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to re-allocate framebuffer\n"); - return FALSE; } + return FALSE; } - return TRUE; } + return TRUE; } #if REMAP_RESERVED @@ -521,10 +601,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, Bool initial) * Allocate a dummy page to pass when attempting to rebind the * pre-allocated region. */ - memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy)); - pI830->Dummy.Key = - xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); - pI830->Dummy.Offset = 0; + if (!dryrun) { + memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy)); + pI830->Dummy.Key = + xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); + pI830->Dummy.Offset = 0; + } #endif /* Clear cursor info */ @@ -532,97 +614,113 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, Bool initial) pI830->CursorMem.Key = -1; if (!pI830->SWCursor) { - + int cursFlags = 0; /* - * Mouse cursor -- The i810-i830 (crazy) need a physical address in - * system memory from which to upload the cursor. We get this from + * Mouse cursor -- The i810-i830 need a physical address in system + * memory from which to upload the cursor. We get this from * the agpgart module using a special memory type. */ - /* - * 4k for the cursor is excessive, but the minimum allocation is - * one 4k page. - */ - size = HWCURSOR_SIZE; - flags = FROM_ANYWHERE | ALLOCATE_AT_TOP; + cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; if (pI830->CursorNeedsPhysical) - flags |= NEED_PHYSICAL_ADDR; + cursFlags |= NEED_PHYSICAL_ADDR; alloced = I830AllocVidMem(pScrn, &(pI830->CursorMem), &(pI830->StolenPool), size, - GTT_PAGE_SIZE, flags); + GTT_PAGE_SIZE, flags | cursFlags); if (alloced < size) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW cursor space.\n"); - return FALSE; + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW cursor space.\n"); + } + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for HW cursor at 0x%x", s, + alloced / 1024, pI830->CursorMem.Start); + if (pI830->CursorNeedsPhysical) + xf86ErrorFVerb(verbosity, " (0x%08x)", pI830->CursorMem.Physical); + xf86ErrorFVerb(verbosity, "\n"); } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for HW cursor at 0x%x", - alloced / 1024, pI830->CursorMem.Start); - if (pI830->CursorNeedsPhysical) - xf86ErrorF(" (0x%08x)", pI830->CursorMem.Physical); - xf86ErrorF("\n"); - } - - if (!pI830->NeedRingBufferLow) - AllocateRingBuffer(pScrn, FALSE); - #ifdef I830_XV - AllocateOverlay(pScrn, FALSE); + AllocateOverlay(pScrn, flags); #endif + if (!pI830->NeedRingBufferLow) + AllocateRingBuffer(pScrn, flags); + /* Clear scratch info */ memset(&(pI830->Scratch), 0, sizeof(pI830->Scratch)); pI830->Scratch.Key = -1; if (!pI830->noAccel) { size = MAX_SCRATCH_BUFFER_SIZE; - flags = FROM_ANYWHERE | ALLOCATE_AT_TOP; alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), &(pI830->StolenPool), - size, GTT_PAGE_SIZE, flags); + size, GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); if (alloced < size) { size = MIN_SCRATCH_BUFFER_SIZE; alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), &(pI830->StolenPool), size, - GTT_PAGE_SIZE, flags); + GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); } if (alloced < size) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate scratch buffer space\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate scratch buffer space\n"); + } return FALSE; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for the scratch buffer at 0x%x\n", - alloced / 1024, pI830->Scratch.Start); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for the scratch buffer at 0x%x\n", s, + alloced / 1024, pI830->Scratch.Start); } return TRUE; } -#ifdef XF86DRI -static Bool -IsTileable(int pitch) +#ifndef ALLOCATE_ALL_BIOSMEM +#define ALLOCATE_ALL_BIOSMEM 1 +#endif + +void +I830ResetAllocations(ScrnInfoPtr pScrn, const int flags) { - /* - * Allow tiling for pitches that are a power of 2 multiple of 128 bytes, - * up to 64 * 128 (= 8192) bytes. - */ - switch (pitch) { - case 128 * 1: - case 128 * 2: - case 128 * 4: - case 128 * 8: - case 128 * 16: - case 128 * 32: - case 128 * 64: - return TRUE; - default: - return FALSE; + I830Ptr pI830 = I830PTR(pScrn); + + pI830->MemoryAperture.Start = pI830->StolenMemory.End; + pI830->MemoryAperture.End = pI830->FbMapSize; + pI830->MemoryAperture.Size = pI830->FbMapSize - pI830->StolenMemory.Size; + pI830->StolenPool.Fixed = pI830->StolenMemory; + pI830->StolenPool.Total = pI830->StolenMemory; +#if ALLOCATE_ALL_BIOSMEM + if (pI830->overrideBIOSMemSize && + pI830->BIOSMemorySize > pI830->StolenMemory.Size) { + pI830->StolenPool.Total.End = pI830->BIOSMemorySize; + pI830->StolenPool.Total.Size = pI830->BIOSMemorySize; } +#endif + pI830->StolenPool.Free = pI830->StolenPool.Total; + pI830->FreeMemory = pI830->TotalVideoRam - pI830->StolenPool.Total.Size; + pI830->allocatedMemory = 0; } +long +I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long allocated; + + allocated = pI830->StolenPool.Total.Size + pI830->allocatedMemory; + if (allocated > pI830->TotalVideoRam) + return allocated - pI830->TotalVideoRam; + else + return 0; +} + +#ifdef XF86DRI static unsigned long GetBestTileAlignment(unsigned long size) { @@ -650,21 +748,32 @@ myLog2(unsigned int n) } Bool -I830Allocate3DMemory(ScrnInfoPtr pScrn) +I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); unsigned long size, alloced, align = 0; - int flags, i; + int i; Bool tileable; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + int lines; DPRINTF(PFX, "I830Allocate3DMemory\n"); /* Back Buffer */ memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); pI830->BackBuffer.Key = -1; - tileable = IsTileable(pScrn->displayWidth * pI830->cpp); - size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); - flags = FROM_ANYWHERE | ALLOCATE_AT_TOP; + tileable = !(flags & ALLOC_NO_TILING) && + IsTileable(pScrn->displayWidth * pI830->cpp); + if (tileable) { + /* Make the height a multiple of the tile height (16) */ + lines = (pScrn->virtualY + 15) / 16 * 16; + } else { + lines = pScrn->virtualY; + } + + size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); /* * Try to allocate on the best tile-friendly boundaries. */ @@ -674,7 +783,8 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn) for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) { alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), &(pI830->StolenPool), size, align, - flags | ALIGN_BOTH_ENDS); + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | + ALIGN_BOTH_ENDS); if (alloced >= size) break; } @@ -682,18 +792,22 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn) if (alloced < size) { /* Give up on trying to tile */ tileable = FALSE; + size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); align = GTT_PAGE_SIZE; alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), - &(pI830->StolenPool), size, align, flags); + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); } if (alloced < size) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate back buffer space\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate back buffer space.\n"); + } return FALSE; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for the back buffer at 0x%x\n", - alloced / 1024, pI830->BackBuffer.Start); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for the back buffer at 0x%x.\n", s, + alloced / 1024, pI830->BackBuffer.Start); /* Depth Buffer -- same size as the back buffer */ memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); @@ -707,7 +821,8 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn) for (; align >= KB(512); align >>= 1) { alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), &(pI830->StolenPool), size, align, - flags | ALIGN_BOTH_ENDS); + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | + ALIGN_BOTH_ENDS); if (alloced >= size) break; } @@ -715,34 +830,40 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn) if (alloced < size) { /* Give up on trying to tile */ tileable = FALSE; + size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); align = GTT_PAGE_SIZE; alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), - &(pI830->StolenPool), size, align, flags); + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); } if (alloced < size) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate depth buffer space\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate depth buffer space.\n"); + } return FALSE; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for the depth buffer at 0x%x\n", - alloced / 1024, pI830->DepthBuffer.Start); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for the depth buffer at 0x%x.\n", s, + alloced / 1024, pI830->DepthBuffer.Start); /* Space for logical context. 32k is fine for right now. */ memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); pI830->ContextMem.Key = -1; size = KB(32); - flags = FROM_ANYWHERE | ALLOCATE_AT_TOP; alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem), - &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags); + &(pI830->StolenPool), size, GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); if (alloced < size) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate logical context space\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate logical context space.\n"); + } return FALSE; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for the logical context at 0x%x\n", - alloced / 1024, pI830->ContextMem.Start); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for the logical context at 0x%x.\n", s, + alloced / 1024, pI830->ContextMem.Start); /* * Space for DMA buffers, only if there's enough free for at least 1MB @@ -752,22 +873,26 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn) pI830->BufferMem.Key = -1; /* This should already be a page multiple */ size = I830_DMA_BUF_NR * I830_DMA_BUF_SZ; - if (GetFreeSpace(pScrn) >= size + MB(1)) { - flags = FROM_ANYWHERE | ALLOCATE_AT_TOP; + if (dryrun || (GetFreeSpace(pScrn) >= size + MB(1))) { alloced = I830AllocVidMem(pScrn, &(pI830->BufferMem), &(pI830->StolenPool), size, - GTT_PAGE_SIZE, flags); + GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); if (alloced < size) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate DMA buffer space\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate DMA buffer space.\n"); + } return FALSE; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for the DMA buffers at 0x%x\n", - alloced / 1024, pI830->BufferMem.Start); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for the DMA buffers at 0x%x.\n", s, + alloced / 1024, pI830->BufferMem.Start); } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not enough free space for DMA buffers\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Not enough free space for DMA buffers.\n"); + } return FALSE; } @@ -775,6 +900,8 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn) memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); pI830->TexMem.Key = -1; size = GetFreeSpace(pScrn); + if (dryrun && (size < MB(1))) + size = MB(1); i = myLog2(size / I830_NR_TEX_REGIONS); if (i < I830_LOG_MIN_TEX_REGION_SIZE) i = I830_LOG_MIN_TEX_REGION_SIZE; @@ -783,21 +910,25 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn) size >>= i; size <<= i; if (size < KB(512)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Less than %d kBytes for texture space\n", size / 1024); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Less than %d kBytes for texture space.\n", size / 1024); + } return FALSE; } - flags = FROM_ANYWHERE | ALLOCATE_AT_TOP; alloced = I830AllocVidMem(pScrn, &(pI830->TexMem), - &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags); + &(pI830->StolenPool), size, GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); if (alloced < size) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate texture space\n"); + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate texture space.\n"); + } return FALSE; } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Allocated %d kB for textures at 0x%x\n", - alloced / 1024, pI830->TexMem.Start); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %d kB for textures at 0x%x\n", s, + alloced / 1024, pI830->TexMem.Start); return TRUE; } @@ -859,7 +990,7 @@ static unsigned long topOfMem = 0; * following options. * * XXX Write a better description. - * + * */ #define PACK_RANGES 0 #define POOL_RANGES 0 @@ -884,7 +1015,7 @@ FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem) * a contiguous region in the aperture. Normally most AGP-allocated areas * will be at the top of the aperture, making alignment requirements * easier to achieve. This optin is primarily for debugging purposes, - * and using this option can break any special alignment requirements. + * and using this option can break any special alignment requirements. */ if (!mem->Pool && mem->Start != 0 && mem->Key != -1 && mem->Physical == 0 && mem->Offset != 0) { @@ -961,7 +1092,7 @@ I830FixupOffsets(ScrnInfoPtr pScrn) * Need to make it less likely that we miss out on this - probably * need to move the frontbuffer away from the 'guarenteed' alignment * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. + * framebuffer to get more alignment 'sweet spots'. */ static void SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, @@ -1071,15 +1202,19 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, } static Bool -MakeTiles(ScrnInfoPtr pScrn, const I830MemRange *pMem) +MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem) { I830Ptr pI830 = I830PTR(pScrn); int pitch, ntiles, i; static int nextTile = 0; - static unsigned long tileGeneration = 0; + static int tileGeneration = -1; - DPRINTF(PFX, "MakeTiles: start 0x%08x, size %d kByte, align 0x%08x\n", - pMem->Start, pMem->Size, pMem->Alignment); +#if 0 + /* Hack to "improve" the alignment of the front buffer. + */ + while (!(pMem->Start & ~pMem->Alignment) && pMem->Alignment < 0x00400000 ) + pMem->Alignment <<= 1; +#endif if (tileGeneration != serverGeneration) { tileGeneration = serverGeneration; @@ -1092,8 +1227,9 @@ MakeTiles(ScrnInfoPtr pScrn, const I830MemRange *pMem) * equal to the alignment. */ ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) + if (ntiles >= 4) { return FALSE; + } for (i = 0; i < ntiles; i++, nextTile++) { SetFence(pScrn, nextTile, pMem->Start + i * pMem->Alignment, @@ -1111,8 +1247,30 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) if (!pI830->directRenderingEnabled) return; - if (!IsTileable(pScrn->displayWidth * pI830->cpp)) + if (!IsTileable(pScrn->displayWidth * pI830->cpp)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "I830SetupMemoryTiling: Not tileable 0x%x\n", + pScrn->displayWidth * pI830->cpp); + pI830->allowPageFlip = FALSE; return; + } + + if (pI830->allowPageFlip) { + if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->FrontBuffer))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Activating tiled memory for the FRONT buffer\n"); + } else { + pI830->allowPageFlip = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the FRONT buffer\n"); + } + } else { + pI830->allowPageFlip = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Alignment bad for the FRONT buffer\n"); + } + } /* * We tried to get the best alignment during the allocation. Check @@ -1120,15 +1278,27 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) * successful, the address range reserved is a multiple of the align * value. */ - if (pI830->BackBuffer.Alignment >= KB(512)) - if (MakeTiles(pScrn, &(pI830->BackBuffer))) + if (pI830->BackBuffer.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->BackBuffer))) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Activating tiled memory for the back buffer.\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the back buffer.\n"); + pI830->allowPageFlip = FALSE; + } + } - if (pI830->DepthBuffer.Alignment >= KB(512)) - if (MakeTiles(pScrn, &(pI830->DepthBuffer))) + if (pI830->DepthBuffer.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->DepthBuffer))) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Activating tiled memory for the depth buffer.\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the back buffer.\n"); + } + } + } #endif /* XF86DRI */ @@ -1164,7 +1334,7 @@ I830BindGARTMemory(ScrnInfoPtr pScrn) /* Rebind the pre-allocated region. */ BindMemRange(pScrn, &(pI830->Dummy)); #endif - + if (!BindMemRange(pScrn, &(pI830->StolenPool.Allocated))) return FALSE; if (!BindMemRange(pScrn, &(pI830->FrontBuffer))) @@ -1230,7 +1400,7 @@ I830UnbindGARTMemory(ScrnInfoPtr pScrn) /* "unbind" the pre-allocated region. */ UnbindMemRange(pScrn, &(pI830->Dummy)); #endif - + if (!UnbindMemRange(pScrn, &(pI830->StolenPool.Allocated))) return FALSE; if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer))) @@ -1259,13 +1429,16 @@ I830UnbindGARTMemory(ScrnInfoPtr pScrn) return FALSE; } #endif + if (!xf86ReleaseGART(pScrn->scrnIndex)) + return FALSE; + pI830->GttBound = 0; } return TRUE; } -int +long I830CheckAvailableMemory(ScrnInfoPtr pScrn) { AgpInfoPtr agpinf; @@ -1278,7 +1451,7 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn) return -1; maxPages = agpinf->totalPages - agpinf->usedPages; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %dk available\n", + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n", "I830CheckAvailableMemory", maxPages * 4); return maxPages * 4; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c index 150ed6302..25f9716b5 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c @@ -24,7 +24,7 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c,v 1.1 2002/09/12 04:08:25 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c,v 1.6 2003/02/06 04:18:05 dawes Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: @@ -78,6 +78,10 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dixstruct.h" #include "fourcc.h" +#ifndef USE_USLEEP_FOR_VIDEO +#define USE_USLEEP_FOR_VIDEO 0 +#endif + #define OFF_DELAY 250 /* milliseconds */ #define FREE_DELAY 15000 @@ -205,6 +209,9 @@ Edummy(const char *dummy, ...) /* OCONFIG register */ #define CC_OUT_8BIT (0x1<<3) +#define OVERLAY_PIPE_MASK (0x1<<18) +#define OVERLAY_PIPE_A (0x0<<18) +#define OVERLAY_PIPE_B (0x1<<18) /* DCLRKM register */ #define DEST_KEY_ENABLE (0x1<<31) @@ -347,6 +354,9 @@ typedef struct { FBLinearPtr linear; I830OverlayStateRec hwstate; + + Bool refreshOK; + int maxRate; } I830PortPrivRec, *I830PortPrivPtr; #define GET_PORT_PRIVATE(pScrn) \ @@ -484,6 +494,15 @@ I830ResetVideo(ScrnInfoPtr pScrn) overlay->SCLRKEN = 0; /* source color key disable */ overlay->OCONFIG = CC_OUT_8BIT; + /* + * Select which pipe the overlay is enabled on. Give preference to + * pipe A. + */ + if (pI830->pipeEnabled[0]) + overlay->OCONFIG |= OVERLAY_PIPE_A; + else if (pI830->pipeEnabled[1]) + overlay->OCONFIG |= OVERLAY_PIPE_B; + overlay->OCMD = YUV_420; /* setup hwstate */ @@ -517,6 +536,25 @@ I830ResetVideo(ScrnInfoPtr pScrn) } +/* + * Each chipset has a limit on the pixel rate that the video overlay can + * be used for. Enabling the overlay above that limit can result in a + * lockup. These two functions check the pixel rate for the new mode + * and turn the overlay off before switching to the new mode if it exceeds + * the limit, or turn it back on if the new mode is below the limit. + */ + +/* + * Approximate pixel rate limits for the video overlay. + * The rate is calculated based on the mode resolution and refresh rate. + */ +#define I830_OVERLAY_RATE 79 /* 1024x768@85, 1280x1024@60 */ +#define I845_OVERLAY_RATE 120 /* 1280x1024@85, 1600x1200@60 */ +#define I852_OVERLAY_RATE 79 /* 1024x768@85, 1280x1024@60 */ +#define I855_OVERLAY_RATE 120 /* 1280x1024@85, 1600x1200@60 */ +#define I865_OVERLAY_RATE 170 /* 1600x1200@85, 1920x1440@60 */ +#define DEFAULT_OVERLAY_RATE 120 + static XF86VideoAdaptorPtr I830SetupImageVideo(ScreenPtr pScreen) { @@ -533,7 +571,7 @@ I830SetupImageVideo(ScreenPtr pScreen) adapt->type = XvWindowMask | XvInputMask | XvImageMask; adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - adapt->name = "I830/I845G Video Overlay"; + adapt->name = "Intel(R) 830M/845G/852GM/855GM/865G Video Overlay"; adapt->nEncodings = 1; adapt->pEncodings = DummyEncoding; adapt->nFormats = NUM_FORMATS; @@ -566,11 +604,40 @@ I830SetupImageVideo(ScreenPtr pScreen) pPriv->linear = NULL; pPriv->currentBuf = 0; + switch (pI830->PciInfo->chipType) { + case PCI_CHIP_I830_M: + pPriv->maxRate = I830_OVERLAY_RATE; + break; + case PCI_CHIP_845_G: + pPriv->maxRate = I845_OVERLAY_RATE; + break; + case PCI_CHIP_I855_GM: + switch (pI830->variant) { + case I852_GM: + case I852_GME: + pPriv->maxRate = I852_OVERLAY_RATE; + break; + default: + pPriv->maxRate = I855_OVERLAY_RATE; + break; + } + break; + case PCI_CHIP_I865_G: + pPriv->maxRate = I865_OVERLAY_RATE; + break; + default: + pPriv->maxRate = DEFAULT_OVERLAY_RATE; + break; + } + /* gotta uninit this someplace */ REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); pI830->adaptor = adapt; + /* Initialise pPriv->refreshOK */ + I830VideoSwitchModeAfter(pScrn, pScrn->currentMode); + pI830->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = I830BlockHandler; @@ -659,13 +726,15 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, return BadValue; pPriv->brightness = value; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); - OVERLAY_UPDATE; + if (pPriv->refreshOK) + OVERLAY_UPDATE; } else if (attribute == xvContrast) { if ((value < 0) || (value > 255)) return BadValue; pPriv->contrast = value; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); - OVERLAY_UPDATE; + if (pPriv->refreshOK) + OVERLAY_UPDATE; } else if (attribute == xvColorKey) { pPriv->colorKey = value; switch (pScrn->depth) { @@ -679,7 +748,8 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, overlay->DCLRKV = pPriv->colorKey; break; } - OVERLAY_UPDATE; + if (pPriv->refreshOK) + OVERLAY_UPDATE; REGION_EMPTY(pScrn->pScreen, &pPriv->clip); } else return BadMatch; @@ -968,6 +1038,9 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, DPRINTF(PFX, "I830DisplayVideo: %dx%d (pitch %d)\n", width, height, dstPitch); + if (!pPriv->refreshOK) + return; + CompareOverlay(pI830, (CARD32 *) overlay, 0x100); switch (id) { @@ -1117,6 +1190,10 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, } /* Recalculate coefficients if the scaling changed. */ + + /* + * Only Horizontal coefficients so far. + */ if (scaleChanged) { double fCutoffY; double fCutoffUV; @@ -1311,6 +1388,9 @@ I830PutImage(ScrnInfoPtr pScrn, /* Make sure this buffer isn't in use */ loops = 0; while (loops < 1000000) { +#if USE_USLEEP_FOR_VIDEO + usleep(10); +#endif if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) { break; } @@ -1650,6 +1730,9 @@ I830DisplaySurface(XF86SurfacePtr surface, /* wait for the last rendered buffer to be flipped in */ while (((INREG(DOVSTA) & OC_BUF) >> 20) != pI830Priv->currentBuf) { +#if USE_USLEEP_FOR_VIDEO + usleep(10); +#endif if (loops == 200000) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Overlay Lockup\n"); break; @@ -1709,3 +1792,49 @@ I830InitOffscreenImages(ScreenPtr pScreen) xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); } + +void +I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + I830PortPrivPtr pPriv; + int pixrate; + + if (!I830PTR(pScrn)->adaptor) { + return; + } + + pPriv = GET_PORT_PRIVATE(pScrn); + + if (!pPriv) { + xf86ErrorF("pPriv isn't set\n"); + return; + } + + pixrate = mode->HDisplay * mode->VDisplay * mode->VRefresh; + if (pixrate > pPriv->maxRate && pPriv->refreshOK) { + I830StopVideo(pScrn, pPriv, TRUE); + pPriv->refreshOK = FALSE; + } +} + +void +I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + I830PortPrivPtr pPriv; + int pixrate; + + if (!I830PTR(pScrn)->adaptor) { + return; + } + pPriv = GET_PORT_PRIVATE(pScrn); + if (!pPriv) + return; + + /* If this isn't initialised, assume 60Hz. */ + if (mode->VRefresh == 0) + mode->VRefresh = 60; + + pixrate = (mode->HDisplay * mode->VDisplay * mode->VRefresh) / 1000000; + pPriv->refreshOK = (pixrate <= pPriv->maxRate); +} + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile index 27ee448c0..cb06de249 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.44 2002/09/16 18:05:55 eich Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.46 2003/02/17 17:06:42 dawes Exp $ XCOMM XCOMM This is an Imakefile for the MGA driver. XCOMM @@ -80,7 +80,7 @@ INCLUDES = -I. $(MGAHALINCLUDES) -I$(XF86COMSRC) -I$(XF86OSSRC) \ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC) \ -I$(SERVERSRC)/render \ - -I$(XF86OSSRC)/vbe $(DRIINCLUDES) + -I$(XF86SRC)/vbe $(DRIINCLUDES) #endif DEFINES = $(MGAHALDEFINES) $(DRIDEFINES) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h index 3e296a154..5cb9750a7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.83 2002/09/16 18:05:55 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.85 2002/12/16 16:19:17 dawes Exp $ */ /* * MGA Millennium (MGA2064W) functions * diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c index 0bf4eba5d..37d3a9a6f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.24 2002/10/08 22:14:08 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.28 2003/02/08 21:26:58 dawes Exp $ */ /* * Copyright 2000 VA Linux Systems Inc., Fremont, California. @@ -891,7 +891,7 @@ static Bool MGADRIKernelInit( ScreenPtr pScreen ) init.texture_offset[0] = pMGADRIServer->textureOffset; init.texture_size[0] = pMGADRIServer->textureSize; - init.fb_offset = pMga->FbAddress; + init.fb_offset = pMGADRIServer->fb.handle; init.mmio_offset = pMGADRIServer->registers.handle; init.status_offset = pMGADRIServer->status.handle; @@ -1233,6 +1233,15 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) DRICloseScreen( pScreen ); return FALSE; } + { + void *scratch_ptr; + int scratch_int; + + DRIGetDeviceInfo(pScreen, &pMGADRIServer->fb.handle, + &scratch_int, &scratch_int, + &scratch_int, &scratch_int, + &scratch_ptr); + } if ( !MGAInitVisualConfigs( pScreen ) ) { DRICloseScreen( pScreen ); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h index bab60b0b9..b9ed1c215 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h,v 1.6 2001/04/10 16:08:01 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h,v 1.8 2002/11/29 11:06:42 eich Exp $ */ /* * Copyright 2000 VA Linux Systems Inc., Fremont, California. @@ -66,6 +66,7 @@ typedef struct { drmRegion agp; /* PCI mappings */ + drmRegion fb; drmRegion registers; drmRegion status; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c index 4e754d1a7..1948b5dd4 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c @@ -45,7 +45,7 @@ * Added digital screen option for first head */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.222 2002/10/08 22:14:09 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.231 2003/01/29 19:29:49 eich Exp $ */ /* * This is a first cut at a non-accelerated version to work with the @@ -287,6 +287,7 @@ static const char *ramdacSymbols[] = { NULL }; +#ifdef XFree86LOADER #ifdef XF86DRI static const char *drmSymbols[] = { "drmAddBufs", @@ -311,8 +312,8 @@ static const char *drmSymbols[] = { "drmGetInterruptFromBusID", "drmGetLibVersion", "drmGetVersion", - "drmMapBufs", "drmMap", + "drmMapBufs", "drmUnmap", "drmUnmapBufs", NULL @@ -323,6 +324,7 @@ static const char *driSymbols[] = { "DRICreateInfoRec", "DRIDestroyInfoRec", "DRIFinishScreenInit", + "DRIGetDeviceInfo", "DRILock", "DRIQueryVersion", "DRIScreenInit", @@ -331,6 +333,7 @@ static const char *driSymbols[] = { NULL }; #endif +#endif #define MGAuseI2C 1 @@ -355,12 +358,14 @@ static const char *shadowSymbols[] = { NULL }; +#ifdef XFree86LOADER static const char *vbeSymbols[] = { "VBEInit", "vbeDoEDID", "vbeFree", NULL }; +#endif static const char *int10Symbols[] = { "xf86FreeInt10", @@ -369,30 +374,23 @@ static const char *int10Symbols[] = { }; static const char *fbdevHWSymbols[] = { - "fbdevHWInit", - "fbdevHWUseBuildinMode", - - "fbdevHWGetVidmem", - - /* colormap */ - "fbdevHWLoadPalette", - - /* ScrnInfo hooks */ - "fbdevHWAdjustFrame", - "fbdevHWEnterVT", - "fbdevHWLeaveVT", - "fbdevHWModeInit", - "fbdevHWRestore", - "fbdevHWSave", - "fbdevHWSwitchMode", - "fbdevHWValidMode", - - "fbdevHWMapMMIO", - "fbdevHWMapVidmem", - "fbdevHWUnmapMMIO", - "fbdevHWUnmapVidmem", - - NULL + "fbdevHWAdjustFrame", + "fbdevHWEnterVT", + "fbdevHWGetVidmem", + "fbdevHWInit", + "fbdevHWLeaveVT", + "fbdevHWLoadPalette", + "fbdevHWMapMMIO", + "fbdevHWMapVidmem", + "fbdevHWModeInit", + "fbdevHWRestore", + "fbdevHWSave", + "fbdevHWSwitchMode", + "fbdevHWUnmapMMIO", + "fbdevHWUnmapVidmem", + "fbdevHWUseBuildinMode", + "fbdevHWValidMode", + NULL }; #ifdef USEMGAHAL @@ -1061,7 +1059,7 @@ MGAdoDDC(ScrnInfoPtr pScrn) MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex,pMga->I2C); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n", MonInfo); xf86PrintEDID(MonInfo); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n"); } if (!MonInfo) #endif /* MGAuseI2C */ @@ -1072,7 +1070,21 @@ MGAdoDDC(ScrnInfoPtr pScrn) pMga->ddc1Read ) ; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n", MonInfo); xf86PrintEDID( MonInfo ); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n"); + } + if (!MonInfo){ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,pMga->pEnt->index); + MonInfo = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + + if (MonInfo){ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBE DDC Monitor info: %p\n", MonInfo); + xf86PrintEDID( MonInfo ); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of VBE DDC Monitor info\n\n"); + } + } } @@ -1309,12 +1321,14 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) } xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"", pScrn->chipset); - if ((pMga->Chipset == PCI_CHIP_MGAG400) && - (pMga->ChipRev >= 0x80)) - xf86ErrorF(" (G450)\n"); - else - xf86ErrorF(" (G400)\n"); - + if (pMga->Chipset == PCI_CHIP_MGAG400) { + if (pMga->ChipRev >= 0x80) + xf86ErrorF(" (G450)\n"); + else + xf86ErrorF(" (G400)\n"); + } else { + xf86ErrorF("\n"); + } #ifdef USEMGAHAL if (HAL_CHIPSETS) { Bool loadHal = TRUE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c index 14c8873eb..ff083ac37 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.97 2002/10/21 13:33:01 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.98 2003/01/16 16:09:10 eich Exp $ */ /* All drivers should typically include these */ @@ -609,8 +609,7 @@ MGANAME(AccelInit)(ScreenPtr pScreen) /* fallthrough */ case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: - if (pMga->SecondCrtc == FALSE) - doRender = TRUE; + doRender = FALSE; pMga->AccelFlags = TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mgareg_flags.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mgareg_flags.h index 901f18310..69050fc10 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mgareg_flags.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mgareg_flags.h @@ -19,6 +19,7 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mgareg_flags.h,v 1.2 2003/01/12 03:55:47 tsi Exp $ */ #ifndef _MGAREGS_H_ #define _MGAREGS_H_ @@ -34,892 +35,892 @@ * Power Graphic Mode Memory Space Registers */ - #define AGP_PLL_agp2xpllen_MASK 0xfffffffe /* bit 0 */ - #define AGP_PLL_agp2xpllen_disable 0x0 - #define AGP_PLL_agp2xpllen_enable 0x1 - - #define AC_src_MASK 0xfffffff0 /* bits 0-3 */ - #define AC_src_zero 0x0 /* val 0, shift 0 */ - #define AC_src_one 0x1 /* val 1, shift 0 */ - #define AC_src_dst_color 0x2 /* val 2, shift 0 */ - #define AC_src_om_dst_color 0x3 /* val 3, shift 0 */ - #define AC_src_src_alpha 0x4 /* val 4, shift 0 */ - #define AC_src_om_src_alpha 0x5 /* val 5, shift 0 */ - #define AC_src_dst_alpha 0x6 /* val 6, shift 0 */ - #define AC_src_om_dst_alpha 0x7 /* val 7, shift 0 */ - #define AC_src_src_alpha_sat 0x8 /* val 8, shift 0 */ - #define AC_dst_MASK 0xffffff0f /* bits 4-7 */ - #define AC_dst_zero 0x0 /* val 0, shift 4 */ - #define AC_dst_one 0x10 /* val 1, shift 4 */ - #define AC_dst_src_color 0x20 /* val 2, shift 4 */ - #define AC_dst_om_src_color 0x30 /* val 3, shift 4 */ - #define AC_dst_src_alpha 0x40 /* val 4, shift 4 */ - #define AC_dst_om_src_alpha 0x50 /* val 5, shift 4 */ - #define AC_dst_dst_alpha 0x60 /* val 6, shift 4 */ - #define AC_dst_om_dst_alpha 0x70 /* val 7, shift 4 */ - #define AC_amode_MASK 0xfffffcff /* bits 8-9 */ - #define AC_amode_FCOL 0x0 /* val 0, shift 8 */ - #define AC_amode_alpha_channel 0x100 /* val 1, shift 8 */ - #define AC_amode_video_alpha 0x200 /* val 2, shift 8 */ - #define AC_amode_RSVD 0x300 /* val 3, shift 8 */ - #define AC_astipple_MASK 0xfffff7ff /* bit 11 */ - #define AC_astipple_disable 0x0 - #define AC_astipple_enable 0x800 - #define AC_aten_MASK 0xffffefff /* bit 12 */ - #define AC_aten_disable 0x0 - #define AC_aten_enable 0x1000 - #define AC_atmode_MASK 0xffff1fff /* bits 13-15 */ - #define AC_atmode_noacmp 0x0 /* val 0, shift 13 */ - #define AC_atmode_ae 0x4000 /* val 2, shift 13 */ - #define AC_atmode_ane 0x6000 /* val 3, shift 13 */ - #define AC_atmode_alt 0x8000 /* val 4, shift 13 */ - #define AC_atmode_alte 0xa000 /* val 5, shift 13 */ - #define AC_atmode_agt 0xc000 /* val 6, shift 13 */ - #define AC_atmode_agte 0xe000 /* val 7, shift 13 */ - #define AC_atref_MASK 0xff00ffff /* bits 16-23 */ - #define AC_atref_SHIFT 16 - #define AC_alphasel_MASK 0xfcffffff /* bits 24-25 */ - #define AC_alphasel_fromtex 0x0 /* val 0, shift 24 */ - #define AC_alphasel_diffused 0x1000000 /* val 1, shift 24 */ - #define AC_alphasel_modulated 0x2000000 /* val 2, shift 24 */ - #define AC_alphasel_trans 0x3000000 /* val 3, shift 24 */ - - #define AR0_ar0_MASK 0xfffc0000 /* bits 0-17 */ - #define AR0_ar0_SHIFT 0 - - #define AR1_ar1_MASK 0xff000000 /* bits 0-23 */ - #define AR1_ar1_SHIFT 0 - - #define AR2_ar2_MASK 0xfffc0000 /* bits 0-17 */ - #define AR2_ar2_SHIFT 0 - - #define AR3_ar3_MASK 0xff000000 /* bits 0-23 */ - #define AR3_ar3_SHIFT 0 - #define AR3_spage_MASK 0xf8ffffff /* bits 24-26 */ - #define AR3_spage_SHIFT 24 - - #define AR4_ar4_MASK 0xfffc0000 /* bits 0-17 */ - #define AR4_ar4_SHIFT 0 - - #define AR5_ar5_MASK 0xfffc0000 /* bits 0-17 */ - #define AR5_ar5_SHIFT 0 - - #define AR6_ar6_MASK 0xfffc0000 /* bits 0-17 */ - #define AR6_ar6_SHIFT 0 - - #define BC_besen_MASK 0xfffffffe /* bit 0 */ - #define BC_besen_disable 0x0 - #define BC_besen_enable 0x1 - #define BC_besv1srcstp_MASK 0xffffffbf /* bit 6 */ - #define BC_besv1srcstp_even 0x0 - #define BC_besv1srcstp_odd 0x40 - #define BC_besv2srcstp_MASK 0xfffffeff /* bit 8 */ - #define BC_besv2srcstp_disable 0x0 - #define BC_besv2srcstp_enable 0x100 - #define BC_beshfen_MASK 0xfffffbff /* bit 10 */ - #define BC_beshfen_disable 0x0 - #define BC_beshfen_enable 0x400 - #define BC_besvfen_MASK 0xfffff7ff /* bit 11 */ - #define BC_besvfen_disable 0x0 - #define BC_besvfen_enable 0x800 - #define BC_beshfixc_MASK 0xffffefff /* bit 12 */ - #define BC_beshfixc_weight 0x0 - #define BC_beshfixc_coeff 0x1000 - #define BC_bescups_MASK 0xfffeffff /* bit 16 */ - #define BC_bescups_disable 0x0 - #define BC_bescups_enable 0x10000 - #define BC_bes420pl_MASK 0xfffdffff /* bit 17 */ - #define BC_bes420pl_422 0x0 - #define BC_bes420pl_420 0x20000 - #define BC_besdith_MASK 0xfffbffff /* bit 18 */ - #define BC_besdith_disable 0x0 - #define BC_besdith_enable 0x40000 - #define BC_beshmir_MASK 0xfff7ffff /* bit 19 */ - #define BC_beshmir_disable 0x0 - #define BC_beshmir_enable 0x80000 - #define BC_besbwen_MASK 0xffefffff /* bit 20 */ - #define BC_besbwen_color 0x0 - #define BC_besbwen_bw 0x100000 - #define BC_besblank_MASK 0xffdfffff /* bit 21 */ - #define BC_besblank_disable 0x0 - #define BC_besblank_enable 0x200000 - #define BC_besfselm_MASK 0xfeffffff /* bit 24 */ - #define BC_besfselm_soft 0x0 - #define BC_besfselm_hard 0x1000000 - #define BC_besfsel_MASK 0xf9ffffff /* bits 25-26 */ - #define BC_besfsel_a1 0x0 /* val 0, shift 25 */ - #define BC_besfsel_a2 0x2000000 /* val 1, shift 25 */ - #define BC_besfsel_b1 0x4000000 /* val 2, shift 25 */ - #define BC_besfsel_b2 0x6000000 /* val 3, shift 25 */ - - #define BGC_beshzoom_MASK 0xfffffffe /* bit 0 */ - #define BGC_beshzoom_disable 0x0 - #define BGC_beshzoom_enable 0x1 - #define BGC_beshzoomf_MASK 0xfffffffd /* bit 1 */ - #define BGC_beshzoomf_disable 0x0 - #define BGC_beshzoomf_enable 0x2 - #define BGC_bescorder_MASK 0xfffffff7 /* bit 3 */ - #define BGC_bescorder_even 0x0 - #define BGC_bescorder_odd 0x8 - #define BGC_besreghup_MASK 0xffffffef /* bit 4 */ - #define BGC_besreghup_disable 0x0 - #define BGC_besreghup_enable 0x10 - #define BGC_besvcnt_MASK 0xf000ffff /* bits 16-27 */ - #define BGC_besvcnt_SHIFT 16 - - #define BHC_besright_MASK 0xfffff800 /* bits 0-10 */ - #define BHC_besright_SHIFT 0 - #define BHC_besleft_MASK 0xf800ffff /* bits 16-26 */ - #define BHC_besleft_SHIFT 16 - - #define BHISF_beshiscal_MASK 0xffe00003 /* bits 2-20 */ - #define BHISF_beshiscal_SHIFT 2 - - #define BHSE_beshsrcend_MASK 0xfc000003 /* bits 2-25 */ - #define BHSE_beshsrcend_SHIFT 2 - - #define BHSL_beshsrclst_MASK 0xfc00ffff /* bits 16-25 */ - #define BHSL_beshsrclst_SHIFT 16 - - #define BHSS_beshsrcst_MASK 0xfc000003 /* bits 2-25 */ - #define BHSS_beshsrcst_SHIFT 2 - - #define BP_bespitch_MASK 0xfffff000 /* bits 0-11 */ - #define BP_bespitch_SHIFT 0 - - #define BS_besstat_MASK 0xfffffffc /* bits 0-1 */ - #define BS_besstat_a1 0x0 /* val 0, shift 0 */ - #define BS_besstat_a2 0x1 /* val 1, shift 0 */ - #define BS_besstat_b1 0x2 /* val 2, shift 0 */ - #define BS_besstat_b2 0x3 /* val 3, shift 0 */ - - #define BSF_besv1srclast_MASK 0xfffffc00 /* bits 0-9 */ - #define BSF_besv1srclast_SHIFT 0 - - #define BSF_besv2srclst_MASK 0xfffffc00 /* bits 0-9 */ - #define BSF_besv2srclst_SHIFT 0 - - #define BSF_besv1wght_MASK 0xffff0003 /* bits 2-15 */ - #define BSF_besv1wght_SHIFT 2 - #define BSF_besv1wghts_MASK 0xfffeffff /* bit 16 */ - #define BSF_besv1wghts_disable 0x0 - #define BSF_besv1wghts_enable 0x10000 - - #define BSF_besv2wght_MASK 0xffff0003 /* bits 2-15 */ - #define BSF_besv2wght_SHIFT 2 - #define BSF_besv2wghts_MASK 0xfffeffff /* bit 16 */ - #define BSF_besv2wghts_disable 0x0 - #define BSF_besv2wghts_enable 0x10000 - - #define BVC_besbot_MASK 0xfffff800 /* bits 0-10 */ - #define BVC_besbot_SHIFT 0 - #define BVC_bestop_MASK 0xf800ffff /* bits 16-26 */ - #define BVC_bestop_SHIFT 16 - - #define BVISF_besviscal_MASK 0xffe00003 /* bits 2-20 */ - #define BVISF_besviscal_SHIFT 2 - - #define CXB_cxleft_MASK 0xfffff000 /* bits 0-11 */ - #define CXB_cxleft_SHIFT 0 - #define CXB_cxright_MASK 0xf000ffff /* bits 16-27 */ - #define CXB_cxright_SHIFT 16 - - #define DO_dstmap_MASK 0xfffffffe /* bit 0 */ - #define DO_dstmap_fb 0x0 - #define DO_dstmap_sys 0x1 - #define DO_dstacc_MASK 0xfffffffd /* bit 1 */ - #define DO_dstacc_pci 0x0 - #define DO_dstacc_agp 0x2 - #define DO_dstorg_MASK 0x7 /* bits 3-31 */ - #define DO_dstorg_SHIFT 3 - - #define DC_opcod_MASK 0xfffffff0 /* bits 0-3 */ - #define DC_opcod_line_open 0x0 /* val 0, shift 0 */ - #define DC_opcod_autoline_open 0x1 /* val 1, shift 0 */ - #define DC_opcod_line_close 0x2 /* val 2, shift 0 */ - #define DC_opcod_autoline_close 0x3 /* val 3, shift 0 */ - #define DC_opcod_trap 0x4 /* val 4, shift 0 */ - #define DC_opcod_texture_trap 0x6 /* val 6, shift 0 */ - #define DC_opcod_bitblt 0x8 /* val 8, shift 0 */ - #define DC_opcod_iload 0x9 /* val 9, shift 0 */ - #define DC_atype_MASK 0xffffff8f /* bits 4-6 */ - #define DC_atype_rpl 0x0 /* val 0, shift 4 */ - #define DC_atype_rstr 0x10 /* val 1, shift 4 */ - #define DC_atype_zi 0x30 /* val 3, shift 4 */ - #define DC_atype_blk 0x40 /* val 4, shift 4 */ - #define DC_atype_i 0x70 /* val 7, shift 4 */ - #define DC_linear_MASK 0xffffff7f /* bit 7 */ - #define DC_linear_xy 0x0 - #define DC_linear_linear 0x80 - #define DC_zmode_MASK 0xfffff8ff /* bits 8-10 */ - #define DC_zmode_nozcmp 0x0 /* val 0, shift 8 */ - #define DC_zmode_ze 0x200 /* val 2, shift 8 */ - #define DC_zmode_zne 0x300 /* val 3, shift 8 */ - #define DC_zmode_zlt 0x400 /* val 4, shift 8 */ - #define DC_zmode_zlte 0x500 /* val 5, shift 8 */ - #define DC_zmode_zgt 0x600 /* val 6, shift 8 */ - #define DC_zmode_zgte 0x700 /* val 7, shift 8 */ - #define DC_solid_MASK 0xfffff7ff /* bit 11 */ - #define DC_solid_disable 0x0 - #define DC_solid_enable 0x800 - #define DC_arzero_MASK 0xffffefff /* bit 12 */ - #define DC_arzero_disable 0x0 - #define DC_arzero_enable 0x1000 - #define DC_sgnzero_MASK 0xffffdfff /* bit 13 */ - #define DC_sgnzero_disable 0x0 - #define DC_sgnzero_enable 0x2000 - #define DC_shftzero_MASK 0xffffbfff /* bit 14 */ - #define DC_shftzero_disable 0x0 - #define DC_shftzero_enable 0x4000 - #define DC_bop_MASK 0xfff0ffff /* bits 16-19 */ - #define DC_bop_SHIFT 16 - #define DC_trans_MASK 0xff0fffff /* bits 20-23 */ - #define DC_trans_SHIFT 20 - #define DC_bltmod_MASK 0xe1ffffff /* bits 25-28 */ - #define DC_bltmod_bmonolef 0x0 /* val 0, shift 25 */ - #define DC_bltmod_bmonowf 0x8000000 /* val 4, shift 25 */ - #define DC_bltmod_bplan 0x2000000 /* val 1, shift 25 */ - #define DC_bltmod_bfcol 0x4000000 /* val 2, shift 25 */ - #define DC_bltmod_bu32bgr 0x6000000 /* val 3, shift 25 */ - #define DC_bltmod_bu32rgb 0xe000000 /* val 7, shift 25 */ - #define DC_bltmod_bu24bgr 0x16000000 /* val 11, shift 25 */ - #define DC_bltmod_bu24rgb 0x1e000000 /* val 15, shift 25 */ - #define DC_pattern_MASK 0xdfffffff /* bit 29 */ - #define DC_pattern_disable 0x0 - #define DC_pattern_enable 0x20000000 - #define DC_transc_MASK 0xbfffffff /* bit 30 */ - #define DC_transc_disable 0x0 - #define DC_transc_enable 0x40000000 - #define DC_clipdis_MASK 0x7fffffff /* bit 31 */ - #define DC_clipdis_disable 0x0 - #define DC_clipdis_enable 0x80000000 - - #define DS_dwgsyncaddr_MASK 0x3 /* bits 2-31 */ - #define DS_dwgsyncaddr_SHIFT 2 - - #define FS_fifocount_MASK 0xffffff80 /* bits 0-6 */ - #define FS_fifocount_SHIFT 0 - #define FS_bfull_MASK 0xfffffeff /* bit 8 */ - #define FS_bfull_disable 0x0 - #define FS_bfull_enable 0x100 - #define FS_bempty_MASK 0xfffffdff /* bit 9 */ - #define FS_bempty_disable 0x0 - #define FS_bempty_enable 0x200 - - #define XA_fxleft_MASK 0xffff0000 /* bits 0-15 */ - #define XA_fxleft_SHIFT 0 - #define XA_fxright_MASK 0xffff /* bits 16-31 */ - #define XA_fxright_SHIFT 16 - - #define IC_softrapiclr_MASK 0xfffffffe /* bit 0 */ - #define IC_softrapiclr_disable 0x0 - #define IC_softrapiclr_enable 0x1 - #define IC_pickiclr_MASK 0xfffffffb /* bit 2 */ - #define IC_pickiclr_disable 0x0 - #define IC_pickiclr_enable 0x4 - #define IC_vlineiclr_MASK 0xffffffdf /* bit 5 */ - #define IC_vlineiclr_disable 0x0 - #define IC_vlineiclr_enable 0x20 - #define IC_wiclr_MASK 0xffffff7f /* bit 7 */ - #define IC_wiclr_disable 0x0 - #define IC_wiclr_enable 0x80 - #define IC_wciclr_MASK 0xfffffeff /* bit 8 */ - #define IC_wciclr_disable 0x0 - #define IC_wciclr_enable 0x100 - - #define IE_softrapien_MASK 0xfffffffe /* bit 0 */ - #define IE_softrapien_disable 0x0 - #define IE_softrapien_enable 0x1 - #define IE_pickien_MASK 0xfffffffb /* bit 2 */ - #define IE_pickien_disable 0x0 - #define IE_pickien_enable 0x4 - #define IE_vlineien_MASK 0xffffffdf /* bit 5 */ - #define IE_vlineien_disable 0x0 - #define IE_vlineien_enable 0x20 - #define IE_extien_MASK 0xffffffbf /* bit 6 */ - #define IE_extien_disable 0x0 - #define IE_extien_enable 0x40 - #define IE_wien_MASK 0xffffff7f /* bit 7 */ - #define IE_wien_disable 0x0 - #define IE_wien_enable 0x80 - #define IE_wcien_MASK 0xfffffeff /* bit 8 */ - #define IE_wcien_disable 0x0 - #define IE_wcien_enable 0x100 - - #define MA_pwidth_MASK 0xfffffffc /* bits 0-1 */ - #define MA_pwidth_8 0x0 /* val 0, shift 0 */ - #define MA_pwidth_16 0x1 /* val 1, shift 0 */ - #define MA_pwidth_32 0x2 /* val 2, shift 0 */ - #define MA_pwidth_24 0x3 /* val 3, shift 0 */ - #define MA_zwidth_MASK 0xffffffe7 /* bits 3-4 */ - #define MA_zwidth_16 0x0 /* val 0, shift 3 */ - #define MA_zwidth_32 0x8 /* val 1, shift 3 */ - #define MA_zwidth_15 0x10 /* val 2, shift 3 */ - #define MA_zwidth_24 0x18 /* val 3, shift 3 */ - #define MA_memreset_MASK 0xffff7fff /* bit 15 */ - #define MA_memreset_disable 0x0 - #define MA_memreset_enable 0x8000 - #define MA_fogen_MASK 0xfbffffff /* bit 26 */ - #define MA_fogen_disable 0x0 - #define MA_fogen_enable 0x4000000 - #define MA_tlutload_MASK 0xdfffffff /* bit 29 */ - #define MA_tlutload_disable 0x0 - #define MA_tlutload_enable 0x20000000 - #define MA_nodither_MASK 0xbfffffff /* bit 30 */ - #define MA_nodither_disable 0x0 - #define MA_nodither_enable 0x40000000 - #define MA_dit555_MASK 0x7fffffff /* bit 31 */ - #define MA_dit555_disable 0x0 - #define MA_dit555_enable 0x80000000 - - #define MCWS_casltncy_MASK 0xfffffff8 /* bits 0-2 */ - #define MCWS_casltncy_SHIFT 0 - #define MCWS_rrddelay_MASK 0xffffffcf /* bits 4-5 */ - #define MCWS_rcddelay_MASK 0xfffffe7f /* bits 7-8 */ - #define MCWS_rasmin_MASK 0xffffe3ff /* bits 10-12 */ - #define MCWS_rasmin_SHIFT 10 - #define MCWS_rpdelay_MASK 0xffff3fff /* bits 14-15 */ - #define MCWS_wrdelay_MASK 0xfff3ffff /* bits 18-19 */ - #define MCWS_rddelay_MASK 0xffdfffff /* bit 21 */ - #define MCWS_rddelay_disable 0x0 - #define MCWS_rddelay_enable 0x200000 - #define MCWS_smrdelay_MASK 0xfe7fffff /* bits 23-24 */ - #define MCWS_bwcdelay_MASK 0xf3ffffff /* bits 26-27 */ - #define MCWS_bpldelay_MASK 0x1fffffff /* bits 29-31 */ - #define MCWS_bpldelay_SHIFT 29 - - #define MRB_mclkbrd0_MASK 0xfffffff0 /* bits 0-3 */ - #define MRB_mclkbrd0_SHIFT 0 - #define MRB_mclkbrd1_MASK 0xfffffe1f /* bits 5-8 */ - #define MRB_mclkbrd1_SHIFT 5 - #define MRB_strmfctl_MASK 0xff3fffff /* bits 22-23 */ - #define MRB_mrsopcod_MASK 0xe1ffffff /* bits 25-28 */ - #define MRB_mrsopcod_SHIFT 25 - - #define OM_dmamod_MASK 0xfffffff3 /* bits 2-3 */ - #define OM_dmamod_general 0x0 /* val 0, shift 2 */ - #define OM_dmamod_blit 0x4 /* val 1, shift 2 */ - #define OM_dmamod_vector 0x8 /* val 2, shift 2 */ - #define OM_dmamod_vertex 0xc /* val 3, shift 2 */ - #define OM_dmadatasiz_MASK 0xfffffcff /* bits 8-9 */ - #define OM_dmadatasiz_8 0x0 /* val 0, shift 8 */ - #define OM_dmadatasiz_16 0x100 /* val 1, shift 8 */ - #define OM_dmadatasiz_32 0x200 /* val 2, shift 8 */ - #define OM_dirdatasiz_MASK 0xfffcffff /* bits 16-17 */ - #define OM_dirdatasiz_8 0x0 /* val 0, shift 16 */ - #define OM_dirdatasiz_16 0x10000 /* val 1, shift 16 */ - #define OM_dirdatasiz_32 0x20000 /* val 2, shift 16 */ - - #define P_iy_MASK 0xffffe000 /* bits 0-12 */ - #define P_iy_SHIFT 0 - #define P_ylin_MASK 0xffff7fff /* bit 15 */ - #define P_ylin_disable 0x0 - #define P_ylin_enable 0x8000 - - #define PDCA_primod_MASK 0xfffffffc /* bits 0-1 */ - #define PDCA_primod_general 0x0 /* val 0, shift 0 */ - #define PDCA_primod_blit 0x1 /* val 1, shift 0 */ - #define PDCA_primod_vector 0x2 /* val 2, shift 0 */ - #define PDCA_primod_vertex 0x3 /* val 3, shift 0 */ - #define PDCA_primaddress_MASK 0x3 /* bits 2-31 */ - #define PDCA_primaddress_SHIFT 2 - - #define PDEA_primnostart_MASK 0xfffffffe /* bit 0 */ - #define PDEA_primnostart_disable 0x0 - #define PDEA_primnostart_enable 0x1 - #define PDEA_pagpxfer_MASK 0xfffffffd /* bit 1 */ - #define PDEA_pagpxfer_disable 0x0 - #define PDEA_pagpxfer_enable 0x2 - #define PDEA_primend_MASK 0x3 /* bits 2-31 */ - #define PDEA_primend_SHIFT 2 - - #define PLS_primptren0_MASK 0xfffffffe /* bit 0 */ - #define PLS_primptren0_disable 0x0 - #define PLS_primptren0_enable 0x1 - #define PLS_primptren1_MASK 0xfffffffd /* bit 1 */ - #define PLS_primptren1_disable 0x0 - #define PLS_primptren1_enable 0x2 - #define PLS_primptr_MASK 0x7 /* bits 3-31 */ - #define PLS_primptr_SHIFT 3 - - #define R_softreset_MASK 0xfffffffe /* bit 0 */ - #define R_softreset_disable 0x0 - #define R_softreset_enable 0x1 - #define R_softextrst_MASK 0xfffffffd /* bit 1 */ - #define R_softextrst_disable 0x0 - #define R_softextrst_enable 0x2 - - #define SDCA_secmod_MASK 0xfffffffc /* bits 0-1 */ - #define SDCA_secmod_general 0x0 /* val 0, shift 0 */ - #define SDCA_secmod_blit 0x1 /* val 1, shift 0 */ - #define SDCA_secmod_vector 0x2 /* val 2, shift 0 */ - #define SDCA_secmod_vertex 0x3 /* val 3, shift 0 */ - #define SDCA_secaddress_MASK 0x3 /* bits 2-31 */ - #define SDCA_secaddress_SHIFT 2 - - #define SDEA_sagpxfer_MASK 0xfffffffd /* bit 1 */ - #define SDEA_sagpxfer_disable 0x0 - #define SDEA_sagpxfer_enable 0x2 - #define SDEA_secend_MASK 0x3 /* bits 2-31 */ - #define SDEA_secend_SHIFT 2 - - #define SETDCA_setupmod_MASK 0xfffffffc /* bits 0-1 */ - #define SETDCA_setupmod_vertlist 0x0 /* val 0, shift 0 */ - #define SETDCA_setupaddress_MASK 0x3 /* bits 2-31 */ - #define SETDCA_setupaddress_SHIFT 2 - - #define SETDEA_setupagpxfer_MASK 0xfffffffd /* bit 1 */ - #define SETDEA_setupagpxfer_disable 0x0 - #define SETDEA_setupagpxfer_enable 0x2 - #define SETDEA_setupend_MASK 0x3 /* bits 2-31 */ - #define SETDEA_setupend_SHIFT 2 - - #define S_sdydxl_MASK 0xfffffffe /* bit 0 */ - #define S_sdydxl_y 0x0 - #define S_sdydxl_x 0x1 - #define S_scanleft_MASK 0xfffffffe /* bit 0 */ - #define S_scanleft_disable 0x0 - #define S_scanleft_enable 0x1 - #define S_sdxl_MASK 0xfffffffd /* bit 1 */ - #define S_sdxl_pos 0x0 - #define S_sdxl_neg 0x2 - #define S_sdy_MASK 0xfffffffb /* bit 2 */ - #define S_sdy_pos 0x0 - #define S_sdy_neg 0x4 - #define S_sdxr_MASK 0xffffffdf /* bit 5 */ - #define S_sdxr_pos 0x0 - #define S_sdxr_neg 0x20 - #define S_brkleft_MASK 0xfffffeff /* bit 8 */ - #define S_brkleft_disable 0x0 - #define S_brkleft_enable 0x100 - #define S_errorinit_MASK 0x7fffffff /* bit 31 */ - #define S_errorinit_disable 0x0 - #define S_errorinit_enable 0x80000000 - - #define FSC_x_off_MASK 0xfffffff0 /* bits 0-3 */ - #define FSC_x_off_SHIFT 0 - #define FSC_funcnt_MASK 0xffffff80 /* bits 0-6 */ - #define FSC_funcnt_SHIFT 0 - #define FSC_y_off_MASK 0xffffff8f /* bits 4-6 */ - #define FSC_y_off_SHIFT 4 - #define FSC_funoff_MASK 0xffc0ffff /* bits 16-21 */ - #define FSC_funoff_SHIFT 16 - #define FSC_stylelen_MASK 0xffc0ffff /* bits 16-21 */ - #define FSC_stylelen_SHIFT 16 - - - #define STH_softraphand_MASK 0x3 /* bits 2-31 */ - #define STH_softraphand_SHIFT 2 - - #define SO_srcmap_MASK 0xfffffffe /* bit 0 */ - #define SO_srcmap_fb 0x0 - #define SO_srcmap_sys 0x1 - #define SO_srcacc_MASK 0xfffffffd /* bit 1 */ - #define SO_srcacc_pci 0x0 - #define SO_srcacc_agp 0x2 - #define SO_srcorg_MASK 0x7 /* bits 3-31 */ - #define SO_srcorg_SHIFT 3 - - #define STAT_softrapen_MASK 0xfffffffe /* bit 0 */ - #define STAT_softrapen_disable 0x0 - #define STAT_softrapen_enable 0x1 - #define STAT_pickpen_MASK 0xfffffffb /* bit 2 */ - #define STAT_pickpen_disable 0x0 - #define STAT_pickpen_enable 0x4 - #define STAT_vsyncsts_MASK 0xfffffff7 /* bit 3 */ - #define STAT_vsyncsts_disable 0x0 - #define STAT_vsyncsts_enable 0x8 - #define STAT_vsyncpen_MASK 0xffffffef /* bit 4 */ - #define STAT_vsyncpen_disable 0x0 - #define STAT_vsyncpen_enable 0x10 - #define STAT_vlinepen_MASK 0xffffffdf /* bit 5 */ - #define STAT_vlinepen_disable 0x0 - #define STAT_vlinepen_enable 0x20 - #define STAT_extpen_MASK 0xffffffbf /* bit 6 */ - #define STAT_extpen_disable 0x0 - #define STAT_extpen_enable 0x40 - #define STAT_wpen_MASK 0xffffff7f /* bit 7 */ - #define STAT_wpen_disable 0x0 - #define STAT_wpen_enable 0x80 - #define STAT_wcpen_MASK 0xfffffeff /* bit 8 */ - #define STAT_wcpen_disable 0x0 - #define STAT_wcpen_enable 0x100 - #define STAT_dwgengsts_MASK 0xfffeffff /* bit 16 */ - #define STAT_dwgengsts_disable 0x0 - #define STAT_dwgengsts_enable 0x10000 - #define STAT_endprdmasts_MASK 0xfffdffff /* bit 17 */ - #define STAT_endprdmasts_disable 0x0 - #define STAT_endprdmasts_enable 0x20000 - #define STAT_wbusy_MASK 0xfffbffff /* bit 18 */ - #define STAT_wbusy_disable 0x0 - #define STAT_wbusy_enable 0x40000 - #define STAT_swflag_MASK 0xfffffff /* bits 28-31 */ - #define STAT_swflag_SHIFT 28 - - #define S_sref_MASK 0xffffff00 /* bits 0-7 */ - #define S_sref_SHIFT 0 - #define S_smsk_MASK 0xffff00ff /* bits 8-15 */ - #define S_smsk_SHIFT 8 - #define S_swtmsk_MASK 0xff00ffff /* bits 16-23 */ - #define S_swtmsk_SHIFT 16 - - #define SC_smode_MASK 0xfffffff8 /* bits 0-2 */ - #define SC_smode_salways 0x0 /* val 0, shift 0 */ - #define SC_smode_snever 0x1 /* val 1, shift 0 */ - #define SC_smode_se 0x2 /* val 2, shift 0 */ - #define SC_smode_sne 0x3 /* val 3, shift 0 */ - #define SC_smode_slt 0x4 /* val 4, shift 0 */ - #define SC_smode_slte 0x5 /* val 5, shift 0 */ - #define SC_smode_sgt 0x6 /* val 6, shift 0 */ - #define SC_smode_sgte 0x7 /* val 7, shift 0 */ - #define SC_sfailop_MASK 0xffffffc7 /* bits 3-5 */ - #define SC_sfailop_keep 0x0 /* val 0, shift 3 */ - #define SC_sfailop_zero 0x8 /* val 1, shift 3 */ - #define SC_sfailop_replace 0x10 /* val 2, shift 3 */ - #define SC_sfailop_incrsat 0x18 /* val 3, shift 3 */ - #define SC_sfailop_decrsat 0x20 /* val 4, shift 3 */ - #define SC_sfailop_invert 0x28 /* val 5, shift 3 */ - #define SC_sfailop_incr 0x30 /* val 6, shift 3 */ - #define SC_sfailop_decr 0x38 /* val 7, shift 3 */ - #define SC_szfailop_MASK 0xfffffe3f /* bits 6-8 */ - #define SC_szfailop_keep 0x0 /* val 0, shift 6 */ - #define SC_szfailop_zero 0x40 /* val 1, shift 6 */ - #define SC_szfailop_replace 0x80 /* val 2, shift 6 */ - #define SC_szfailop_incrsat 0xc0 /* val 3, shift 6 */ - #define SC_szfailop_decrsat 0x100 /* val 4, shift 6 */ - #define SC_szfailop_invert 0x140 /* val 5, shift 6 */ - #define SC_szfailop_incr 0x180 /* val 6, shift 6 */ - #define SC_szfailop_decr 0x1c0 /* val 7, shift 6 */ - #define SC_szpassop_MASK 0xfffff1ff /* bits 9-11 */ - #define SC_szpassop_keep 0x0 /* val 0, shift 9 */ - #define SC_szpassop_zero 0x200 /* val 1, shift 9 */ - #define SC_szpassop_replace 0x400 /* val 2, shift 9 */ - #define SC_szpassop_incrsat 0x600 /* val 3, shift 9 */ - #define SC_szpassop_decrsat 0x800 /* val 4, shift 9 */ - #define SC_szpassop_invert 0xa00 /* val 5, shift 9 */ - #define SC_szpassop_incr 0xc00 /* val 6, shift 9 */ - #define SC_szpassop_decr 0xe00 /* val 7, shift 9 */ - - #define TD1_color1arg2selMASK 0xfffffffc /* bits 0-1 */ - #define TD1_color1alphaselMASK 0xffffffe3 /* bits 2-4 */ - #define TD1_color1alphaselSHIFT 2 - #define TD1_color1arg1alphaMASK 0xffffffdf /* bit 5 */ - #define TD1_color1arg1alphadisable 0x0 - #define TD1_color1arg1alphaenable 0x20 - #define TD1_color1arg1invMASK 0xffffffbf /* bit 6 */ - #define TD1_color1arg1invdisable 0x0 - #define TD1_color1arg1invenable 0x40 - #define TD1_color1arg2alphaMASK 0xffffff7f /* bit 7 */ - #define TD1_color1arg2alphadisable 0x0 - #define TD1_color1arg2alphaenable 0x80 - #define TD1_color1arg2invMASK 0xfffffeff /* bit 8 */ - #define TD1_color1arg2invdisable 0x0 - #define TD1_color1arg2invenable 0x100 - #define TD1_color1alpha1invMASK 0xfffffdff /* bit 9 */ - #define TD1_color1alpha1invdisable 0x0 - #define TD1_color1alpha1invenable 0x200 - #define TD1_color1alpha2invMASK 0xfffffbff /* bit 10 */ - #define TD1_color1alpha2invdisable 0x0 - #define TD1_color1alpha2invenable 0x400 - #define TD1_color1selMASK 0xff9fffff /* bits 21-22 */ - #define TD1_color1selarg1 0x0 /* val 0, shift 21 */ - #define TD1_color1selarg2 0x200000 /* val 1, shift 21 */ - #define TD1_color1seladd 0x400000 /* val 2, shift 21 */ - #define TD1_color1selmul 0x600000 /* val 3, shift 21 */ - #define TD1_alpha1selMASK 0x3fffffff /* bits 30-31 */ - #define TD1_alpha1selarg1 0x0 /* val 0, shift 30 */ - #define TD1_alpha1selarg2 0x40000000 /* val 1, shift 30 */ - #define TD1_alpha1seladd 0x80000000 /* val 2, shift 30 */ - #define TD1_alpha1selmul 0xc0000000 /* val 3, shift 30 */ - - #define TST_ramtsten_MASK 0xfffffffe /* bit 0 */ - #define TST_ramtsten_disable 0x0 - #define TST_ramtsten_enable 0x1 - #define TST_ramtstdone_MASK 0xfffffffd /* bit 1 */ - #define TST_ramtstdone_disable 0x0 - #define TST_ramtstdone_enable 0x2 - #define TST_wramtstpass_MASK 0xfffffffb /* bit 2 */ - #define TST_wramtstpass_disable 0x0 - #define TST_wramtstpass_enable 0x4 - #define TST_tcachetstpass_MASK 0xfffffff7 /* bit 3 */ - #define TST_tcachetstpass_disable 0x0 - #define TST_tcachetstpass_enable 0x8 - #define TST_tluttstpass_MASK 0xffffffef /* bit 4 */ - #define TST_tluttstpass_disable 0x0 - #define TST_tluttstpass_enable 0x10 - #define TST_luttstpass_MASK 0xffffffdf /* bit 5 */ - #define TST_luttstpass_disable 0x0 - #define TST_luttstpass_enable 0x20 - #define TST_besramtstpass_MASK 0xffffffbf /* bit 6 */ - #define TST_besramtstpass_disable 0x0 - #define TST_besramtstpass_enable 0x40 - #define TST_ringen_MASK 0xfffffeff /* bit 8 */ - #define TST_ringen_disable 0x0 - #define TST_ringen_enable 0x100 - #define TST_apllbyp_MASK 0xfffffdff /* bit 9 */ - #define TST_apllbyp_disable 0x0 - #define TST_apllbyp_enable 0x200 - #define TST_hiten_MASK 0xfffffbff /* bit 10 */ - #define TST_hiten_disable 0x0 - #define TST_hiten_enable 0x400 - #define TST_tmode_MASK 0xffffc7ff /* bits 11-13 */ - #define TST_tmode_SHIFT 11 - #define TST_tclksel_MASK 0xfffe3fff /* bits 14-16 */ - #define TST_tclksel_SHIFT 14 - #define TST_ringcnten_MASK 0xfffdffff /* bit 17 */ - #define TST_ringcnten_disable 0x0 - #define TST_ringcnten_enable 0x20000 - #define TST_ringcnt_MASK 0xc003ffff /* bits 18-29 */ - #define TST_ringcnt_SHIFT 18 - #define TST_ringcntclksl_MASK 0xbfffffff /* bit 30 */ - #define TST_ringcntclksl_disable 0x0 - #define TST_ringcntclksl_enable 0x40000000 - #define TST_biosboot_MASK 0x7fffffff /* bit 31 */ - #define TST_biosboot_disable 0x0 - #define TST_biosboot_enable 0x80000000 - - #define TMC_tformat_MASK 0xfffffff0 /* bits 0-3 */ - #define TMC_tformat_tw4 0x0 /* val 0, shift 0 */ - #define TMC_tformat_tw8 0x1 /* val 1, shift 0 */ - #define TMC_tformat_tw15 0x2 /* val 2, shift 0 */ - #define TMC_tformat_tw16 0x3 /* val 3, shift 0 */ - #define TMC_tformat_tw12 0x4 /* val 4, shift 0 */ - #define TMC_tformat_tw32 0x6 /* val 6, shift 0 */ - #define TMC_tformat_tw422 0xa /* val 10, shift 0 */ - #define TMC_tpitchlin_MASK 0xfffffeff /* bit 8 */ - #define TMC_tpitchlin_disable 0x0 - #define TMC_tpitchlin_enable 0x100 - #define TMC_tpitchext_MASK 0xfff001ff /* bits 9-19 */ - #define TMC_tpitchext_SHIFT 9 - #define TMC_tpitch_MASK 0xfff8ffff /* bits 16-18 */ - #define TMC_tpitch_SHIFT 16 - #define TMC_owalpha_MASK 0xffbfffff /* bit 22 */ - #define TMC_owalpha_disable 0x0 - #define TMC_owalpha_enable 0x400000 - #define TMC_azeroextend_MASK 0xff7fffff /* bit 23 */ - #define TMC_azeroextend_disable 0x0 - #define TMC_azeroextend_enable 0x800000 - #define TMC_decalckey_MASK 0xfeffffff /* bit 24 */ - #define TMC_decalckey_disable 0x0 - #define TMC_decalckey_enable 0x1000000 - #define TMC_takey_MASK 0xfdffffff /* bit 25 */ - #define TMC_takey_0 0x0 - #define TMC_takey_1 0x2000000 - #define TMC_tamask_MASK 0xfbffffff /* bit 26 */ - #define TMC_tamask_0 0x0 - #define TMC_tamask_1 0x4000000 - #define TMC_clampv_MASK 0xf7ffffff /* bit 27 */ - #define TMC_clampv_disable 0x0 - #define TMC_clampv_enable 0x8000000 - #define TMC_clampu_MASK 0xefffffff /* bit 28 */ - #define TMC_clampu_disable 0x0 - #define TMC_clampu_enable 0x10000000 - #define TMC_tmodulate_MASK 0xdfffffff /* bit 29 */ - #define TMC_tmodulate_disable 0x0 - #define TMC_tmodulate_enable 0x20000000 - #define TMC_strans_MASK 0xbfffffff /* bit 30 */ - #define TMC_strans_disable 0x0 - #define TMC_strans_enable 0x40000000 - #define TMC_itrans_MASK 0x7fffffff /* bit 31 */ - #define TMC_itrans_disable 0x0 - #define TMC_itrans_enable 0x80000000 - - #define TMC_decalblend_MASK 0xfffffffe /* bit 0 */ - #define TMC_decalblend_disable 0x0 - #define TMC_decalblend_enable 0x1 - #define TMC_idecal_MASK 0xfffffffd /* bit 1 */ - #define TMC_idecal_disable 0x0 - #define TMC_idecal_enable 0x2 - #define TMC_decaldis_MASK 0xfffffffb /* bit 2 */ - #define TMC_decaldis_disable 0x0 - #define TMC_decaldis_enable 0x4 - #define TMC_ckstransdis_MASK 0xffffffef /* bit 4 */ - #define TMC_ckstransdis_disable 0x0 - #define TMC_ckstransdis_enable 0x10 - #define TMC_borderen_MASK 0xffffffdf /* bit 5 */ - #define TMC_borderen_disable 0x0 - #define TMC_borderen_enable 0x20 - #define TMC_specen_MASK 0xffffffbf /* bit 6 */ - #define TMC_specen_disable 0x0 - #define TMC_specen_enable 0x40 - - #define TF_minfilter_MASK 0xfffffff0 /* bits 0-3 */ - #define TF_minfilter_nrst 0x0 /* val 0, shift 0 */ - #define TF_minfilter_bilin 0x2 /* val 2, shift 0 */ - #define TF_minfilter_cnst 0x3 /* val 3, shift 0 */ - #define TF_minfilter_mm1s 0x8 /* val 8, shift 0 */ - #define TF_minfilter_mm2s 0x9 /* val 9, shift 0 */ - #define TF_minfilter_mm4s 0xa /* val 10, shift 0 */ - #define TF_minfilter_mm8s 0xc /* val 12, shift 0 */ - #define TF_magfilter_MASK 0xffffff0f /* bits 4-7 */ - #define TF_magfilter_nrst 0x0 /* val 0, shift 4 */ - #define TF_magfilter_bilin 0x20 /* val 2, shift 4 */ - #define TF_magfilter_cnst 0x30 /* val 3, shift 4 */ - #define TF_avgstride_MASK 0xfff7ffff /* bit 19 */ - #define TF_avgstride_disable 0x0 - #define TF_avgstride_enable 0x80000 - #define TF_filteralpha_MASK 0xffefffff /* bit 20 */ - #define TF_filteralpha_disable 0x0 - #define TF_filteralpha_enable 0x100000 - #define TF_fthres_MASK 0xe01fffff /* bits 21-28 */ - #define TF_fthres_SHIFT 21 - #define TF_mapnb_MASK 0x1fffffff /* bits 29-31 */ - #define TF_mapnb_SHIFT 29 - - #define TH_th_MASK 0xffffffc0 /* bits 0-5 */ - #define TH_th_SHIFT 0 - #define TH_rfh_MASK 0xffff81ff /* bits 9-14 */ - #define TH_rfh_SHIFT 9 - #define TH_thmask_MASK 0xe003ffff /* bits 18-28 */ - #define TH_thmask_SHIFT 18 - - #define TO_texorgmap_MASK 0xfffffffe /* bit 0 */ - #define TO_texorgmap_fb 0x0 - #define TO_texorgmap_sys 0x1 - #define TO_texorgacc_MASK 0xfffffffd /* bit 1 */ - #define TO_texorgacc_pci 0x0 - #define TO_texorgacc_agp 0x2 - #define TO_texorg_MASK 0x1f /* bits 5-31 */ - #define TO_texorg_SHIFT 5 - - #define TT_tckey_MASK 0xffff0000 /* bits 0-15 */ - #define TT_tckey_SHIFT 0 - #define TT_tkmask_MASK 0xffff /* bits 16-31 */ - #define TT_tkmask_SHIFT 16 - - #define TT_tckeyh_MASK 0xffff0000 /* bits 0-15 */ - #define TT_tckeyh_SHIFT 0 - #define TT_tkmaskh_MASK 0xffff /* bits 16-31 */ - #define TT_tkmaskh_SHIFT 16 - - #define TW_tw_MASK 0xffffffc0 /* bits 0-5 */ - #define TW_tw_SHIFT 0 - #define TW_rfw_MASK 0xffff81ff /* bits 9-14 */ - #define TW_rfw_SHIFT 9 - #define TW_twmask_MASK 0xe003ffff /* bits 18-28 */ - #define TW_twmask_SHIFT 18 - - #define WAS_seqdst0_MASK 0xffffffc0 /* bits 0-5 */ - #define WAS_seqdst0_SHIFT 0 - #define WAS_seqdst1_MASK 0xfffff03f /* bits 6-11 */ - #define WAS_seqdst1_SHIFT 6 - #define WAS_seqdst2_MASK 0xfffc0fff /* bits 12-17 */ - #define WAS_seqdst2_SHIFT 12 - #define WAS_seqdst3_MASK 0xff03ffff /* bits 18-23 */ - #define WAS_seqdst3_SHIFT 18 - #define WAS_seqlen_MASK 0xfcffffff /* bits 24-25 */ - #define WAS_wfirsttag_MASK 0xfbffffff /* bit 26 */ - #define WAS_wfirsttag_disable 0x0 - #define WAS_wfirsttag_enable 0x4000000 - #define WAS_wsametag_MASK 0xf7ffffff /* bit 27 */ - #define WAS_wsametag_disable 0x0 - #define WAS_wsametag_enable 0x8000000 - #define WAS_seqoff_MASK 0xefffffff /* bit 28 */ - #define WAS_seqoff_disable 0x0 - #define WAS_seqoff_enable 0x10000000 - - #define WMA_wcodeaddr_MASK 0xff /* bits 8-31 */ - #define WMA_wcodeaddr_SHIFT 8 - - #define WF_walustsflag_MASK 0xffffff00 /* bits 0-7 */ - #define WF_walustsflag_SHIFT 0 - #define WF_walucfgflag_MASK 0xffff00ff /* bits 8-15 */ - #define WF_walucfgflag_SHIFT 8 - #define WF_wprgflag_MASK 0xffff /* bits 16-31 */ - #define WF_wprgflag_SHIFT 16 - - #define WF1_walustsflag1_MASK 0xffffff00 /* bits 0-7 */ - #define WF1_walustsflag1_SHIFT 0 - #define WF1_walucfgflag1_MASK 0xffff00ff /* bits 8-15 */ - #define WF1_walucfgflag1_SHIFT 8 - #define WF1_wprgflag1_MASK 0xffff /* bits 16-31 */ - #define WF1_wprgflag1_SHIFT 16 - - #define WGV_wgetmsbmin_MASK 0xffffffe0 /* bits 0-4 */ - #define WGV_wgetmsbmin_SHIFT 0 - #define WGV_wgetmsbmax_MASK 0xffffe0ff /* bits 8-12 */ - #define WGV_wgetmsbmax_SHIFT 8 - #define WGV_wbrklefttop_MASK 0xfffeffff /* bit 16 */ - #define WGV_wbrklefttop_disable 0x0 - #define WGV_wbrklefttop_enable 0x10000 - #define WGV_wfastcrop_MASK 0xfffdffff /* bit 17 */ - #define WGV_wfastcrop_disable 0x0 - #define WGV_wfastcrop_enable 0x20000 - #define WGV_wcentersnap_MASK 0xfffbffff /* bit 18 */ - #define WGV_wcentersnap_disable 0x0 - #define WGV_wcentersnap_enable 0x40000 - #define WGV_wbrkrighttop_MASK 0xfff7ffff /* bit 19 */ - #define WGV_wbrkrighttop_disable 0x0 - #define WGV_wbrkrighttop_enable 0x80000 - - #define WIA_wmode_MASK 0xfffffffc /* bits 0-1 */ - #define WIA_wmode_suspend 0x0 /* val 0, shift 0 */ - #define WIA_wmode_resume 0x1 /* val 1, shift 0 */ - #define WIA_wmode_jump 0x2 /* val 2, shift 0 */ - #define WIA_wmode_start 0x3 /* val 3, shift 0 */ - #define WIA_wagp_MASK 0xfffffffb /* bit 2 */ - #define WIA_wagp_pci 0x0 - #define WIA_wagp_agp 0x4 - #define WIA_wiaddr_MASK 0x7 /* bits 3-31 */ - #define WIA_wiaddr_SHIFT 3 - - #define WIA2_wmode_MASK 0xfffffffc /* bits 0-1 */ - #define WIA2_wmode_suspend 0x0 /* val 0, shift 0 */ - #define WIA2_wmode_resume 0x1 /* val 1, shift 0 */ - #define WIA2_wmode_jump 0x2 /* val 2, shift 0 */ - #define WIA2_wmode_start 0x3 /* val 3, shift 0 */ - #define WIA2_wagp_MASK 0xfffffffb /* bit 2 */ - #define WIA2_wagp_pci 0x0 - #define WIA2_wagp_agp 0x4 - #define WIA2_wiaddr_MASK 0x7 /* bits 3-31 */ - #define WIA2_wiaddr_SHIFT 3 - - #define WIMA_wimemaddr_MASK 0xffffff00 /* bits 0-7 */ - #define WIMA_wimemaddr_SHIFT 0 - - #define WM_wucodecache_MASK 0xfffffffe /* bit 0 */ - #define WM_wucodecache_disable 0x0 - #define WM_wucodecache_enable 0x1 - #define WM_wmaster_MASK 0xfffffffd /* bit 1 */ - #define WM_wmaster_disable 0x0 - #define WM_wmaster_enable 0x2 - #define WM_wcacheflush_MASK 0xfffffff7 /* bit 3 */ - #define WM_wcacheflush_disable 0x0 - #define WM_wcacheflush_enable 0x8 - - #define WVS_wvrtxsz_MASK 0xffffffc0 /* bits 0-5 */ - #define WVS_wvrtxsz_SHIFT 0 - #define WVS_primsz_MASK 0xffffc0ff /* bits 8-13 */ - #define WVS_primsz_SHIFT 8 - - #define XYEA_x_end_MASK 0xffff0000 /* bits 0-15 */ - #define XYEA_x_end_SHIFT 0 - #define XYEA_y_end_MASK 0xffff /* bits 16-31 */ - #define XYEA_y_end_SHIFT 16 - - #define XYSA_x_start_MASK 0xffff0000 /* bits 0-15 */ - #define XYSA_x_start_SHIFT 0 - #define XYSA_y_start_MASK 0xffff /* bits 16-31 */ - #define XYSA_y_start_SHIFT 16 - - #define YA_ydst_MASK 0xff800000 /* bits 0-22 */ - #define YA_ydst_SHIFT 0 - #define YA_sellin_MASK 0x1fffffff /* bits 29-31 */ - #define YA_sellin_SHIFT 29 - - #define YDL_length_MASK 0xffff0000 /* bits 0-15 */ - #define YDL_length_SHIFT 0 - #define YDL_yval_MASK 0xffff /* bits 16-31 */ - #define YDL_yval_SHIFT 16 - - #define ZO_zorgmap_MASK 0xfffffffe /* bit 0 */ - #define ZO_zorgmap_fb 0x0 - #define ZO_zorgmap_sys 0x1 - #define ZO_zorgacc_MASK 0xfffffffd /* bit 1 */ - #define ZO_zorgacc_pci 0x0 - #define ZO_zorgacc_agp 0x2 - #define ZO_zorg_MASK 0x3 /* bits 2-31 */ - #define ZO_zorg_SHIFT 2 +# define AGP_PLL_agp2xpllen_MASK 0xfffffffe /* bit 0 */ +# define AGP_PLL_agp2xpllen_disable 0x0 +# define AGP_PLL_agp2xpllen_enable 0x1 + +# define AC_src_MASK 0xfffffff0 /* bits 0-3 */ +# define AC_src_zero 0x0 /* val 0, shift 0 */ +# define AC_src_one 0x1 /* val 1, shift 0 */ +# define AC_src_dst_color 0x2 /* val 2, shift 0 */ +# define AC_src_om_dst_color 0x3 /* val 3, shift 0 */ +# define AC_src_src_alpha 0x4 /* val 4, shift 0 */ +# define AC_src_om_src_alpha 0x5 /* val 5, shift 0 */ +# define AC_src_dst_alpha 0x6 /* val 6, shift 0 */ +# define AC_src_om_dst_alpha 0x7 /* val 7, shift 0 */ +# define AC_src_src_alpha_sat 0x8 /* val 8, shift 0 */ +# define AC_dst_MASK 0xffffff0f /* bits 4-7 */ +# define AC_dst_zero 0x0 /* val 0, shift 4 */ +# define AC_dst_one 0x10 /* val 1, shift 4 */ +# define AC_dst_src_color 0x20 /* val 2, shift 4 */ +# define AC_dst_om_src_color 0x30 /* val 3, shift 4 */ +# define AC_dst_src_alpha 0x40 /* val 4, shift 4 */ +# define AC_dst_om_src_alpha 0x50 /* val 5, shift 4 */ +# define AC_dst_dst_alpha 0x60 /* val 6, shift 4 */ +# define AC_dst_om_dst_alpha 0x70 /* val 7, shift 4 */ +# define AC_amode_MASK 0xfffffcff /* bits 8-9 */ +# define AC_amode_FCOL 0x0 /* val 0, shift 8 */ +# define AC_amode_alpha_channel 0x100 /* val 1, shift 8 */ +# define AC_amode_video_alpha 0x200 /* val 2, shift 8 */ +# define AC_amode_RSVD 0x300 /* val 3, shift 8 */ +# define AC_astipple_MASK 0xfffff7ff /* bit 11 */ +# define AC_astipple_disable 0x0 +# define AC_astipple_enable 0x800 +# define AC_aten_MASK 0xffffefff /* bit 12 */ +# define AC_aten_disable 0x0 +# define AC_aten_enable 0x1000 +# define AC_atmode_MASK 0xffff1fff /* bits 13-15 */ +# define AC_atmode_noacmp 0x0 /* val 0, shift 13 */ +# define AC_atmode_ae 0x4000 /* val 2, shift 13 */ +# define AC_atmode_ane 0x6000 /* val 3, shift 13 */ +# define AC_atmode_alt 0x8000 /* val 4, shift 13 */ +# define AC_atmode_alte 0xa000 /* val 5, shift 13 */ +# define AC_atmode_agt 0xc000 /* val 6, shift 13 */ +# define AC_atmode_agte 0xe000 /* val 7, shift 13 */ +# define AC_atref_MASK 0xff00ffff /* bits 16-23 */ +# define AC_atref_SHIFT 16 +# define AC_alphasel_MASK 0xfcffffff /* bits 24-25 */ +# define AC_alphasel_fromtex 0x0 /* val 0, shift 24 */ +# define AC_alphasel_diffused 0x1000000 /* val 1, shift 24 */ +# define AC_alphasel_modulated 0x2000000 /* val 2, shift 24 */ +# define AC_alphasel_trans 0x3000000 /* val 3, shift 24 */ + +# define AR0_ar0_MASK 0xfffc0000 /* bits 0-17 */ +# define AR0_ar0_SHIFT 0 + +# define AR1_ar1_MASK 0xff000000 /* bits 0-23 */ +# define AR1_ar1_SHIFT 0 + +# define AR2_ar2_MASK 0xfffc0000 /* bits 0-17 */ +# define AR2_ar2_SHIFT 0 + +# define AR3_ar3_MASK 0xff000000 /* bits 0-23 */ +# define AR3_ar3_SHIFT 0 +# define AR3_spage_MASK 0xf8ffffff /* bits 24-26 */ +# define AR3_spage_SHIFT 24 + +# define AR4_ar4_MASK 0xfffc0000 /* bits 0-17 */ +# define AR4_ar4_SHIFT 0 + +# define AR5_ar5_MASK 0xfffc0000 /* bits 0-17 */ +# define AR5_ar5_SHIFT 0 + +# define AR6_ar6_MASK 0xfffc0000 /* bits 0-17 */ +# define AR6_ar6_SHIFT 0 + +# define BC_besen_MASK 0xfffffffe /* bit 0 */ +# define BC_besen_disable 0x0 +# define BC_besen_enable 0x1 +# define BC_besv1srcstp_MASK 0xffffffbf /* bit 6 */ +# define BC_besv1srcstp_even 0x0 +# define BC_besv1srcstp_odd 0x40 +# define BC_besv2srcstp_MASK 0xfffffeff /* bit 8 */ +# define BC_besv2srcstp_disable 0x0 +# define BC_besv2srcstp_enable 0x100 +# define BC_beshfen_MASK 0xfffffbff /* bit 10 */ +# define BC_beshfen_disable 0x0 +# define BC_beshfen_enable 0x400 +# define BC_besvfen_MASK 0xfffff7ff /* bit 11 */ +# define BC_besvfen_disable 0x0 +# define BC_besvfen_enable 0x800 +# define BC_beshfixc_MASK 0xffffefff /* bit 12 */ +# define BC_beshfixc_weight 0x0 +# define BC_beshfixc_coeff 0x1000 +# define BC_bescups_MASK 0xfffeffff /* bit 16 */ +# define BC_bescups_disable 0x0 +# define BC_bescups_enable 0x10000 +# define BC_bes420pl_MASK 0xfffdffff /* bit 17 */ +# define BC_bes420pl_422 0x0 +# define BC_bes420pl_420 0x20000 +# define BC_besdith_MASK 0xfffbffff /* bit 18 */ +# define BC_besdith_disable 0x0 +# define BC_besdith_enable 0x40000 +# define BC_beshmir_MASK 0xfff7ffff /* bit 19 */ +# define BC_beshmir_disable 0x0 +# define BC_beshmir_enable 0x80000 +# define BC_besbwen_MASK 0xffefffff /* bit 20 */ +# define BC_besbwen_color 0x0 +# define BC_besbwen_bw 0x100000 +# define BC_besblank_MASK 0xffdfffff /* bit 21 */ +# define BC_besblank_disable 0x0 +# define BC_besblank_enable 0x200000 +# define BC_besfselm_MASK 0xfeffffff /* bit 24 */ +# define BC_besfselm_soft 0x0 +# define BC_besfselm_hard 0x1000000 +# define BC_besfsel_MASK 0xf9ffffff /* bits 25-26 */ +# define BC_besfsel_a1 0x0 /* val 0, shift 25 */ +# define BC_besfsel_a2 0x2000000 /* val 1, shift 25 */ +# define BC_besfsel_b1 0x4000000 /* val 2, shift 25 */ +# define BC_besfsel_b2 0x6000000 /* val 3, shift 25 */ + +# define BGC_beshzoom_MASK 0xfffffffe /* bit 0 */ +# define BGC_beshzoom_disable 0x0 +# define BGC_beshzoom_enable 0x1 +# define BGC_beshzoomf_MASK 0xfffffffd /* bit 1 */ +# define BGC_beshzoomf_disable 0x0 +# define BGC_beshzoomf_enable 0x2 +# define BGC_bescorder_MASK 0xfffffff7 /* bit 3 */ +# define BGC_bescorder_even 0x0 +# define BGC_bescorder_odd 0x8 +# define BGC_besreghup_MASK 0xffffffef /* bit 4 */ +# define BGC_besreghup_disable 0x0 +# define BGC_besreghup_enable 0x10 +# define BGC_besvcnt_MASK 0xf000ffff /* bits 16-27 */ +# define BGC_besvcnt_SHIFT 16 + +# define BHC_besright_MASK 0xfffff800 /* bits 0-10 */ +# define BHC_besright_SHIFT 0 +# define BHC_besleft_MASK 0xf800ffff /* bits 16-26 */ +# define BHC_besleft_SHIFT 16 + +# define BHISF_beshiscal_MASK 0xffe00003 /* bits 2-20 */ +# define BHISF_beshiscal_SHIFT 2 + +# define BHSE_beshsrcend_MASK 0xfc000003 /* bits 2-25 */ +# define BHSE_beshsrcend_SHIFT 2 + +# define BHSL_beshsrclst_MASK 0xfc00ffff /* bits 16-25 */ +# define BHSL_beshsrclst_SHIFT 16 + +# define BHSS_beshsrcst_MASK 0xfc000003 /* bits 2-25 */ +# define BHSS_beshsrcst_SHIFT 2 + +# define BP_bespitch_MASK 0xfffff000 /* bits 0-11 */ +# define BP_bespitch_SHIFT 0 + +# define BS_besstat_MASK 0xfffffffc /* bits 0-1 */ +# define BS_besstat_a1 0x0 /* val 0, shift 0 */ +# define BS_besstat_a2 0x1 /* val 1, shift 0 */ +# define BS_besstat_b1 0x2 /* val 2, shift 0 */ +# define BS_besstat_b2 0x3 /* val 3, shift 0 */ + +# define BSF_besv1srclast_MASK 0xfffffc00 /* bits 0-9 */ +# define BSF_besv1srclast_SHIFT 0 + +# define BSF_besv2srclst_MASK 0xfffffc00 /* bits 0-9 */ +# define BSF_besv2srclst_SHIFT 0 + +# define BSF_besv1wght_MASK 0xffff0003 /* bits 2-15 */ +# define BSF_besv1wght_SHIFT 2 +# define BSF_besv1wghts_MASK 0xfffeffff /* bit 16 */ +# define BSF_besv1wghts_disable 0x0 +# define BSF_besv1wghts_enable 0x10000 + +# define BSF_besv2wght_MASK 0xffff0003 /* bits 2-15 */ +# define BSF_besv2wght_SHIFT 2 +# define BSF_besv2wghts_MASK 0xfffeffff /* bit 16 */ +# define BSF_besv2wghts_disable 0x0 +# define BSF_besv2wghts_enable 0x10000 + +# define BVC_besbot_MASK 0xfffff800 /* bits 0-10 */ +# define BVC_besbot_SHIFT 0 +# define BVC_bestop_MASK 0xf800ffff /* bits 16-26 */ +# define BVC_bestop_SHIFT 16 + +# define BVISF_besviscal_MASK 0xffe00003 /* bits 2-20 */ +# define BVISF_besviscal_SHIFT 2 + +# define CXB_cxleft_MASK 0xfffff000 /* bits 0-11 */ +# define CXB_cxleft_SHIFT 0 +# define CXB_cxright_MASK 0xf000ffff /* bits 16-27 */ +# define CXB_cxright_SHIFT 16 + +# define DO_dstmap_MASK 0xfffffffe /* bit 0 */ +# define DO_dstmap_fb 0x0 +# define DO_dstmap_sys 0x1 +# define DO_dstacc_MASK 0xfffffffd /* bit 1 */ +# define DO_dstacc_pci 0x0 +# define DO_dstacc_agp 0x2 +# define DO_dstorg_MASK 0x7 /* bits 3-31 */ +# define DO_dstorg_SHIFT 3 + +# define DC_opcod_MASK 0xfffffff0 /* bits 0-3 */ +# define DC_opcod_line_open 0x0 /* val 0, shift 0 */ +# define DC_opcod_autoline_open 0x1 /* val 1, shift 0 */ +# define DC_opcod_line_close 0x2 /* val 2, shift 0 */ +# define DC_opcod_autoline_close 0x3 /* val 3, shift 0 */ +# define DC_opcod_trap 0x4 /* val 4, shift 0 */ +# define DC_opcod_texture_trap 0x6 /* val 6, shift 0 */ +# define DC_opcod_bitblt 0x8 /* val 8, shift 0 */ +# define DC_opcod_iload 0x9 /* val 9, shift 0 */ +# define DC_atype_MASK 0xffffff8f /* bits 4-6 */ +# define DC_atype_rpl 0x0 /* val 0, shift 4 */ +# define DC_atype_rstr 0x10 /* val 1, shift 4 */ +# define DC_atype_zi 0x30 /* val 3, shift 4 */ +# define DC_atype_blk 0x40 /* val 4, shift 4 */ +# define DC_atype_i 0x70 /* val 7, shift 4 */ +# define DC_linear_MASK 0xffffff7f /* bit 7 */ +# define DC_linear_xy 0x0 +# define DC_linear_linear 0x80 +# define DC_zmode_MASK 0xfffff8ff /* bits 8-10 */ +# define DC_zmode_nozcmp 0x0 /* val 0, shift 8 */ +# define DC_zmode_ze 0x200 /* val 2, shift 8 */ +# define DC_zmode_zne 0x300 /* val 3, shift 8 */ +# define DC_zmode_zlt 0x400 /* val 4, shift 8 */ +# define DC_zmode_zlte 0x500 /* val 5, shift 8 */ +# define DC_zmode_zgt 0x600 /* val 6, shift 8 */ +# define DC_zmode_zgte 0x700 /* val 7, shift 8 */ +# define DC_solid_MASK 0xfffff7ff /* bit 11 */ +# define DC_solid_disable 0x0 +# define DC_solid_enable 0x800 +# define DC_arzero_MASK 0xffffefff /* bit 12 */ +# define DC_arzero_disable 0x0 +# define DC_arzero_enable 0x1000 +# define DC_sgnzero_MASK 0xffffdfff /* bit 13 */ +# define DC_sgnzero_disable 0x0 +# define DC_sgnzero_enable 0x2000 +# define DC_shftzero_MASK 0xffffbfff /* bit 14 */ +# define DC_shftzero_disable 0x0 +# define DC_shftzero_enable 0x4000 +# define DC_bop_MASK 0xfff0ffff /* bits 16-19 */ +# define DC_bop_SHIFT 16 +# define DC_trans_MASK 0xff0fffff /* bits 20-23 */ +# define DC_trans_SHIFT 20 +# define DC_bltmod_MASK 0xe1ffffff /* bits 25-28 */ +# define DC_bltmod_bmonolef 0x0 /* val 0, shift 25 */ +# define DC_bltmod_bmonowf 0x8000000 /* val 4, shift 25 */ +# define DC_bltmod_bplan 0x2000000 /* val 1, shift 25 */ +# define DC_bltmod_bfcol 0x4000000 /* val 2, shift 25 */ +# define DC_bltmod_bu32bgr 0x6000000 /* val 3, shift 25 */ +# define DC_bltmod_bu32rgb 0xe000000 /* val 7, shift 25 */ +# define DC_bltmod_bu24bgr 0x16000000 /* val 11, shift 25 */ +# define DC_bltmod_bu24rgb 0x1e000000 /* val 15, shift 25 */ +# define DC_pattern_MASK 0xdfffffff /* bit 29 */ +# define DC_pattern_disable 0x0 +# define DC_pattern_enable 0x20000000 +# define DC_transc_MASK 0xbfffffff /* bit 30 */ +# define DC_transc_disable 0x0 +# define DC_transc_enable 0x40000000 +# define DC_clipdis_MASK 0x7fffffff /* bit 31 */ +# define DC_clipdis_disable 0x0 +# define DC_clipdis_enable 0x80000000 + +# define DS_dwgsyncaddr_MASK 0x3 /* bits 2-31 */ +# define DS_dwgsyncaddr_SHIFT 2 + +# define FS_fifocount_MASK 0xffffff80 /* bits 0-6 */ +# define FS_fifocount_SHIFT 0 +# define FS_bfull_MASK 0xfffffeff /* bit 8 */ +# define FS_bfull_disable 0x0 +# define FS_bfull_enable 0x100 +# define FS_bempty_MASK 0xfffffdff /* bit 9 */ +# define FS_bempty_disable 0x0 +# define FS_bempty_enable 0x200 + +# define XA_fxleft_MASK 0xffff0000 /* bits 0-15 */ +# define XA_fxleft_SHIFT 0 +# define XA_fxright_MASK 0xffff /* bits 16-31 */ +# define XA_fxright_SHIFT 16 + +# define IC_softrapiclr_MASK 0xfffffffe /* bit 0 */ +# define IC_softrapiclr_disable 0x0 +# define IC_softrapiclr_enable 0x1 +# define IC_pickiclr_MASK 0xfffffffb /* bit 2 */ +# define IC_pickiclr_disable 0x0 +# define IC_pickiclr_enable 0x4 +# define IC_vlineiclr_MASK 0xffffffdf /* bit 5 */ +# define IC_vlineiclr_disable 0x0 +# define IC_vlineiclr_enable 0x20 +# define IC_wiclr_MASK 0xffffff7f /* bit 7 */ +# define IC_wiclr_disable 0x0 +# define IC_wiclr_enable 0x80 +# define IC_wciclr_MASK 0xfffffeff /* bit 8 */ +# define IC_wciclr_disable 0x0 +# define IC_wciclr_enable 0x100 + +# define IE_softrapien_MASK 0xfffffffe /* bit 0 */ +# define IE_softrapien_disable 0x0 +# define IE_softrapien_enable 0x1 +# define IE_pickien_MASK 0xfffffffb /* bit 2 */ +# define IE_pickien_disable 0x0 +# define IE_pickien_enable 0x4 +# define IE_vlineien_MASK 0xffffffdf /* bit 5 */ +# define IE_vlineien_disable 0x0 +# define IE_vlineien_enable 0x20 +# define IE_extien_MASK 0xffffffbf /* bit 6 */ +# define IE_extien_disable 0x0 +# define IE_extien_enable 0x40 +# define IE_wien_MASK 0xffffff7f /* bit 7 */ +# define IE_wien_disable 0x0 +# define IE_wien_enable 0x80 +# define IE_wcien_MASK 0xfffffeff /* bit 8 */ +# define IE_wcien_disable 0x0 +# define IE_wcien_enable 0x100 + +# define MA_pwidth_MASK 0xfffffffc /* bits 0-1 */ +# define MA_pwidth_8 0x0 /* val 0, shift 0 */ +# define MA_pwidth_16 0x1 /* val 1, shift 0 */ +# define MA_pwidth_32 0x2 /* val 2, shift 0 */ +# define MA_pwidth_24 0x3 /* val 3, shift 0 */ +# define MA_zwidth_MASK 0xffffffe7 /* bits 3-4 */ +# define MA_zwidth_16 0x0 /* val 0, shift 3 */ +# define MA_zwidth_32 0x8 /* val 1, shift 3 */ +# define MA_zwidth_15 0x10 /* val 2, shift 3 */ +# define MA_zwidth_24 0x18 /* val 3, shift 3 */ +# define MA_memreset_MASK 0xffff7fff /* bit 15 */ +# define MA_memreset_disable 0x0 +# define MA_memreset_enable 0x8000 +# define MA_fogen_MASK 0xfbffffff /* bit 26 */ +# define MA_fogen_disable 0x0 +# define MA_fogen_enable 0x4000000 +# define MA_tlutload_MASK 0xdfffffff /* bit 29 */ +# define MA_tlutload_disable 0x0 +# define MA_tlutload_enable 0x20000000 +# define MA_nodither_MASK 0xbfffffff /* bit 30 */ +# define MA_nodither_disable 0x0 +# define MA_nodither_enable 0x40000000 +# define MA_dit555_MASK 0x7fffffff /* bit 31 */ +# define MA_dit555_disable 0x0 +# define MA_dit555_enable 0x80000000 + +# define MCWS_casltncy_MASK 0xfffffff8 /* bits 0-2 */ +# define MCWS_casltncy_SHIFT 0 +# define MCWS_rrddelay_MASK 0xffffffcf /* bits 4-5 */ +# define MCWS_rcddelay_MASK 0xfffffe7f /* bits 7-8 */ +# define MCWS_rasmin_MASK 0xffffe3ff /* bits 10-12 */ +# define MCWS_rasmin_SHIFT 10 +# define MCWS_rpdelay_MASK 0xffff3fff /* bits 14-15 */ +# define MCWS_wrdelay_MASK 0xfff3ffff /* bits 18-19 */ +# define MCWS_rddelay_MASK 0xffdfffff /* bit 21 */ +# define MCWS_rddelay_disable 0x0 +# define MCWS_rddelay_enable 0x200000 +# define MCWS_smrdelay_MASK 0xfe7fffff /* bits 23-24 */ +# define MCWS_bwcdelay_MASK 0xf3ffffff /* bits 26-27 */ +# define MCWS_bpldelay_MASK 0x1fffffff /* bits 29-31 */ +# define MCWS_bpldelay_SHIFT 29 + +# define MRB_mclkbrd0_MASK 0xfffffff0 /* bits 0-3 */ +# define MRB_mclkbrd0_SHIFT 0 +# define MRB_mclkbrd1_MASK 0xfffffe1f /* bits 5-8 */ +# define MRB_mclkbrd1_SHIFT 5 +# define MRB_strmfctl_MASK 0xff3fffff /* bits 22-23 */ +# define MRB_mrsopcod_MASK 0xe1ffffff /* bits 25-28 */ +# define MRB_mrsopcod_SHIFT 25 + +# define OM_dmamod_MASK 0xfffffff3 /* bits 2-3 */ +# define OM_dmamod_general 0x0 /* val 0, shift 2 */ +# define OM_dmamod_blit 0x4 /* val 1, shift 2 */ +# define OM_dmamod_vector 0x8 /* val 2, shift 2 */ +# define OM_dmamod_vertex 0xc /* val 3, shift 2 */ +# define OM_dmadatasiz_MASK 0xfffffcff /* bits 8-9 */ +# define OM_dmadatasiz_8 0x0 /* val 0, shift 8 */ +# define OM_dmadatasiz_16 0x100 /* val 1, shift 8 */ +# define OM_dmadatasiz_32 0x200 /* val 2, shift 8 */ +# define OM_dirdatasiz_MASK 0xfffcffff /* bits 16-17 */ +# define OM_dirdatasiz_8 0x0 /* val 0, shift 16 */ +# define OM_dirdatasiz_16 0x10000 /* val 1, shift 16 */ +# define OM_dirdatasiz_32 0x20000 /* val 2, shift 16 */ + +# define P_iy_MASK 0xffffe000 /* bits 0-12 */ +# define P_iy_SHIFT 0 +# define P_ylin_MASK 0xffff7fff /* bit 15 */ +# define P_ylin_disable 0x0 +# define P_ylin_enable 0x8000 + +# define PDCA_primod_MASK 0xfffffffc /* bits 0-1 */ +# define PDCA_primod_general 0x0 /* val 0, shift 0 */ +# define PDCA_primod_blit 0x1 /* val 1, shift 0 */ +# define PDCA_primod_vector 0x2 /* val 2, shift 0 */ +# define PDCA_primod_vertex 0x3 /* val 3, shift 0 */ +# define PDCA_primaddress_MASK 0x3 /* bits 2-31 */ +# define PDCA_primaddress_SHIFT 2 + +# define PDEA_primnostart_MASK 0xfffffffe /* bit 0 */ +# define PDEA_primnostart_disable 0x0 +# define PDEA_primnostart_enable 0x1 +# define PDEA_pagpxfer_MASK 0xfffffffd /* bit 1 */ +# define PDEA_pagpxfer_disable 0x0 +# define PDEA_pagpxfer_enable 0x2 +# define PDEA_primend_MASK 0x3 /* bits 2-31 */ +# define PDEA_primend_SHIFT 2 + +# define PLS_primptren0_MASK 0xfffffffe /* bit 0 */ +# define PLS_primptren0_disable 0x0 +# define PLS_primptren0_enable 0x1 +# define PLS_primptren1_MASK 0xfffffffd /* bit 1 */ +# define PLS_primptren1_disable 0x0 +# define PLS_primptren1_enable 0x2 +# define PLS_primptr_MASK 0x7 /* bits 3-31 */ +# define PLS_primptr_SHIFT 3 + +# define R_softreset_MASK 0xfffffffe /* bit 0 */ +# define R_softreset_disable 0x0 +# define R_softreset_enable 0x1 +# define R_softextrst_MASK 0xfffffffd /* bit 1 */ +# define R_softextrst_disable 0x0 +# define R_softextrst_enable 0x2 + +# define SDCA_secmod_MASK 0xfffffffc /* bits 0-1 */ +# define SDCA_secmod_general 0x0 /* val 0, shift 0 */ +# define SDCA_secmod_blit 0x1 /* val 1, shift 0 */ +# define SDCA_secmod_vector 0x2 /* val 2, shift 0 */ +# define SDCA_secmod_vertex 0x3 /* val 3, shift 0 */ +# define SDCA_secaddress_MASK 0x3 /* bits 2-31 */ +# define SDCA_secaddress_SHIFT 2 + +# define SDEA_sagpxfer_MASK 0xfffffffd /* bit 1 */ +# define SDEA_sagpxfer_disable 0x0 +# define SDEA_sagpxfer_enable 0x2 +# define SDEA_secend_MASK 0x3 /* bits 2-31 */ +# define SDEA_secend_SHIFT 2 + +# define SETDCA_setupmod_MASK 0xfffffffc /* bits 0-1 */ +# define SETDCA_setupmod_vertlist 0x0 /* val 0, shift 0 */ +# define SETDCA_setupaddress_MASK 0x3 /* bits 2-31 */ +# define SETDCA_setupaddress_SHIFT 2 + +# define SETDEA_setupagpxfer_MASK 0xfffffffd /* bit 1 */ +# define SETDEA_setupagpxfer_disable 0x0 +# define SETDEA_setupagpxfer_enable 0x2 +# define SETDEA_setupend_MASK 0x3 /* bits 2-31 */ +# define SETDEA_setupend_SHIFT 2 + +# define S_sdydxl_MASK 0xfffffffe /* bit 0 */ +# define S_sdydxl_y 0x0 +# define S_sdydxl_x 0x1 +# define S_scanleft_MASK 0xfffffffe /* bit 0 */ +# define S_scanleft_disable 0x0 +# define S_scanleft_enable 0x1 +# define S_sdxl_MASK 0xfffffffd /* bit 1 */ +# define S_sdxl_pos 0x0 +# define S_sdxl_neg 0x2 +# define S_sdy_MASK 0xfffffffb /* bit 2 */ +# define S_sdy_pos 0x0 +# define S_sdy_neg 0x4 +# define S_sdxr_MASK 0xffffffdf /* bit 5 */ +# define S_sdxr_pos 0x0 +# define S_sdxr_neg 0x20 +# define S_brkleft_MASK 0xfffffeff /* bit 8 */ +# define S_brkleft_disable 0x0 +# define S_brkleft_enable 0x100 +# define S_errorinit_MASK 0x7fffffff /* bit 31 */ +# define S_errorinit_disable 0x0 +# define S_errorinit_enable 0x80000000 + +# define FSC_x_off_MASK 0xfffffff0 /* bits 0-3 */ +# define FSC_x_off_SHIFT 0 +# define FSC_funcnt_MASK 0xffffff80 /* bits 0-6 */ +# define FSC_funcnt_SHIFT 0 +# define FSC_y_off_MASK 0xffffff8f /* bits 4-6 */ +# define FSC_y_off_SHIFT 4 +# define FSC_funoff_MASK 0xffc0ffff /* bits 16-21 */ +# define FSC_funoff_SHIFT 16 +# define FSC_stylelen_MASK 0xffc0ffff /* bits 16-21 */ +# define FSC_stylelen_SHIFT 16 + + +# define STH_softraphand_MASK 0x3 /* bits 2-31 */ +# define STH_softraphand_SHIFT 2 + +# define SO_srcmap_MASK 0xfffffffe /* bit 0 */ +# define SO_srcmap_fb 0x0 +# define SO_srcmap_sys 0x1 +# define SO_srcacc_MASK 0xfffffffd /* bit 1 */ +# define SO_srcacc_pci 0x0 +# define SO_srcacc_agp 0x2 +# define SO_srcorg_MASK 0x7 /* bits 3-31 */ +# define SO_srcorg_SHIFT 3 + +# define STAT_softrapen_MASK 0xfffffffe /* bit 0 */ +# define STAT_softrapen_disable 0x0 +# define STAT_softrapen_enable 0x1 +# define STAT_pickpen_MASK 0xfffffffb /* bit 2 */ +# define STAT_pickpen_disable 0x0 +# define STAT_pickpen_enable 0x4 +# define STAT_vsyncsts_MASK 0xfffffff7 /* bit 3 */ +# define STAT_vsyncsts_disable 0x0 +# define STAT_vsyncsts_enable 0x8 +# define STAT_vsyncpen_MASK 0xffffffef /* bit 4 */ +# define STAT_vsyncpen_disable 0x0 +# define STAT_vsyncpen_enable 0x10 +# define STAT_vlinepen_MASK 0xffffffdf /* bit 5 */ +# define STAT_vlinepen_disable 0x0 +# define STAT_vlinepen_enable 0x20 +# define STAT_extpen_MASK 0xffffffbf /* bit 6 */ +# define STAT_extpen_disable 0x0 +# define STAT_extpen_enable 0x40 +# define STAT_wpen_MASK 0xffffff7f /* bit 7 */ +# define STAT_wpen_disable 0x0 +# define STAT_wpen_enable 0x80 +# define STAT_wcpen_MASK 0xfffffeff /* bit 8 */ +# define STAT_wcpen_disable 0x0 +# define STAT_wcpen_enable 0x100 +# define STAT_dwgengsts_MASK 0xfffeffff /* bit 16 */ +# define STAT_dwgengsts_disable 0x0 +# define STAT_dwgengsts_enable 0x10000 +# define STAT_endprdmasts_MASK 0xfffdffff /* bit 17 */ +# define STAT_endprdmasts_disable 0x0 +# define STAT_endprdmasts_enable 0x20000 +# define STAT_wbusy_MASK 0xfffbffff /* bit 18 */ +# define STAT_wbusy_disable 0x0 +# define STAT_wbusy_enable 0x40000 +# define STAT_swflag_MASK 0xfffffff /* bits 28-31 */ +# define STAT_swflag_SHIFT 28 + +# define S_sref_MASK 0xffffff00 /* bits 0-7 */ +# define S_sref_SHIFT 0 +# define S_smsk_MASK 0xffff00ff /* bits 8-15 */ +# define S_smsk_SHIFT 8 +# define S_swtmsk_MASK 0xff00ffff /* bits 16-23 */ +# define S_swtmsk_SHIFT 16 + +# define SC_smode_MASK 0xfffffff8 /* bits 0-2 */ +# define SC_smode_salways 0x0 /* val 0, shift 0 */ +# define SC_smode_snever 0x1 /* val 1, shift 0 */ +# define SC_smode_se 0x2 /* val 2, shift 0 */ +# define SC_smode_sne 0x3 /* val 3, shift 0 */ +# define SC_smode_slt 0x4 /* val 4, shift 0 */ +# define SC_smode_slte 0x5 /* val 5, shift 0 */ +# define SC_smode_sgt 0x6 /* val 6, shift 0 */ +# define SC_smode_sgte 0x7 /* val 7, shift 0 */ +# define SC_sfailop_MASK 0xffffffc7 /* bits 3-5 */ +# define SC_sfailop_keep 0x0 /* val 0, shift 3 */ +# define SC_sfailop_zero 0x8 /* val 1, shift 3 */ +# define SC_sfailop_replace 0x10 /* val 2, shift 3 */ +# define SC_sfailop_incrsat 0x18 /* val 3, shift 3 */ +# define SC_sfailop_decrsat 0x20 /* val 4, shift 3 */ +# define SC_sfailop_invert 0x28 /* val 5, shift 3 */ +# define SC_sfailop_incr 0x30 /* val 6, shift 3 */ +# define SC_sfailop_decr 0x38 /* val 7, shift 3 */ +# define SC_szfailop_MASK 0xfffffe3f /* bits 6-8 */ +# define SC_szfailop_keep 0x0 /* val 0, shift 6 */ +# define SC_szfailop_zero 0x40 /* val 1, shift 6 */ +# define SC_szfailop_replace 0x80 /* val 2, shift 6 */ +# define SC_szfailop_incrsat 0xc0 /* val 3, shift 6 */ +# define SC_szfailop_decrsat 0x100 /* val 4, shift 6 */ +# define SC_szfailop_invert 0x140 /* val 5, shift 6 */ +# define SC_szfailop_incr 0x180 /* val 6, shift 6 */ +# define SC_szfailop_decr 0x1c0 /* val 7, shift 6 */ +# define SC_szpassop_MASK 0xfffff1ff /* bits 9-11 */ +# define SC_szpassop_keep 0x0 /* val 0, shift 9 */ +# define SC_szpassop_zero 0x200 /* val 1, shift 9 */ +# define SC_szpassop_replace 0x400 /* val 2, shift 9 */ +# define SC_szpassop_incrsat 0x600 /* val 3, shift 9 */ +# define SC_szpassop_decrsat 0x800 /* val 4, shift 9 */ +# define SC_szpassop_invert 0xa00 /* val 5, shift 9 */ +# define SC_szpassop_incr 0xc00 /* val 6, shift 9 */ +# define SC_szpassop_decr 0xe00 /* val 7, shift 9 */ + +# define TD1_color1arg2selMASK 0xfffffffc /* bits 0-1 */ +# define TD1_color1alphaselMASK 0xffffffe3 /* bits 2-4 */ +# define TD1_color1alphaselSHIFT 2 +# define TD1_color1arg1alphaMASK 0xffffffdf /* bit 5 */ +# define TD1_color1arg1alphadisable 0x0 +# define TD1_color1arg1alphaenable 0x20 +# define TD1_color1arg1invMASK 0xffffffbf /* bit 6 */ +# define TD1_color1arg1invdisable 0x0 +# define TD1_color1arg1invenable 0x40 +# define TD1_color1arg2alphaMASK 0xffffff7f /* bit 7 */ +# define TD1_color1arg2alphadisable 0x0 +# define TD1_color1arg2alphaenable 0x80 +# define TD1_color1arg2invMASK 0xfffffeff /* bit 8 */ +# define TD1_color1arg2invdisable 0x0 +# define TD1_color1arg2invenable 0x100 +# define TD1_color1alpha1invMASK 0xfffffdff /* bit 9 */ +# define TD1_color1alpha1invdisable 0x0 +# define TD1_color1alpha1invenable 0x200 +# define TD1_color1alpha2invMASK 0xfffffbff /* bit 10 */ +# define TD1_color1alpha2invdisable 0x0 +# define TD1_color1alpha2invenable 0x400 +# define TD1_color1selMASK 0xff9fffff /* bits 21-22 */ +# define TD1_color1selarg1 0x0 /* val 0, shift 21 */ +# define TD1_color1selarg2 0x200000 /* val 1, shift 21 */ +# define TD1_color1seladd 0x400000 /* val 2, shift 21 */ +# define TD1_color1selmul 0x600000 /* val 3, shift 21 */ +# define TD1_alpha1selMASK 0x3fffffff /* bits 30-31 */ +# define TD1_alpha1selarg1 0x0 /* val 0, shift 30 */ +# define TD1_alpha1selarg2 0x40000000 /* val 1, shift 30 */ +# define TD1_alpha1seladd 0x80000000 /* val 2, shift 30 */ +# define TD1_alpha1selmul 0xc0000000 /* val 3, shift 30 */ + +# define TST_ramtsten_MASK 0xfffffffe /* bit 0 */ +# define TST_ramtsten_disable 0x0 +# define TST_ramtsten_enable 0x1 +# define TST_ramtstdone_MASK 0xfffffffd /* bit 1 */ +# define TST_ramtstdone_disable 0x0 +# define TST_ramtstdone_enable 0x2 +# define TST_wramtstpass_MASK 0xfffffffb /* bit 2 */ +# define TST_wramtstpass_disable 0x0 +# define TST_wramtstpass_enable 0x4 +# define TST_tcachetstpass_MASK 0xfffffff7 /* bit 3 */ +# define TST_tcachetstpass_disable 0x0 +# define TST_tcachetstpass_enable 0x8 +# define TST_tluttstpass_MASK 0xffffffef /* bit 4 */ +# define TST_tluttstpass_disable 0x0 +# define TST_tluttstpass_enable 0x10 +# define TST_luttstpass_MASK 0xffffffdf /* bit 5 */ +# define TST_luttstpass_disable 0x0 +# define TST_luttstpass_enable 0x20 +# define TST_besramtstpass_MASK 0xffffffbf /* bit 6 */ +# define TST_besramtstpass_disable 0x0 +# define TST_besramtstpass_enable 0x40 +# define TST_ringen_MASK 0xfffffeff /* bit 8 */ +# define TST_ringen_disable 0x0 +# define TST_ringen_enable 0x100 +# define TST_apllbyp_MASK 0xfffffdff /* bit 9 */ +# define TST_apllbyp_disable 0x0 +# define TST_apllbyp_enable 0x200 +# define TST_hiten_MASK 0xfffffbff /* bit 10 */ +# define TST_hiten_disable 0x0 +# define TST_hiten_enable 0x400 +# define TST_tmode_MASK 0xffffc7ff /* bits 11-13 */ +# define TST_tmode_SHIFT 11 +# define TST_tclksel_MASK 0xfffe3fff /* bits 14-16 */ +# define TST_tclksel_SHIFT 14 +# define TST_ringcnten_MASK 0xfffdffff /* bit 17 */ +# define TST_ringcnten_disable 0x0 +# define TST_ringcnten_enable 0x20000 +# define TST_ringcnt_MASK 0xc003ffff /* bits 18-29 */ +# define TST_ringcnt_SHIFT 18 +# define TST_ringcntclksl_MASK 0xbfffffff /* bit 30 */ +# define TST_ringcntclksl_disable 0x0 +# define TST_ringcntclksl_enable 0x40000000 +# define TST_biosboot_MASK 0x7fffffff /* bit 31 */ +# define TST_biosboot_disable 0x0 +# define TST_biosboot_enable 0x80000000 + +# define TMC_tformat_MASK 0xfffffff0 /* bits 0-3 */ +# define TMC_tformat_tw4 0x0 /* val 0, shift 0 */ +# define TMC_tformat_tw8 0x1 /* val 1, shift 0 */ +# define TMC_tformat_tw15 0x2 /* val 2, shift 0 */ +# define TMC_tformat_tw16 0x3 /* val 3, shift 0 */ +# define TMC_tformat_tw12 0x4 /* val 4, shift 0 */ +# define TMC_tformat_tw32 0x6 /* val 6, shift 0 */ +# define TMC_tformat_tw422 0xa /* val 10, shift 0 */ +# define TMC_tpitchlin_MASK 0xfffffeff /* bit 8 */ +# define TMC_tpitchlin_disable 0x0 +# define TMC_tpitchlin_enable 0x100 +# define TMC_tpitchext_MASK 0xfff001ff /* bits 9-19 */ +# define TMC_tpitchext_SHIFT 9 +# define TMC_tpitch_MASK 0xfff8ffff /* bits 16-18 */ +# define TMC_tpitch_SHIFT 16 +# define TMC_owalpha_MASK 0xffbfffff /* bit 22 */ +# define TMC_owalpha_disable 0x0 +# define TMC_owalpha_enable 0x400000 +# define TMC_azeroextend_MASK 0xff7fffff /* bit 23 */ +# define TMC_azeroextend_disable 0x0 +# define TMC_azeroextend_enable 0x800000 +# define TMC_decalckey_MASK 0xfeffffff /* bit 24 */ +# define TMC_decalckey_disable 0x0 +# define TMC_decalckey_enable 0x1000000 +# define TMC_takey_MASK 0xfdffffff /* bit 25 */ +# define TMC_takey_0 0x0 +# define TMC_takey_1 0x2000000 +# define TMC_tamask_MASK 0xfbffffff /* bit 26 */ +# define TMC_tamask_0 0x0 +# define TMC_tamask_1 0x4000000 +# define TMC_clampv_MASK 0xf7ffffff /* bit 27 */ +# define TMC_clampv_disable 0x0 +# define TMC_clampv_enable 0x8000000 +# define TMC_clampu_MASK 0xefffffff /* bit 28 */ +# define TMC_clampu_disable 0x0 +# define TMC_clampu_enable 0x10000000 +# define TMC_tmodulate_MASK 0xdfffffff /* bit 29 */ +# define TMC_tmodulate_disable 0x0 +# define TMC_tmodulate_enable 0x20000000 +# define TMC_strans_MASK 0xbfffffff /* bit 30 */ +# define TMC_strans_disable 0x0 +# define TMC_strans_enable 0x40000000 +# define TMC_itrans_MASK 0x7fffffff /* bit 31 */ +# define TMC_itrans_disable 0x0 +# define TMC_itrans_enable 0x80000000 + +# define TMC_decalblend_MASK 0xfffffffe /* bit 0 */ +# define TMC_decalblend_disable 0x0 +# define TMC_decalblend_enable 0x1 +# define TMC_idecal_MASK 0xfffffffd /* bit 1 */ +# define TMC_idecal_disable 0x0 +# define TMC_idecal_enable 0x2 +# define TMC_decaldis_MASK 0xfffffffb /* bit 2 */ +# define TMC_decaldis_disable 0x0 +# define TMC_decaldis_enable 0x4 +# define TMC_ckstransdis_MASK 0xffffffef /* bit 4 */ +# define TMC_ckstransdis_disable 0x0 +# define TMC_ckstransdis_enable 0x10 +# define TMC_borderen_MASK 0xffffffdf /* bit 5 */ +# define TMC_borderen_disable 0x0 +# define TMC_borderen_enable 0x20 +# define TMC_specen_MASK 0xffffffbf /* bit 6 */ +# define TMC_specen_disable 0x0 +# define TMC_specen_enable 0x40 + +# define TF_minfilter_MASK 0xfffffff0 /* bits 0-3 */ +# define TF_minfilter_nrst 0x0 /* val 0, shift 0 */ +# define TF_minfilter_bilin 0x2 /* val 2, shift 0 */ +# define TF_minfilter_cnst 0x3 /* val 3, shift 0 */ +# define TF_minfilter_mm1s 0x8 /* val 8, shift 0 */ +# define TF_minfilter_mm2s 0x9 /* val 9, shift 0 */ +# define TF_minfilter_mm4s 0xa /* val 10, shift 0 */ +# define TF_minfilter_mm8s 0xc /* val 12, shift 0 */ +# define TF_magfilter_MASK 0xffffff0f /* bits 4-7 */ +# define TF_magfilter_nrst 0x0 /* val 0, shift 4 */ +# define TF_magfilter_bilin 0x20 /* val 2, shift 4 */ +# define TF_magfilter_cnst 0x30 /* val 3, shift 4 */ +# define TF_avgstride_MASK 0xfff7ffff /* bit 19 */ +# define TF_avgstride_disable 0x0 +# define TF_avgstride_enable 0x80000 +# define TF_filteralpha_MASK 0xffefffff /* bit 20 */ +# define TF_filteralpha_disable 0x0 +# define TF_filteralpha_enable 0x100000 +# define TF_fthres_MASK 0xe01fffff /* bits 21-28 */ +# define TF_fthres_SHIFT 21 +# define TF_mapnb_MASK 0x1fffffff /* bits 29-31 */ +# define TF_mapnb_SHIFT 29 + +# define TH_th_MASK 0xffffffc0 /* bits 0-5 */ +# define TH_th_SHIFT 0 +# define TH_rfh_MASK 0xffff81ff /* bits 9-14 */ +# define TH_rfh_SHIFT 9 +# define TH_thmask_MASK 0xe003ffff /* bits 18-28 */ +# define TH_thmask_SHIFT 18 + +# define TO_texorgmap_MASK 0xfffffffe /* bit 0 */ +# define TO_texorgmap_fb 0x0 +# define TO_texorgmap_sys 0x1 +# define TO_texorgacc_MASK 0xfffffffd /* bit 1 */ +# define TO_texorgacc_pci 0x0 +# define TO_texorgacc_agp 0x2 +# define TO_texorg_MASK 0x1f /* bits 5-31 */ +# define TO_texorg_SHIFT 5 + +# define TT_tckey_MASK 0xffff0000 /* bits 0-15 */ +# define TT_tckey_SHIFT 0 +# define TT_tkmask_MASK 0xffff /* bits 16-31 */ +# define TT_tkmask_SHIFT 16 + +# define TT_tckeyh_MASK 0xffff0000 /* bits 0-15 */ +# define TT_tckeyh_SHIFT 0 +# define TT_tkmaskh_MASK 0xffff /* bits 16-31 */ +# define TT_tkmaskh_SHIFT 16 + +# define TW_tw_MASK 0xffffffc0 /* bits 0-5 */ +# define TW_tw_SHIFT 0 +# define TW_rfw_MASK 0xffff81ff /* bits 9-14 */ +# define TW_rfw_SHIFT 9 +# define TW_twmask_MASK 0xe003ffff /* bits 18-28 */ +# define TW_twmask_SHIFT 18 + +# define WAS_seqdst0_MASK 0xffffffc0 /* bits 0-5 */ +# define WAS_seqdst0_SHIFT 0 +# define WAS_seqdst1_MASK 0xfffff03f /* bits 6-11 */ +# define WAS_seqdst1_SHIFT 6 +# define WAS_seqdst2_MASK 0xfffc0fff /* bits 12-17 */ +# define WAS_seqdst2_SHIFT 12 +# define WAS_seqdst3_MASK 0xff03ffff /* bits 18-23 */ +# define WAS_seqdst3_SHIFT 18 +# define WAS_seqlen_MASK 0xfcffffff /* bits 24-25 */ +# define WAS_wfirsttag_MASK 0xfbffffff /* bit 26 */ +# define WAS_wfirsttag_disable 0x0 +# define WAS_wfirsttag_enable 0x4000000 +# define WAS_wsametag_MASK 0xf7ffffff /* bit 27 */ +# define WAS_wsametag_disable 0x0 +# define WAS_wsametag_enable 0x8000000 +# define WAS_seqoff_MASK 0xefffffff /* bit 28 */ +# define WAS_seqoff_disable 0x0 +# define WAS_seqoff_enable 0x10000000 + +# define WMA_wcodeaddr_MASK 0xff /* bits 8-31 */ +# define WMA_wcodeaddr_SHIFT 8 + +# define WF_walustsflag_MASK 0xffffff00 /* bits 0-7 */ +# define WF_walustsflag_SHIFT 0 +# define WF_walucfgflag_MASK 0xffff00ff /* bits 8-15 */ +# define WF_walucfgflag_SHIFT 8 +# define WF_wprgflag_MASK 0xffff /* bits 16-31 */ +# define WF_wprgflag_SHIFT 16 + +# define WF1_walustsflag1_MASK 0xffffff00 /* bits 0-7 */ +# define WF1_walustsflag1_SHIFT 0 +# define WF1_walucfgflag1_MASK 0xffff00ff /* bits 8-15 */ +# define WF1_walucfgflag1_SHIFT 8 +# define WF1_wprgflag1_MASK 0xffff /* bits 16-31 */ +# define WF1_wprgflag1_SHIFT 16 + +# define WGV_wgetmsbmin_MASK 0xffffffe0 /* bits 0-4 */ +# define WGV_wgetmsbmin_SHIFT 0 +# define WGV_wgetmsbmax_MASK 0xffffe0ff /* bits 8-12 */ +# define WGV_wgetmsbmax_SHIFT 8 +# define WGV_wbrklefttop_MASK 0xfffeffff /* bit 16 */ +# define WGV_wbrklefttop_disable 0x0 +# define WGV_wbrklefttop_enable 0x10000 +# define WGV_wfastcrop_MASK 0xfffdffff /* bit 17 */ +# define WGV_wfastcrop_disable 0x0 +# define WGV_wfastcrop_enable 0x20000 +# define WGV_wcentersnap_MASK 0xfffbffff /* bit 18 */ +# define WGV_wcentersnap_disable 0x0 +# define WGV_wcentersnap_enable 0x40000 +# define WGV_wbrkrighttop_MASK 0xfff7ffff /* bit 19 */ +# define WGV_wbrkrighttop_disable 0x0 +# define WGV_wbrkrighttop_enable 0x80000 + +# define WIA_wmode_MASK 0xfffffffc /* bits 0-1 */ +# define WIA_wmode_suspend 0x0 /* val 0, shift 0 */ +# define WIA_wmode_resume 0x1 /* val 1, shift 0 */ +# define WIA_wmode_jump 0x2 /* val 2, shift 0 */ +# define WIA_wmode_start 0x3 /* val 3, shift 0 */ +# define WIA_wagp_MASK 0xfffffffb /* bit 2 */ +# define WIA_wagp_pci 0x0 +# define WIA_wagp_agp 0x4 +# define WIA_wiaddr_MASK 0x7 /* bits 3-31 */ +# define WIA_wiaddr_SHIFT 3 + +# define WIA2_wmode_MASK 0xfffffffc /* bits 0-1 */ +# define WIA2_wmode_suspend 0x0 /* val 0, shift 0 */ +# define WIA2_wmode_resume 0x1 /* val 1, shift 0 */ +# define WIA2_wmode_jump 0x2 /* val 2, shift 0 */ +# define WIA2_wmode_start 0x3 /* val 3, shift 0 */ +# define WIA2_wagp_MASK 0xfffffffb /* bit 2 */ +# define WIA2_wagp_pci 0x0 +# define WIA2_wagp_agp 0x4 +# define WIA2_wiaddr_MASK 0x7 /* bits 3-31 */ +# define WIA2_wiaddr_SHIFT 3 + +# define WIMA_wimemaddr_MASK 0xffffff00 /* bits 0-7 */ +# define WIMA_wimemaddr_SHIFT 0 + +# define WM_wucodecache_MASK 0xfffffffe /* bit 0 */ +# define WM_wucodecache_disable 0x0 +# define WM_wucodecache_enable 0x1 +# define WM_wmaster_MASK 0xfffffffd /* bit 1 */ +# define WM_wmaster_disable 0x0 +# define WM_wmaster_enable 0x2 +# define WM_wcacheflush_MASK 0xfffffff7 /* bit 3 */ +# define WM_wcacheflush_disable 0x0 +# define WM_wcacheflush_enable 0x8 + +# define WVS_wvrtxsz_MASK 0xffffffc0 /* bits 0-5 */ +# define WVS_wvrtxsz_SHIFT 0 +# define WVS_primsz_MASK 0xffffc0ff /* bits 8-13 */ +# define WVS_primsz_SHIFT 8 + +# define XYEA_x_end_MASK 0xffff0000 /* bits 0-15 */ +# define XYEA_x_end_SHIFT 0 +# define XYEA_y_end_MASK 0xffff /* bits 16-31 */ +# define XYEA_y_end_SHIFT 16 + +# define XYSA_x_start_MASK 0xffff0000 /* bits 0-15 */ +# define XYSA_x_start_SHIFT 0 +# define XYSA_y_start_MASK 0xffff /* bits 16-31 */ +# define XYSA_y_start_SHIFT 16 + +# define YA_ydst_MASK 0xff800000 /* bits 0-22 */ +# define YA_ydst_SHIFT 0 +# define YA_sellin_MASK 0x1fffffff /* bits 29-31 */ +# define YA_sellin_SHIFT 29 + +# define YDL_length_MASK 0xffff0000 /* bits 0-15 */ +# define YDL_length_SHIFT 0 +# define YDL_yval_MASK 0xffff /* bits 16-31 */ +# define YDL_yval_SHIFT 16 + +# define ZO_zorgmap_MASK 0xfffffffe /* bit 0 */ +# define ZO_zorgmap_fb 0x0 +# define ZO_zorgmap_sys 0x1 +# define ZO_zorgacc_MASK 0xfffffffd /* bit 1 */ +# define ZO_zorgacc_pci 0x0 +# define ZO_zorgacc_agp 0x2 +# define ZO_zorg_MASK 0x3 /* bits 2-31 */ +# define ZO_zorg_SHIFT 2 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README index 3d7f20016..b5b473043 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README @@ -147,4 +147,4 @@ -$XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/README,v 1.1 1999/04/17 07:06:15 dawes Exp $ +$XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/README,v 1.2 2002/10/30 12:52:20 alanh Exp $ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h index 6ff546901..8b070b4e0 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.22 2002/09/16 18:05:57 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.23 2002/10/30 12:52:21 alanh Exp $ */ /* * The original Precision Insight driver for diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c index a67b891ee..55fd637a4 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c,v 1.4 2002/04/04 14:05:44 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c,v 1.5 2002/10/30 12:52:21 alanh Exp $ */ /* * The original Precision Insight driver for diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c index 2b757576a..e424a9384 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c,v 1.6 2002/04/04 14:05:44 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c,v 1.7 2002/10/30 12:52:21 alanh Exp $ */ /* * The original Precision Insight driver for diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c index d95be89f5..ce9b35b06 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c,v 1.10 2002/10/08 22:14:09 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c,v 1.12 2002/12/10 17:36:29 dawes Exp $ */ /* * The original Precision Insight driver for @@ -192,7 +192,7 @@ Neo2097AccelInit(ScreenPtr pScreen) Neo2097SubsequentMono8x8PatternFill; #endif - if (nPtr->strangeLockups) { + if (!nPtr->strangeLockups) { /* image writes */ infoPtr->ScanlineImageWriteFlags = ( CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD | diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c index fc8e64bb8..04bb5ad1e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c,v 1.18 2002/10/08 22:14:10 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c,v 1.20 2003/01/12 03:55:48 tsi Exp $ */ /* * The original Precision Insight driver for * XFree86 v.3.3 has been sponsored by Red Hat. @@ -541,7 +541,7 @@ Neo2200SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, #endif OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags | ((skipleft << 2) & 0x1C)); - #ifdef NEO_DO_CLIPPING +#ifdef NEO_DO_CLIPPING OUTREG(NEOREG_CLIPLT, (y << 16) | (x + skipleft)); OUTREG(NEOREG_CLIPRB, ((y + h) << 16) | (x + w)); #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c index 668aad0ff..8c40f4f2d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c,v 1.3 2002/01/25 21:56:05 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c,v 1.4 2002/10/30 12:52:21 alanh Exp $ */ /* * The original Precision Insight driver for diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c index 4f17a3673..1863fe53e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.8 2001/10/28 03:33:42 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.9 2002/10/30 12:52:21 alanh Exp $ */ /* * The original Precision Insight driver for diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c index 46f4bfc6e..bda060077 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c @@ -30,7 +30,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * Copyright 2002 Shigehiro Nomura */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.63 2002/09/16 18:05:57 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.66 2002/12/09 11:32:48 eich Exp $ */ /* * The original Precision Insight driver for @@ -1640,7 +1640,6 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(scrnIndex, X_PROBED, "%d bytes off-screen memory available\n", freespace); - nAcl->CursorAddress = 0; if (nPtr->swCursor || !nPtr->NeoMMIOBase) { xf86DrvMsg(scrnIndex, X_CONFIG, "Using Software Cursor.\n"); @@ -2829,7 +2828,7 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) int HDisplay = mode->HDisplay << ((mode->VDisplay < 480) ? 1 : 0); hoffset = ((nPtr->NeoPanelWidth - HDisplay) >> 4) - 1; - if (mode->VDisplay <= 480) + if (mode->VDisplay < 480) hoffset >>= 1; doCenter = TRUE; } else { @@ -2847,7 +2846,7 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) if (noLcdStretch) { /* Calculate the vertical offsets. */ int VDisplay = mode->VDisplay - << ((mode->Flags | V_DBLSCAN) ? 1 : 0); + << ((mode->Flags & V_DBLSCAN) ? 1 : 0); voffset = ((nPtr->NeoPanelHeight - VDisplay) >> 1) - 2; doCenter = TRUE; } else { @@ -2907,7 +2906,7 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) } #endif - if (mode->VDisplay <= 480) { + if (mode->VDisplay < 480) { NeoStd->Sequencer[1] |= 0x8; clockMul = 2; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c index 8a297868d..e97c7235e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.4 2002/09/16 18:05:58 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.5 2002/10/30 12:52:22 alanh Exp $ */ /* * The original Precision Insight driver for diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h index abc08f100..7e535195e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h,v 1.1 1999/04/17 07:06:27 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h,v 1.2 2002/10/30 12:52:22 alanh Exp $ */ /* * The original Precision Insight driver for diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h index fddc016c0..389323db3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h,v 1.1 1999/04/17 07:06:29 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h,v 1.2 2002/10/30 12:52:22 alanh Exp $ */ /* * The original Precision Insight driver for diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile index b0e2d67af..ab639c136 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile @@ -1,11 +1,11 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile,v 1.4 2001/05/16 06:48:09 keithp Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile,v 1.5 2002/12/10 04:03:00 dawes Exp $ #define IHaveModules #include <Server.tmpl> -SRCS = newport_driver.c newport_regs.c newport_cmap.c newport_shadow.c +SRCS = newport_driver.c newport_regs.c newport_cmap.c newport_shadow.c newport_cursor.c -OBJS = newport_driver.o newport_regs.o newport_cmap.o newport_shadow.o +OBJS = newport_driver.o newport_regs.o newport_cmap.o newport_shadow.o newport_cursor.o XF86CONFIG = XF86Config.indy diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy b/xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy index 080fd3de1..3a1dcc6e1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy @@ -27,7 +27,7 @@ # dealings in this Software without prior written authorization from the # XFree86 Project. # -# $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy,v 1.2 2000/12/14 20:59:12 dawes Exp $ +# $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy,v 1.3 2003/02/20 04:05:15 dawes Exp $ # ********************************************************************** # This is a configuration file for the Indy's Newport Graphics and the @@ -107,6 +107,12 @@ Section "ServerFlags" # Option "NoTrapSignals" +# Uncomment this to disable the <Crtl><Alt><Fn> VT switch sequence +# (where n is 1 through 12). This allows clients to receive these key +# events. + +# Option "DontVTSwitch" + # Uncomment this to disable the <Crtl><Alt><BS> server abort sequence # This allows clients to receive this key event. diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h index 584f72c41..ee71736f9 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h @@ -1,7 +1,7 @@ /* * Id: newport.h,v 1.4 2000/11/29 20:58:10 agx Exp $ */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h,v 1.9 2002/09/30 22:17:55 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h,v 1.10 2002/12/10 04:03:00 dawes Exp $ */ #ifndef __NEWPORT_H__ #define __NEWPORT_H__ @@ -25,7 +25,7 @@ #include "newport_regs.h" #define NEWPORT_BASE_ADDR0 0x1f0f0000 -#define NEWPORT_BASE_OFFSET 0x0040000 +#define NEWPORT_BASE_OFFSET 0x00400000 #define NEWPORT_MAX_BOARDS 4 #if 0 @@ -47,14 +47,21 @@ typedef struct { int bitplanes; /* revision numbers of the various pieces of silicon */ unsigned int board_rev, cmap_rev, rex3_rev, xmap9_rev, bt445_rev; + /* shadow copies of frequently used registers */ NewportRegsPtr pNewportRegs; /* Pointer to REX3 registers */ npireg_t drawmode1; /* REX3 drawmode1 common to all drawing operations */ + CARD16 vc2ctrl; /* VC2 control register */ /* ShadowFB stuff: */ CARD32* ShadowPtr; unsigned long int ShadowPitch; unsigned int Bpp; /* Bytes per pixel */ + /* HWCursour stuff: */ + Bool hwCursor; + xf86CursorInfoPtr CursorInfoRec; + CARD16 curs_cmap_base; /* MSB of the cursor's cmap */ + /* wrapped funtions: */ CloseScreenProcPtr CloseScreen; @@ -68,12 +75,19 @@ typedef struct { npireg_t txt_smask2y; npireg_t txt_clipmode; /* Rex3 clip mode register */ - unsigned short txt_vc2ctrl; /* VC2 control register */ + CARD16 txt_vc2ctrl; /* VC2 control register */ + CARD16 txt_vc2cur_x; /* VC2 hw cursor x location */ + CARD16 txt_vc2cur_y; /* VC2 hw cursor x location */ + CARD32 txt_vc2cur_data[64]; /* VC2 hw cursor glyph data */ + CARD8 txt_xmap9_cfg0; /* 0. Xmap9's control register */ CARD8 txt_xmap9_cfg1; /* 1. Xmap9's control register */ + CARD8 txt_xmap9_ccmsb; /* cursor cmap msb */ CARD8 txt_xmap9_mi; /* Xmap9s' mode index register */ CARD32 txt_xmap9_mod0; /* Xmap9s' mode 0 register */ + LOCO txt_colormap[256]; + OptionInfoPtr Options; } NewportRec, *NewportPtr; @@ -91,15 +105,24 @@ void NewportBackupRex3( ScrnInfoPtr pScrn); void NewportRestoreRex3( ScrnInfoPtr pScrn); void NewportBackupXmap9s( ScrnInfoPtr pScrn); void NewportRestoreXmap9s( ScrnInfoPtr pScrn); +void NewportBackupVc2( ScrnInfoPtr pScrn); +void NewportRestoreVc2( ScrnInfoPtr pScrn); +void NewportBackupVc2Cursor( ScrnInfoPtr pScrn); +void NewportRestoreVc2Cursor( ScrnInfoPtr pScrn); /* newort_cmap.c */ void NewportLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO* colors, VisualPtr pVisual); void NewportRestorePalette(ScrnInfoPtr pScrn); void NewportBackupPalette(ScrnInfoPtr pScrn); +void NewportCmapSetRGB( NewportRegsPtr pNewportRegs, unsigned short addr, LOCO color); /* newport_shadow.c */ void NewportRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); void NewportRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +/* newport_cursor.c */ +Bool NewportHWCursorInit(ScreenPtr pScreen); +void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits); + #endif /* __NEWPORT_H__ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_cursor.c new file mode 100644 index 000000000..b5328f8c4 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_cursor.c @@ -0,0 +1,165 @@ +/* + * newport_cursor.c + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_cursor.c,v 1.1 2002/12/10 04:03:00 dawes Exp $ */ + +#include "newport.h" +#include "cursorstr.h" + +#include "servermd.h" + +#define MAX_CURS 32 + +static void NewportShowCursor(ScrnInfoPtr pScrn); +static void NewportHideCursor(ScrnInfoPtr pScrn); +static void NewportSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); +static void NewportSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); +/* static void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits); */ +static unsigned char* NewportRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs); + +Bool +NewportHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + xf86CursorInfoPtr infoPtr; + CARD16 tmp; + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) + return FALSE; + + pNewport->CursorInfoRec = infoPtr; + infoPtr->MaxWidth = MAX_CURS; + infoPtr->MaxHeight = MAX_CURS; + infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; + + infoPtr->SetCursorColors = NewportSetCursorColors; + infoPtr->SetCursorPosition = NewportSetCursorPosition; + infoPtr->LoadCursorImage = NewportLoadCursorImage; + infoPtr->HideCursor = NewportHideCursor; + infoPtr->ShowCursor = NewportShowCursor; + infoPtr->RealizeCursor = NewportRealizeCursor; + infoPtr->UseHWCursor = NULL; + + /* enable cursor funtion in shadow register */ + pNewport->vc2ctrl |= VC2_CTRL_ECURS; + /* enable glyph cursor, maximum size is 32x32x2 */ + pNewport->vc2ctrl &= ~( VC2_CTRL_ECG64 | VC2_CTRL_ECCURS); + /* setup hw cursors cmap base address */ + NewportBfwait(pNewportRegs); + pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | + XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 ); + tmp = pNewportRegs->set.dcbdata0.bytes.b3; +#if 0 + /* The docs say we can change base address of the cursors + * cmap entries, but it doesn't work. */ + tmp++; +#endif + pNewportRegs->set.dcbmode = (DCB_XMAP0 | W_DCB_XMAP9_PROTOCOL | + XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 ); + pNewportRegs->set.dcbdata0.bytes.b3 = tmp; + pNewport->curs_cmap_base = (tmp << 5) & 0xffe0; + + return xf86InitCursor(pScreen, infoPtr); +} + + +static void NewportShowCursor(ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + pNewport->vc2ctrl |= VC2_CTRL_ECDISP; + NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); +} + +static void NewportHideCursor(ScrnInfoPtr pScrn) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + pNewport->vc2ctrl &= ~VC2_CTRL_ECDISP; + NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); +} + +static void NewportSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + CARD16 x_off; + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + NewportPtr pNewport = NEWPORTPTR(pScrn); + + /* the docu says this should always be 31, but it isn't */ + x_off = 31; + if ( pNewport->board_rev < 6 ) + x_off = 21; + NewportVc2Set( pNewportRegs, VC2_IREG_CURSX, (CARD16) x + x_off); + NewportVc2Set( pNewportRegs, VC2_IREG_CURSY, (CARD16) y + 31); +} + +static void NewportSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + NewportPtr pNewport = NEWPORTPTR(pScrn); + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + LOCO color; + + color.blue = bg & 0xff; + color.green = (bg & 0xff00) >> 8; + color.red = (bg & 0xff0000) >> 16; + NewportCmapSetRGB( pNewportRegs, pNewport->curs_cmap_base+2, color); + + color.blue = fg & 0xff; + color.green = (fg & 0xff00) >> 8; + color.red = (fg & 0xff0000) >> 16; + NewportCmapSetRGB( pNewportRegs, pNewport->curs_cmap_base+1, color); +} + +static unsigned char* NewportRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) +{ + int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; + CARD32 *mem, *SrcS, *SrcM, *DstS; + unsigned int i; + + if (!(mem = xcalloc(1, size))) + return NULL; + + SrcS = (CARD32*)pCurs->bits->source; + SrcM = (CARD32*)pCurs->bits->mask; + DstS = mem; + /* first color: maximum is 32*4 Bytes */ + for(i=0; i < pCurs->bits->height; i++) { + *DstS = *SrcS & *SrcM; + DstS++, SrcS++, SrcM++; + } + /* second color is the lower of mem: again 32*4 Bytes at most */ + DstS = mem + MAX_CURS; + SrcS = (CARD32*)pCurs->bits->source; + SrcM = (CARD32*)pCurs->bits->mask; + for(i=0; i < pCurs->bits->height; i++) { + *DstS = (~*SrcS) & *SrcM; + DstS++, SrcS++, SrcM++; + } + return (unsigned char*) mem; +} + +void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) +{ + int i; + CARD16 tmp; + NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); + + /* address of cursor data in vc2's ram */ + tmp = NewportVc2Get( pNewportRegs, VC2_IREG_CENTRY); + /* this is where we want to write to: */ + NewportVc2Set( pNewportRegs, VC2_IREG_RADDR, tmp); + pNewportRegs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | + NPORT_DMODE_W2 | VC2_PROTOCOL); + /* write cursor data */ + for (i = 0; i < ((MAX_CURS * MAX_CURS) >> 3); i++) { + NewportBfwait(pNewportRegs); + pNewportRegs->set.dcbdata0.hwords.s1 = *(unsigned short*)bits; + bits += sizeof(unsigned short); + } +} + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c index 3971a7548..e55354cd2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c @@ -5,7 +5,7 @@ * * This driver is based on the newport.c & newport_con.c kernel code * - * (c) 2000,2001 Guido Guenther <agx@sigxcpu.org> + * (c) 2000-2002 Guido Guenther <agx@sigxcpu.org> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,7 +30,7 @@ * Project. * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c,v 1.20 2002/09/30 22:17:55 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c,v 1.24 2003/02/18 19:10:36 alanh Exp $ */ /* function prototypes, common data structures & generic includes */ #include "newport.h" @@ -106,6 +106,12 @@ static const char *fbSymbols[] = { NULL }; +static const char *ramdacSymbols[] = { + "xf86CreateCursorInfoRec", + "xf86InitCursor", + NULL +}; + static const char *shadowSymbols[] = { "ShadowFBInit", NULL @@ -150,7 +156,7 @@ newportSetup(pointer module, pointer opts, int *errmaj, int *errmin) * might refer to. * */ - LoaderRefSymLists( fbSymbols, shadowSymbols, NULL); + LoaderRefSymLists( fbSymbols, ramdacSymbols, shadowSymbols, NULL); /* @@ -168,13 +174,15 @@ newportSetup(pointer module, pointer opts, int *errmaj, int *errmin) typedef enum { OPTION_BITPLANES, - OPTION_BUS_ID + OPTION_BUS_ID, + OPTION_HWCURSOR } NewportOpts; /* Supported options */ static const OptionInfoRec NewportOptions [] = { { OPTION_BITPLANES, "bitplanes", OPTV_INTEGER, {0}, FALSE }, { OPTION_BUS_ID, "BusID", OPTV_INTEGER, {0}, FALSE }, + { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -243,7 +251,8 @@ NewportProbe(DriverPtr drv, int flags) * Set it as an ISA entity to get the entity field set up right. */ entity = xf86ClaimIsaSlot(drv, 0, dev, TRUE); - base = (NEWPORT_BASE_ADDR0 + busID * NEWPORT_BASE_OFFSET); + base = (NEWPORT_BASE_ADDR0 + + busID * NEWPORT_BASE_OFFSET); RANGE(range[0], base, base + sizeof(NewportRegs),\ ResExcMemBlock); pScrn = xf86ConfigIsaEntity(pScrn, 0, entity, NULL, range, \ @@ -385,11 +394,17 @@ NewportPreInit(ScrnInfoPtr pScrn, int flags) pNewport->bitplanes); return FALSE; } + + from=X_DEFAULT; + pNewport->hwCursor = TRUE; + if (xf86GetOptValBool(pNewport->Options, OPTION_HWCURSOR, &pNewport->hwCursor)) + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pNewport->hwCursor ? "HW" : "SW"); /* Set up clock ranges that are alway ok */ - /* XXX: Use information from VC2 here */ - clockRanges = xnfalloc(sizeof(ClockRange)); + clockRanges = xnfcalloc(sizeof(ClockRange),1); clockRanges->next = NULL; clockRanges->minClock = 10000; clockRanges->maxClock = 300000; @@ -437,6 +452,15 @@ NewportPreInit(ScrnInfoPtr pScrn, int flags) } xf86LoaderReqSymLists( fbSymbols, NULL); + /* Load ramdac modules */ + if (pNewport->hwCursor) { + if (!xf86LoadSubModule(pScrn, "ramdac")) { + NewportFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(ramdacSymbols, NULL); + } + /* Load ShadowFB module */ if (!xf86LoadSubModule(pScrn, "shadowfb")) { NewportFreeRec(pScrn); @@ -478,7 +502,7 @@ NewportScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) /* Setup the stuff for the shadow framebuffer */ pNewport->ShadowPitch = (( pScrn->virtualX * pNewport->Bpp ) + 3) & ~3L; pNewport->ShadowPtr = xnfalloc(pNewport->ShadowPitch * pScrn->virtualY); - + if (!NewportModeInit(pScrn, pScrn->currentMode)) return FALSE; @@ -517,19 +541,35 @@ NewportScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) /* Initialize software cursor */ if(!miDCInitialize(pScreen, xf86GetPointerScreenFuncs())) return FALSE; - + + /* Initialize hardware cursor */ + if(pNewport->hwCursor) + if(!NewportHWCursorInit(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + return FALSE; + } + /* Initialise default colourmap */ if (!miCreateDefColormap(pScreen)) return FALSE; /* Install our LoadPalette funciton */ if(!xf86HandleColormaps(pScreen, 256, 8, NewportLoadPalette, 0, - CMAP_RELOAD_ON_MODE_SWITCH )) + CMAP_RELOAD_ON_MODE_SWITCH )) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Colormap initialization failed\n"); return FALSE; + } /* Initialise shadow frame buffer */ - ShadowFBInit(pScreen, (pNewport->Bpp == 1) ? &NewportRefreshArea8 : - &NewportRefreshArea24); + if(!ShadowFBInit(pScreen, (pNewport->Bpp == 1) ? &NewportRefreshArea8 : + &NewportRefreshArea24)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ShadowFB initialization failed\n"); + return FALSE; + } + #ifdef XvExtension { @@ -596,9 +636,9 @@ static Bool NewportSaveScreen(ScreenPtr pScreen, int mode) { ScrnInfoPtr pScrn; + NewportPtr pNewport; NewportRegsPtr pNewportRegs; Bool unblank; - unsigned short treg; if (!pScreen) return TRUE; @@ -609,15 +649,14 @@ NewportSaveScreen(ScreenPtr pScreen, int mode) if (!pScrn->vtSema) return TRUE; + pNewport = NEWPORTPTR(pScrn); pNewportRegs = NEWPORTPTR(pScrn)->pNewportRegs; - if (unblank) { - treg = NewportVc2Get(pNewportRegs, VC2_IREG_CONTROL); - NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, (treg | VC2_CTRL_EDISP)); - } else { - treg = NewportVc2Get(pNewportRegs, VC2_IREG_CONTROL); - NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, (treg & ~(VC2_CTRL_EDISP))); - } + if (unblank) + pNewport->vc2ctrl |= VC2_CTRL_EDISP; + else + pNewport->vc2ctrl &= ~VC2_CTRL_EDISP; + NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); return TRUE; } @@ -648,11 +687,11 @@ NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pScrn->vtSema = TRUE; /* first backup the necessary registers... */ NewportBackupRex3(pScrn); - pNewport->txt_vc2ctrl = NewportVc2Get( pNewportRegs, VC2_IREG_CONTROL); + if( pNewport->hwCursor ) + NewportBackupVc2Cursor( pScrn ); + NewportBackupVc2(pScrn); NewportBackupPalette(pScrn); - if( pNewport->Bpp == 3) { /* at 24bpp we have to backup some more registers */ - NewportBackupXmap9s( pScrn ); - } + NewportBackupXmap9s( pScrn ); /* ...then setup the hardware */ pNewport->drawmode1 = DM1_RGBPLANES | NPORT_DMODE1_CCLT | @@ -668,7 +707,7 @@ NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) /* tell the xmap9s that we are using 24bpp */ NewportBfwait(pNewport->pNewportRegs); - pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | R_DCB_XMAP9_PROTOCOL | + pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL | XM9_CRS_CONFIG | NPORT_DMODE_W1 ); pNewportRegs->set.dcbdata0.bytes.b3 &= ~(XM9_8_BITPLANES | XM9_PUPMODE); NewportBfwait(pNewport->pNewportRegs); @@ -710,6 +749,9 @@ NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) NewportWait(pNewportRegs); pNewportRegs->set.drawmode1 = pNewport->drawmode1; + /* XXX: Lazy mode on: just use the textmode value */ + pNewport->vc2ctrl = pNewport->txt_vc2ctrl; + return TRUE; } @@ -723,15 +765,14 @@ static void NewportRestore(ScrnInfoPtr pScrn, Bool Closing) { NewportPtr pNewport = NEWPORTPTR(pScrn); - NewportRegsPtr pNewportRegs = pNewport->pNewportRegs; /* Restore backed up registers */ NewportRestoreRex3( pScrn ); - NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->txt_vc2ctrl ); + if( pNewport->hwCursor ) + NewportRestoreVc2Cursor( pScrn ); + NewportRestoreVc2( pScrn ); NewportRestorePalette( pScrn ); - if( pNewport->Bpp == 3) { - NewportRestoreXmap9s( pScrn); - } + NewportRestoreXmap9s( pScrn ); } @@ -740,21 +781,26 @@ NewportRestore(ScrnInfoPtr pScrn, Bool Closing) static unsigned NewportHWProbe(unsigned probedIDs[]) { - FILE* cpuinfo; + FILE* cpuinfo; char line[80]; unsigned hasNewport = 0; + if ((cpuinfo = fopen("/proc/cpuinfo", "r"))) { - while(fgets(line, 80, cpuinfo) != NULL) { + while(fgets(line, 80, cpuinfo) != NULL) { if(strstr(line, "SGI Indy") != NULL) { hasNewport = 1; + probedIDs[0] = 0; + break; + } + if(strstr(line, "SGI Indigo2") != NULL) { + hasNewport = 1; + probedIDs[0] = 1; break; } } - fclose(cpuinfo); + fclose(cpuinfo); } - - probedIDs[0] = 0; - return hasNewport; + return hasNewport; } /* Probe for Chipset revisions */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/nsc/Imakefile new file mode 100644 index 000000000..caab37f73 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/Imakefile @@ -0,0 +1,178 @@ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/Imakefile,v 1.6 2003/02/19 10:10:49 alanh Exp $ +XCOMM Imakefile for the National Semiconductor display driver +XCOMM that is based on the durango code. +XCOMM +XCOMM (c) 2000 National Semiconductor corporation +XCOMM (c) 2000 by Juergen Schneider, Infomatec IAS GmbH +XCOMM +#define IHaveModules +#include <Server.tmpl> + +XCOMM Turn this on for the Set-Top-Box (STB) mode which uses +XCOMM the NSC linux kernel frame buffer driver interface. + +XCOMM #define NSC_STB + +#if !defined(NSC_STB) +DEFINES = -DOPT_ACCEL +DURANGOSRCS = durango.c panel.c +DURANGOOBJS = durango.o panel.o +EXTINCLUDES = -I./gfx -I./panel +#else +DEFINES = -DSTB_X +STBSRCS = nsc_galstub.c +STBOBJS = nsc_galstub.o +EXTINCLUDES = -I/usr/src/linux/drivers/video/nsc/gfx \ + -I/usr/src/linux/drivers/video/nsc/panel \ + -I/usr/src/linux/drivers/video/nsc/ +#endif + +#ifdef i386Architecture +I86SRC = nsc_msr_asm.S +I86OBJ = nsc_msr_asm.o +#endif + +SRCS = nsc_driver.c \ + nsc_gx1_driver.c \ + nsc_gx1_dga.c \ + nsc_gx1_accel.c \ + nsc_gx1_cursor.c \ + nsc_gx1_video.c \ + nsc_gx1_shadow.c \ + nsc_gx2_driver.c\ + nsc_gx2_accel.c \ + nsc_gx2_cursor.c \ + nsc_gx2_dga.c \ + nsc_gx2_video.c \ + nsc_gx2_shadow.c $(I86SRC) $(STBSRCS) $(DURANGOSRCS) + +OBJS = nsc_driver.o \ + nsc_gx1_driver.o \ + nsc_gx1_accel.o \ + nsc_gx1_cursor.o \ + nsc_gx1_dga.o \ + nsc_gx1_shadow.o \ + nsc_gx1_video.o \ + nsc_gx2_driver.o \ + nsc_gx2_accel.o \ + nsc_gx2_cursor.o \ + nsc_gx2_dga.o \ + nsc_gx2_video.o \ + nsc_gx2_shadow.o $(I86OBJ) $(STBOBJS) $(DURANGOOBJS) + +#if defined(XF86DriverSDK) +INCLUDES = -I. -I../../include +#else +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/cfb -I$(SERVERSRC)/fb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ + -I$(XF86SRC)/rac -I$(XF86SRC)/int10 \ + -I$(XF86SRC)/xf24_32bpp -I$(FONTINCSRC) \ + -I$(XF86SRC)/xf8_32bpp -I$(XF86SRC)/xf1bpp \ + -I$(XF86SRC)/xf4bpp -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(EXTINCSRC) $(DRIINCLUDES) \ + -I$(XF86SRC)/shadowfb -I$(XF86SRC)/fbdevhw \ + -I$(XTOP)/include -I$(XF86SRC)/vbe -I$(SERVERSRC)/render \ + $(EXTINCLUDES) +#endif + + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif + +ModuleObjectRule() + +ObjectModuleTarget(nsc,$(OBJS)) + +InstallObjectModule(nsc,$(MODULEDIR),drivers) + +#if !defined(XF86DriverSDK) +CppManTarget(nsc,) +InstallModuleManPage(nsc) +#endif + +DependTarget() + +#ifdef i386Architecture +ObjectFromAsmSource(nsc_msr_asm,NullParameter) +#endif + +InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/nsc) + +InstallDriverSDKNonExecFile(durango.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc.h,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_driver.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_fourcc.h,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_galfns.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_galstub.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx1_accel.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx1_cursor.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx1_dga.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx1_driver.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx1_shadow.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx1_video.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx2_accel.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx2_cursor.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx2_dga.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx2_driver.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx2_shadow.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx2_vga.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_gx2_video.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_msr_asm.S,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(nsc_regacc.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(panel.c,$(DRIVERSDKDIR)/drivers/nsc) +InstallDriverSDKNonExecFile(gfx/disp_gu1.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/disp_gu2.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/durango.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_dcdr.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_defs.h,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_disp.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_i2c.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_init.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_mode.h,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_msr.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_regs.h,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_rndr.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_rtns.h,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_tv.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_type.h,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_vga.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_vid.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/gfx_vip.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/history.h,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/i2c_acc.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/i2c_gpio.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/init_gu1.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/init_gu2.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/msr_rdcl.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/release.txt,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/rndr_gu1.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/rndr_gu2.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/saa7114.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/tv_1200.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/tv_fs450.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/tv_fs450.h,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/vga_gu1.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/vid_1200.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/vid_5530.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/vid_rdcl.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(gfx/vip_1200.c,$(DRIVERSDKDIR)/drivers/nsc/gfx) +InstallDriverSDKNonExecFile(panel/92xx.h,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/cen9211.c,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/cen9211.h,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/dora9211.c,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/dora9211.h,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/drac9210.c,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/drac9210.h,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/panel.c,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/panel.h,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/platform.c,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/pnl_bios.c,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/pnl_defs.h,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/pnl_init.c,$(DRIVERSDKDIR)/drivers/nsc/panel) +InstallDriverSDKNonExecFile(panel/readme.txt,$(DRIVERSDKDIR)/drivers/nsc/panel) + +InstallDriverSDKObjectModule(nsc,$(DRIVERSDKMODULEDIR),drivers) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/durango.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/durango.c new file mode 100644 index 000000000..88030bb31 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/durango.c @@ -0,0 +1,722 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/durango.c,v 1.5 2003/01/24 17:16:52 tsi Exp $ */ +/* + * $Workfile: durango.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * This is the main file used to add Durango graphics support to a software + * project. The main reason to have a single file include the other files + * is that it centralizes the location of the compiler options. This file + * should be tuned for a specific implementation, and then modified as needed + * for new Durango releases. The releases.txt file indicates any updates to + * this main file, such as a new definition for a new hardware platform. + * + * In other words, this file should be copied from the Durango source files + * once when a software project starts, and then maintained as necessary. + * It should not be recopied with new versions of Durango unless the + * developer is willing to tune the file again for the specific project. + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* COMPILER OPTIONS + * These compiler options specify how the Durango routines are compiled + * for the different hardware platforms. For best performance, a driver + * would build for a specific platform. The "dynamic" switches are set + * by diagnostic applications such as Darwin that will run on a variety + * of platforms and use the appropriate code at runtime. Each component + * may be separately dynamic, so that a driver has the option of being + * tuned for a specific 2D accelerator, but will still run with a variety + * of chipsets. + */ + +#define GFX_DISPLAY_DYNAMIC 1 /* runtime selection */ +#define GFX_DISPLAY_GU1 1 /* 1st generation display controller */ +#define GFX_DISPLAY_GU2 1 /* 2nd generation display controller */ + +#define GFX_INIT_DYNAMIC 1 /* runtime selection */ +#define GFX_INIT_GU1 1 /* Geode family */ +#define GFX_INIT_GU2 1 /* Redcloud */ + +#define GFX_MSR_DYNAMIC 1 /* runtime selection */ +#define GFX_MSR_REDCLOUD 1 /* Redcloud */ + +#define GFX_2DACCEL_DYNAMIC 1 /* runtime selection */ +#define GFX_2DACCEL_GU1 1 /* 1st generation 2D accelerator */ +#define GFX_2DACCEL_GU2 1 /* 2nd generation 2D accelerator */ + +#define GFX_VIDEO_DYNAMIC 1 /* runtime selection */ +#define GFX_VIDEO_CS5530 1 /* support for CS5530 */ +#define GFX_VIDEO_SC1200 1 /* support for SC1200 */ +#define GFX_VIDEO_REDCLOUD 1 /* support for Redcloud */ + +#define GFX_VIP_DYNAMIC 1 /* runtime selection */ +#define GFX_VIP_SC1200 1 /* support for SC1200 */ + +#define GFX_DECODER_DYNAMIC 1 /* runtime selection */ +#define GFX_DECODER_SAA7114 1 /* Philips SAA7114 decoder */ + +#define GFX_TV_DYNAMIC 1 /* runtime selection */ +#define GFX_TV_FS451 0 /* Focus Enhancements FS450 */ +#define GFX_TV_SC1200 1 /* SC1200 integrated TV encoder */ + +#define GFX_I2C_DYNAMIC 1 /* runtime selection */ +#define GFX_I2C_ACCESS 1 /* support for ACCESS.BUS */ +#define GFX_I2C_GPIO 1 /* support for CS5530 GPIOs */ + +#define GFX_VGA_DYNAMIC 1 /* runtime selection */ +#define GFX_VGA_GU1 1 /* 1st generation graphics unit */ + +#define FB4MB 1 /* Set to use 4Mb video ram for Pyramid */ + +#define GFX_NO_IO_IN_WAIT_MACROS 1 /* Set to remove I/O accesses in GP bit testing */ + +/* ROUTINES TO READ VALUES + * These are routines used by Darwin or other diagnostics to read the + * current state of the hardware. Display drivers or embedded applications can + * reduce the size of the Durango code by not including these routines. + */ +#define GFX_READ_ROUTINES 1 /* add routines to read values */ + +/* HEADER FILE FOR DURANGO ROUTINE DEFINITIONS + * Needed since some of the Durango routines call other Durango routines. + * Also defines the size of chipset array (GFX_CSPTR_SIZE). + */ +#include "gfx_rtns.h" /* routine definitions */ + +/* VARIABLES USED FOR RUNTIME SELECTION + * If part of the graphics subsystem is declared as dynamic, then the + * following variables are used to specify which platform has been detected. + * The variables are set in the "gfx_detect_cpu" routine. The values should + * be bit flags to allow masks to be used to check for multiple platforms. + */ + +#if GFX_DISPLAY_DYNAMIC +int gfx_display_type = 0; +#endif + +#if GFX_INIT_DYNAMIC +int gfx_init_type = 0; +#endif + +#if GFX_MSR_DYNAMIC +int gfx_msr_type = 0; +#endif + +#if GFX_2DACCEL_DYNAMIC +int gfx_2daccel_type = 0; +#endif + +#if GFX_VIDEO_DYNAMIC +int gfx_video_type = 0; +#endif + +#if GFX_VIP_DYNAMIC +int gfx_vip_type = 0; +#endif + +#if GFX_DECODER_DYNAMIC +int gfx_decoder_type = 0; +#endif + +#if GFX_TV_DYNAMIC +int gfx_tv_type = 0; +#endif + +#if GFX_I2C_DYNAMIC +int gfx_i2c_type = 0; +#endif + +#if GFX_VGA_DYNAMIC +int gfx_vga_type = 0; +#endif + +/* DEFINE POINTERS TO MEMORY MAPPED REGIONS + * These pointers are used by the Durango routines to access the hardware. + * The variables must be set by the project's initialization code after + * mapping the regions in the appropriate manner. + */ + +/* DEFINE VIRTUAL ADDRESSES */ +/* Note: These addresses define the starting base expected by all */ +/* Durango offsets. Under an OS that requires these pointers */ +/* to be mapped to linear addresses (i.e Windows), it may not */ +/* be possible to keep these base offsets. In these cases, */ +/* the addresses are modified to point to the beginning of the */ +/* relevant memory region and the access macros are adjusted */ +/* to subtract the offset from the default base. For example, */ +/* the register pointer could be moved to be 0x40008000, while */ +/* the WRITE_REG* macros are modified to subtract 0x8000 from */ +/* the offset. */ + +unsigned char *gfx_virt_regptr = (unsigned char *)0x40000000; +unsigned char *gfx_virt_fbptr = (unsigned char *)0x40800000; +unsigned char *gfx_virt_vidptr = (unsigned char *)0x40010000; +unsigned char *gfx_virt_vipptr = (unsigned char *)0x40015000; +unsigned char *gfx_virt_spptr = (unsigned char *)0x40000000; +unsigned char *gfx_virt_gpptr = (unsigned char *)0x40000000; + +/* DEFINE PHYSICAL ADDRESSES */ + +unsigned char *gfx_phys_regptr = (unsigned char *)0x40000000; +unsigned char *gfx_phys_fbptr = (unsigned char *)0x40800000; +unsigned char *gfx_phys_vidptr = (unsigned char *)0x40010000; +unsigned char *gfx_phys_vipptr = (unsigned char *)0x40015000; + +/* HEADER FILE FOR GRAPHICS REGISTER DEFINITIONS + * This contains only constant definitions, so it should be able to be + * included in any software project as is. + */ +#include "gfx_regs.h" /* graphics register definitions */ + +/* HEADER FILE FOR REGISTER ACCESS MACROS + * This file contains the definitions of the WRITE_REG32 and similar macros + * used by the Durango routines to access the hardware. The file assumes + * that the environment can handle 32-bit pointer access. If this is not + * the case, or if there are special requirements, then this header file + * should not be included and the project must define the macros itself. + * (A project may define WRITE_REG32 to call a routine, for example). + */ +#include "gfx_defs.h" /* register access macros */ + +/* IO MACROS AND ROUTINES + * These macros must be defined before the initialization or I2C + * routines will work properly. + */ + +#if defined(OS_WIN32) /* For Windows */ + +/* VSA II CALL */ + +void +gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ + unsigned long temp1, temp2; + + _asm { + mov dx, 0x0AC1C + mov eax, 0x0FC530007 + out dx, eax + add dl, 2 + mov ecx, msrAddr + mov cx, msrReg + in ax, dx; + ;EDX:EAX will contain MSR contents. + mov temp1, edx + mov temp2, eax + } + + *ptrHigh = temp1; + *ptrLow = temp2; +} + +void +gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ + unsigned long temp1 = *ptrHigh; + unsigned long temp2 = *ptrLow; + + _asm { + mov dx, 0x0AC1C + mov eax, 0x0FC530007 + out dx, eax i + add dl, 2 + ;ECX contains msrAddr | msrReg + mov ecx, msrAddr + mov cx, msrReg + ;<OR_mask_hi > + mov ebx, temp1 + + ;<OR_mask_hi > + mov eax, temp2 + ;<AND_mask_hi > + mov esi, 0 + ;<AND_mask_lo > + mov edi, 0 + ;MSR is written at this point + out dx, ax + } +} + +unsigned char +gfx_inb(unsigned short port) +{ + unsigned char data; + + _asm { + pushf + mov dx, port + in al, dx + mov data, al + popf + } + return (data); +} + +unsigned short +gfx_inw(unsigned short port) +{ + unsigned short data; + + _asm { + pushf + mov dx, port + in ax, dx + mov data, ax + popf + } + return (data); +} + +unsigned long +gfx_ind(unsigned short port) +{ + unsigned long data; + + _asm { + pushf + mov dx, port + in eax, dx + mov data, eax + popf + } + return (data); +} + +void +gfx_outb(unsigned short port, unsigned char data) +{ + _asm { + pushf + mov al, data + mov dx, port + out dx, al + popf + } +} + +void +gfx_outw(unsigned short port, unsigned short data) +{ + _asm { + pushf + mov ax, data + mov dx, port + out dx, ax + popf + } +} + +void +gfx_outd(unsigned short port, unsigned long data) +{ + _asm { + pushf + mov eax, data + mov dx, port + out dx, eax + popf + } +} + +#elif defined(OS_VXWORKS) || defined (OS_LINUX) /* VxWorks and Linux */ + +extern unsigned long nsc_asm_msr_vsa_rd(unsigned long, unsigned long *, + unsigned long *); +extern unsigned long nsc_asm_msr_vsa_wr(unsigned long, unsigned long, + unsigned long); + +void +gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ + unsigned long addr, val1, val2; + + addr = msrAddr | (unsigned long)msrReg; + nsc_asm_msr_vsa_rd(addr, &val2, &val1); + *ptrHigh = val2; + *ptrLow = val1; +} + +void +gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ + unsigned long addr, val1, val2; + + val2 = *ptrHigh; + val1 = *ptrLow; + addr = (msrAddr & 0xFFFF0000) | (unsigned long)msrReg; + nsc_asm_msr_vsa_wr(addr, val2, val1); +} + +unsigned char +gfx_inb(unsigned short port) +{ + unsigned char value; + __asm__ volatile ("inb %1,%0":"=a" (value):"d"(port)); + + return value; +} + +unsigned short +gfx_inw(unsigned short port) +{ + unsigned short value; + __asm__ volatile ("in %1,%0":"=a" (value):"d"(port)); + + return value; +} + +unsigned long +gfx_ind(unsigned short port) +{ + unsigned long value; + __asm__ volatile ("inl %1,%0":"=a" (value):"d"(port)); + + return value; +} + +void +gfx_outb(unsigned short port, unsigned char data) +{ + __asm__ volatile ("outb %0,%1"::"a" (data), "d"(port)); +} + +void +gfx_outw(unsigned short port, unsigned short data) +{ + __asm__ volatile ("out %0,%1"::"a" (data), "d"(port)); +} + +void +gfx_outd(unsigned short port, unsigned long data) +{ + __asm__ volatile ("outl %0,%1"::"a" (data), "d"(port)); +} + +#elif defined(XFree86Server) + +#include <xf86_ansic.h> +#include <compiler.h> +#define INB(port) inb(port) +#define INW(port) inw(port) +#define IND(port) inl(port) +#define OUTB(port,data) outb(port, data) +#define OUTW(port,data) outw(port, data) +#define OUTD(port,data) outl(port, data) + +unsigned char gfx_inb(unsigned short port); +unsigned short gfx_inw(unsigned short port); +unsigned long gfx_ind(unsigned short port); +void gfx_outb(unsigned short port, unsigned char data); +void gfx_outw(unsigned short port, unsigned short data); +void gfx_outd(unsigned short port, unsigned long data); + +unsigned char +gfx_inb(unsigned short port) +{ + return inb(port); +} + +unsigned short +gfx_inw(unsigned short port) +{ + return inw(port); +} + +unsigned long +gfx_ind(unsigned short port) +{ + return inl(port); +} + +void +gfx_outb(unsigned short port, unsigned char data) +{ + outb(port, data); +} + +void +gfx_outw(unsigned short port, unsigned short data) +{ + outw(port, data); +} + +void +gfx_outd(unsigned short port, unsigned long data) +{ + outl(port, data); +} + +#ifdef __i386__ +extern unsigned long nsc_asm_msr_vsa_rd(unsigned long, unsigned long *, + unsigned long *); +extern unsigned long nsc_asm_msr_vsa_wr(unsigned long, unsigned long, + unsigned long); +#endif + +void +gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ +#ifdef __i386__ + unsigned long addr, val1, val2; + + addr = msrAddr | (unsigned long)msrReg; + nsc_asm_msr_vsa_rd(addr, &val2, &val1); + *ptrHigh = val2; + *ptrLow = val1; +#endif +} + +void +gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ +#ifdef __i386__ + unsigned long addr, val1, val2; + + val2 = *ptrHigh; + val1 = *ptrLow; + addr = (msrAddr & 0xFFFF0000) | (unsigned long)msrReg; + nsc_asm_msr_vsa_wr(addr, val2, val1); +#endif +} +#else /* else nothing */ + +unsigned char +gfx_inb(unsigned short port) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ + return (0); +} + +unsigned short +gfx_inw(unsigned short port) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ + return (0); +} + +unsigned long +gfx_ind(unsigned short port) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ + return (0); +} + +void +gfx_outb(unsigned short port, unsigned char data) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ +} + +void +gfx_outw(unsigned short port, unsigned short data) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ +} + +void +gfx_outd(unsigned short port, unsigned long data) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ +} +#endif + +#ifndef XFree86Server +#define INB(port) gfx_inb(port) +#define INW(port) gfx_inw(port) +#define IND(port) gfx_ind(port) +#define OUTB(port, data) gfx_outb(port, data) +#define OUTW(port, data) gfx_outw(port, data) +#define OUTD(port, data) gfx_outd(port, data) +#endif + +/* INITIALIZATION ROUTINES + * These routines are used during the initialization of the driver to + * perform such tasks as detecting the type of CPU and video hardware. + * The routines require the use of IO, so the above IO routines need + * to be implemented before the initialization routines will work + * properly. + */ + +#include "gfx_init.c" + +/* INCLUDE MSR ACCESS ROUTINES */ + +#include "gfx_msr.c" + +/* INCLUDE GRAPHICS ENGINE ROUTINES + * These routines are used to program the 2D graphics accelerator. If + * the project does not use graphics acceleration (direct frame buffer + * access only), then this file does not need to be included. + */ +#include "gfx_rndr.c" /* graphics engine routines */ + +/* INCLUDE DISPLAY CONTROLLER ROUTINES + * These routines are used if the display mode is set directly. If the + * project uses VGA registers to set a display mode, then these files + * do not need to be included. + */ +#include "gfx_mode.h" /* display mode tables */ +#include "gfx_disp.c" /* display controller routines */ + +/* INCLUDE VIDEO OVERLAY ROUTINES + * These routines control the video overlay hardware. + */ +#include "gfx_vid.c" /* video overlay routines */ + +/* VIDEO PORT AND VIDEO DECODER ROUTINES + * These routines rely on the I2C routines. + */ +#include "gfx_vip.c" /* video port routines */ +#include "gfx_dcdr.c" /* video decoder routines */ + +/* I2C BUS ACCESS ROUTINES + * These routines are used by the video decoder and possibly an + * external TV encoer. + */ +#include "gfx_i2c.c" /* I2C bus access routines */ + +/* TV ENCODER ROUTINES + * This file does not need to be included if the system does not + * support TV output. + */ +#include "gfx_tv.c" /* TV encoder routines */ + +/* VGA ROUTINES + * This file is used if setting display modes using VGA registers. + */ +#include "gfx_vga.c" /* VGA routines */ + +/* Hardware Register reading functions */ +#include "nsc_regacc.c" + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu1.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu1.c new file mode 100644 index 000000000..b17726410 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu1.c @@ -0,0 +1,2835 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu1.c,v 1.4 2003/02/06 17:46:02 alanh Exp $ */ +/* + * $Workfile: disp_gu1.c $ + * + * This file contains routines for the first generation display controller. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +void gu1_enable_compression(void); /* private routine definition */ +void gu1_disable_compression(void); /* private routine definition */ +void gfx_reset_video(void); /* private routine definition */ +int gfx_set_display_control(int sync_polarities); /* private routine definition */ +void gu1_delay_approximate(unsigned long milliseconds); +void gu1_delay_precise(unsigned long milliseconds); +int gu1_set_display_bpp(unsigned short bpp); +int gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz); +int gu1_set_display_mode(int xres, int yres, int bpp, int hz); +int gu1_set_display_timings(unsigned short bpp, unsigned short flags, + unsigned short hactive, + unsigned short hblank_start, + unsigned short hsync_start, + unsigned short hsync_end, + unsigned short hblank_end, unsigned short htotal, + unsigned short vactive, + unsigned short vblank_start, + unsigned short vsync_start, + unsigned short vsync_end, + unsigned short vblank_end, unsigned short vtotal, + unsigned long frequency); +int gu1_set_vtotal(unsigned short vtotal); +void gu1_set_display_pitch(unsigned short pitch); +void gu1_set_display_offset(unsigned long offset); +int gu1_set_display_palette_entry(unsigned long index, unsigned long palette); +int gu1_set_display_palette(unsigned long *palette); +void gu1_video_shutdown(void); +void gu1_set_clock_frequency(unsigned long frequency); +int gu1_set_crt_enable(int enable); +void gu1_set_cursor_enable(int enable); +void gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor); +void gu1_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, + unsigned short yhotspot); +void gu1_set_cursor_shape32(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask); +void gu1_set_cursor_shape64(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask); +void gu1_set_icon_enable(int enable); +void gu1_set_icon_colors(unsigned long color0, unsigned long color1, + unsigned long color2); +void gu1_set_icon_position(unsigned long memoffset, unsigned short xpos); +void gu1_set_icon_shape64(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask, unsigned int lines); + +int gu1_set_compression_enable(int enable); +int gu1_set_compression_offset(unsigned long offset); +int gu1_set_compression_pitch(unsigned short pitch); +int gu1_set_compression_size(unsigned short size); +void gu1_set_display_priority_high(int enable); +int gu1_test_timing_active(void); +int gu1_test_vertical_active(void); +int gu1_wait_vertical_blank(void); +void gu1_delay_milliseconds(unsigned long milliseconds); +void gu1_delay_microseconds(unsigned long microseconds); +void gu1_enable_panning(int x, int y); +int gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp); +int gu1_set_panel_present(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp); +void gu1_reset_timing_lock(void); + +int gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz); +unsigned short gu1_get_display_pitch(void); +int gu1_get_vsa2_softvga_enable(void); +int gu1_get_sync_polarities(void); +unsigned long gu1_get_clock_frequency(void); +unsigned long gu1_get_max_supported_pixel_clock(void); +int gu1_mode_frequency_supported(int xres, int yres, int bpp, + unsigned long frequency); +int gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, + unsigned long frequency); +int gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, + unsigned long frequency); +int gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, + int *frequency); +int gu1_get_display_mode_count(void); +int gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz); +unsigned long gu1_get_frame_buffer_line_size(void); +unsigned short gu1_get_hactive(void); +unsigned short gu1_get_hblank_start(void); +unsigned short gu1_get_hsync_start(void); +unsigned short gu1_get_hsync_end(void); +unsigned short gu1_get_hblank_end(void); +unsigned short gu1_get_htotal(void); +unsigned short gu1_get_vactive(void); +unsigned short gu1_get_vline(void); +unsigned short gu1_get_vblank_start(void); +unsigned short gu1_get_vsync_start(void); +unsigned short gu1_get_vsync_end(void); +unsigned short gu1_get_vblank_end(void); +unsigned short gu1_get_vtotal(void); +unsigned short gu1_get_display_bpp(void); +unsigned long gu1_get_display_offset(void); +int gu1_get_display_palette_entry(unsigned long index, + unsigned long *palette); +void gu1_get_display_palette(unsigned long *palette); +unsigned long gu1_get_cursor_enable(void); +unsigned long gu1_get_cursor_offset(void); +unsigned long gu1_get_cursor_position(void); +unsigned long gu1_get_cursor_clip(void); +unsigned long gu1_get_cursor_color(int color); +unsigned long gu1_get_icon_enable(void); +unsigned long gu1_get_icon_offset(void); +unsigned long gu1_get_icon_position(void); +unsigned long gu1_get_icon_color(int color); +int gu1_get_compression_enable(void); +unsigned long gu1_get_compression_offset(void); +unsigned short gu1_get_compression_pitch(void); +unsigned short gu1_get_compression_size(void); +int gu1_get_display_priority_high(void); +int gu1_get_valid_bit(int line); +void gu1_set_display_video_enable(int enable); +int gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp); +void gu1_set_display_video_size(unsigned short width, unsigned short height); +void gu1_set_display_video_offset(unsigned long offset); +unsigned long gu1_get_display_video_offset(void); +unsigned long gu1_get_display_video_size(void); + +/* VIDEO BUFFER SIZE */ + +unsigned long vid_buf_size = 0; +int vid_enabled = 0; + +/*----------------------------------------------------------------------------- + * GU1_DELAY_APPROXIMATE (PRIVATE ROUTINE - NOT PART OF DURANGO API) + * + * Delay the requested number of milliseconds by reading a register. This function + * generally takes longer than the requested time. + *-----------------------------------------------------------------------------*/ +void +gu1_delay_approximate(unsigned long milliseconds) +{ + /* ASSUME 300 MHz, 5 CLOCKS PER READ */ + +# define READS_PER_MILLISECOND 60000L + + unsigned long loop; + + loop = milliseconds * READS_PER_MILLISECOND; + while (loop-- > 0) { + READ_REG32(DC_UNLOCK); + } +} + +/*----------------------------------------------------------------------------- + * GU1_DELAY_PRECISE (PRIVATE ROUTINE - NOT PART OF DURANGO API) + * + * Delay the number of milliseconds on a more precise level, varying only by + * 1/10 of a ms. This function should only be called if an SC1200 is present. + *-----------------------------------------------------------------------------*/ +void +gu1_delay_precise(unsigned long milliseconds) +{ +#if GFX_VIDEO_SC1200 + +#define LOOP 1000 + unsigned long i, timer_start, timer_end, total_ticks, previous_ticks, + temp_ticks; + + /* Get current time */ + timer_start = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE); + + /* Calculate expected end time */ + if (INB(SC1200_CB_BASE_ADDR + SC1200_CB_TMCNFG) & SC1200_TMCLKSEL_27MHZ) + total_ticks = 27000 * milliseconds; /* timer resolution is 27 MHz */ + else + total_ticks = 1000 * milliseconds; /* timer resolution is 1 MHz */ + + if (total_ticks > ((unsigned long)0xffffffff - timer_start)) /* wrap-around */ + timer_end = total_ticks - ((unsigned long)0xffffffff - timer_start); + else + timer_end = timer_start + total_ticks; + + /* in case of wrap around */ + if (timer_end < timer_start) { + previous_ticks = timer_start; + while (1) { + temp_ticks = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE); + if (temp_ticks < previous_ticks) + break; + else + previous_ticks = temp_ticks; + for (i = 0; i < LOOP; i++) + READ_REG32(DC_UNLOCK); + } + } + /* now the non-wrap around part */ + while (1) { + for (i = 0; i < LOOP; i++) + READ_REG32(DC_UNLOCK); + if (IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE) > timer_end) + break; + } + +#endif /* GFX_VIDEO_SC1200 */ +} + +/*----------------------------------------------------------------------------- + * WARNING!!!! INACCURATE DELAY MECHANISM + * + * In an effort to keep the code self contained and operating system + * independent, the delay loop just performs reads of a display controller + * register. This time will vary for faster processors. The delay can always + * be longer than intended, only effecting the time of the mode switch + * (obviously want it to still be under a second). Problems with the hardware + * only arise if the delay is not long enough. + * + * For the SC1200, the high resolution timer can be used as an accurate mechanism + * for keeping time. However, in order to avoid a busy loop of IO reads, the + * timer is polled in-between busy loops, and therefore the actual delay might + * be longer than the requested delay by the time of one busy loop + * (which on a 200 MHz system took 95 us) + * + * There are thus two delay functions which are called from the main API routine. + * One is meant to be more precise and should only called if an SC1200 is present. + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_delay_milliseconds(unsigned long milliseconds) +#else +void +gfx_delay_milliseconds(unsigned long milliseconds) +#endif +{ +#if GFX_VIDEO_SC1200 + +#if GFX_VIDEO_DYNAMIC + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) { +#endif + gu1_delay_precise(milliseconds); + return; +#if GFX_VIDEO_DYNAMIC + } +#endif + +#endif /* GFX_VIDEO_SC1200 */ + + gu1_delay_approximate(milliseconds); +} + +#if GFX_DISPLAY_DYNAMIC +void +gu1_delay_microseconds(unsigned long microseconds) +#else +void +gfx_delay_microseconds(unsigned long microseconds) +#endif +{ + /* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */ + + unsigned long loop_count = microseconds * 150; + + while (loop_count-- > 0) { + ; + } +} + +/*----------------------------------------------------------------------------- + * GFX_VIDEO_SHUTDOWN + * + * This routine disables the display controller output. + *----------------------------------------------------------------------------- + */ +void +gu1_video_shutdown(void) +{ + unsigned long unlock; + unsigned long gcfg, tcfg; + + /* DISABLE COMPRESSION */ + + gu1_disable_compression(); + + /* ALSO DISABLE VIDEO */ + /* Use private "reset video" routine to do all that is needed. */ + /* SC1200, for example, also disables the alpha blending regions. */ + + gfx_reset_video(); + + /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ + + unlock = READ_REG32(DC_UNLOCK); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + + /* READ THE CURRENT GX VALUES */ + + gcfg = READ_REG32(DC_GENERAL_CFG); + tcfg = READ_REG32(DC_TIMING_CFG); + + /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */ + + tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN); + WRITE_REG32(DC_TIMING_CFG, tcfg); + + /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */ + /* This delay is used to make sure that all pending requests to the */ + /* memory controller have completed before disabling the FIFO load. */ + + gfx_delay_milliseconds(1); + + /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */ + + gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); + WRITE_REG32(DC_GENERAL_CFG, gcfg); + WRITE_REG32(DC_UNLOCK, unlock); + return; +} + +/*----------------------------------------------------------------------------- + * GFX_SET_DISPLAY_BPP + * + * This routine programs the bpp in the display controller. + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_display_bpp(unsigned short bpp) +#else +int +gfx_set_display_bpp(unsigned short bpp) +#endif +{ + unsigned long ocfg, lock; + + lock = READ_REG32(DC_UNLOCK); + ocfg = READ_REG32(DC_OUTPUT_CFG) & ~(DC_OCFG_8BPP | DC_OCFG_555); + + /* SET DC PIXEL FORMAT */ + + if (bpp == 8) + ocfg |= DC_OCFG_8BPP; + else if (bpp == 15) + ocfg |= DC_OCFG_555; + else if (bpp != 16) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_OUTPUT_CFG, ocfg); + WRITE_REG32(DC_UNLOCK, lock); + + /* SET BPP IN GRAPHICS PIPELINE */ + + gfx_set_bpp(bpp); + + return 0; +} + +/*----------------------------------------------------------------------------- + * GFX_SET_SPECIFIED_MODE + * This routine uses the parameters in the specified display mode structure + * to program the display controller hardware. + *----------------------------------------------------------------------------- + */ +int +gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp) +{ + unsigned long unlock, value; + unsigned long gcfg, tcfg, ocfg; + unsigned long size, pitch; + unsigned long vid_buffer_size; + unsigned long hactive, vactive; + + gbpp = bpp; + + /* CHECK WHETHER TIMING CHANGE IS ALLOWED */ + /* Flag used for locking also overrides timing change restriction */ + + if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING)) + return GFX_STATUS_ERROR; + + /* SET GLOBAL FLAG */ + + if (pMode->flags & GFX_MODE_LOCK_TIMING) + gfx_timing_lock = 1; + + /* DISABLE COMPRESSION */ + + gu1_disable_compression(); + + /* ALSO DISABLE VIDEO */ + /* Use private "reset video" routine to do all that is needed. */ + /* SC1200, for example, also disables the alpha blending regions. */ + + gfx_reset_video(); + + /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ + + unlock = READ_REG32(DC_UNLOCK); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + + /* READ THE CURRENT GX VALUES */ + + gcfg = READ_REG32(DC_GENERAL_CFG); + tcfg = READ_REG32(DC_TIMING_CFG); + + /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */ + + tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN); + WRITE_REG32(DC_TIMING_CFG, tcfg); + + /* DELAY: WAIT FOR PENDING MEMORY REQUESTS + * This delay is used to make sure that all pending requests to the + * memory controller have completed before disabling the FIFO load. + */ + + gfx_delay_milliseconds(1); + + /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */ + + gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); + WRITE_REG32(DC_GENERAL_CFG, gcfg); + + /* CLEAR THE "DCLK_MUL" FIELD */ + + gcfg &= ~(unsigned long)(DC_GCFG_DDCK | DC_GCFG_DPCK | DC_GCFG_DFCK); + gcfg &= ~(unsigned long)DC_GCFG_DCLK_MASK; + WRITE_REG32(DC_GENERAL_CFG, gcfg); + + /* SET THE DOT CLOCK FREQUENCY */ + /* Mask off the divide by two bit (bit 31) */ + + gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF); + + /* DELAY: WAIT FOR THE PLL TO SETTLE */ + /* This allows the dot clock frequency that was just set to settle. */ + + gfx_delay_milliseconds(1); + + /* SET THE "DCLK_MUL" FIELD OF DC_GENERAL_CFG */ + /* The GX hardware divides the dot clock, so 2x really means that the */ + /* internal dot clock equals the external dot clock. */ + + if (pMode->frequency & 0x80000000) + gcfg |= 0x0040; + else + gcfg |= 0x0080; + WRITE_REG32(DC_GENERAL_CFG, gcfg); + + /* DELAY: WAIT FOR THE ADL TO LOCK */ + /* This allows the clock generatation within GX to settle. This is */ + /* needed since some of the register writes that follow require that */ + /* clock to be present. */ + + /* We do a few to ensure we're synced */ + gfx_delay_milliseconds(1); + gfx_delay_milliseconds(1); + gfx_delay_milliseconds(1); + gfx_delay_milliseconds(1); + gfx_delay_milliseconds(1); + gfx_delay_milliseconds(1); + + /* SET THE GX DISPLAY CONTROLLER PARAMETERS */ + + WRITE_REG32(DC_FB_ST_OFFSET, 0); + WRITE_REG32(DC_CB_ST_OFFSET, 0); + WRITE_REG32(DC_CURS_ST_OFFSET, 0); + + /* SET LINE SIZE AND PITCH */ + /* Flat panels use the current flat panel line size to */ + /* calculate the pitch, but load the true line size */ + /* for the mode into the "Frame Buffer Line Size" field */ + /* of DC_BUF_SIZE. */ + + if (PanelEnable) + size = ModeWidth; + else + size = pMode->hactive; + + if (bpp > 8) + size <<= 1; + + /* ONLY PYRAMID SUPPORTS 4K LINE SIZE */ + + if (size <= 1024) { + pitch = 1024; + + /* SPECIAL CASE */ + /* Graphics acceleration in 16-bit pixel line double modes */ + /* requires a pitch of 2048. */ + + if ((pMode->flags & GFX_MODE_LINE_DOUBLE) && bpp > 8) + pitch <<= 1; + } else { + if (gfx_cpu_version == GFX_CPU_PYRAMID) + pitch = (size <= 2048) ? 2048 : 4096; + else + pitch = 2048; + } + WRITE_REG32(DC_LINE_DELTA, pitch >> 2); + + if (PanelEnable) { + size = pMode->hactive; + if (bpp > 8) + size <<= 1; + } + + /* SAVE PREVIOUSLY STORED VIDEO BUFFER SIZE */ + + vid_buffer_size = READ_REG32(DC_BUF_SIZE) & 0x3FFF0000; + + /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */ + + WRITE_REG32(DC_BUF_SIZE, ((size >> 3) + 2) | vid_buffer_size); + + /* ALWAYS ENABLE "PANEL" DATA FROM MEDIAGX */ + /* That is really just the 18 BPP data bus to the companion chip */ + + ocfg = DC_OCFG_PCKE | DC_OCFG_PDEL | DC_OCFG_PDEH; + + /* SET PIXEL FORMAT */ + + if (bpp == 8) + ocfg |= DC_OCFG_8BPP; + else if (bpp == 15) + ocfg |= DC_OCFG_555; + + /* ENABLE TIMING GENERATOR, SYNCS, AND FP DATA */ + + tcfg = DC_TCFG_FPPE | DC_TCFG_HSYE | DC_TCFG_VSYE | DC_TCFG_BLKE | + DC_TCFG_TGEN; + + /* SET FIFO PRIORITY, DCLK MULTIPLIER, AND FIFO ENABLE */ + /* Default 6/5 for FIFO, 2x for DCLK multiplier. */ + + gcfg = (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | + DC_GCFG_DFLE; + + /* INCREASE FIFO PRIORITY FOR LARGE MODES */ + + if (pMode->hactive == 1280 && pMode->vactive == 1024) { + if ((bpp == 8) && (pMode->flags & GFX_MODE_85HZ)) + gcfg = (8l << DC_GCFG_DFHPEL_POS) | (7l << DC_GCFG_DFHPSL_POS) | + DC_GCFG_DFLE; + if ((bpp > 8) && (pMode->flags & GFX_MODE_75HZ)) + gcfg = (7l << DC_GCFG_DFHPEL_POS) | (6l << DC_GCFG_DFHPSL_POS) | + DC_GCFG_DFLE; + if ((bpp > 8) && (pMode->flags & GFX_MODE_85HZ)) + gcfg = (9l << DC_GCFG_DFHPEL_POS) | (8l << DC_GCFG_DFHPSL_POS) | + DC_GCFG_DFLE; + } + + /* SET DOT CLOCK MULTIPLIER */ + /* Bit 31 of frequency indicates divide frequency by two */ + + if (pMode->frequency & 0x80000000) + gcfg |= (1l << DC_GCFG_DCLK_POS); + else + gcfg |= (2l << DC_GCFG_DCLK_POS); + + /* DIVIDE VIDEO CLOCK */ + /* CPU core frequencies above 266 MHz will divide the video */ + /* clock by 4 to ensure that we are running below 150 MHz. */ + + if (gfx_cpu_frequency > 266) + gcfg |= DC_GCFG_VCLK_DIV; + + /* SET THE PIXEL AND LINE DOUBLE BITS IF NECESSARY */ + + hactive = pMode->hactive; + vactive = pMode->vactive; + gfx_line_double = 0; + gfx_pixel_double = 0; + + if (pMode->flags & GFX_MODE_LINE_DOUBLE) { + gcfg |= DC_GCFG_LDBL; + hactive <<= 1; + + /* SET GLOBAL FLAG */ + + gfx_line_double = 1; + } + + if (pMode->flags & GFX_MODE_PIXEL_DOUBLE) { + tcfg |= DC_TCFG_PXDB; + vactive <<= 1; + + /* SET GLOBAL FLAG */ + + gfx_pixel_double = 1; + } + + /* COMBINE AND SET TIMING VALUES */ + + value = (unsigned long)(hactive - 1) | + (((unsigned long)(pMode->htotal - 1)) << 16); + WRITE_REG32(DC_H_TIMING_1, value); + value = (unsigned long)(pMode->hblankstart - 1) | + (((unsigned long)(pMode->hblankend - 1)) << 16); + WRITE_REG32(DC_H_TIMING_2, value); + value = (unsigned long)(pMode->hsyncstart - 1) | + (((unsigned long)(pMode->hsyncend - 1)) << 16); + WRITE_REG32(DC_H_TIMING_3, value); + WRITE_REG32(DC_FP_H_TIMING, value); + value = (unsigned long)(vactive - 1) | + (((unsigned long)(pMode->vtotal - 1)) << 16); + WRITE_REG32(DC_V_TIMING_1, value); + value = (unsigned long)(pMode->vblankstart - 1) | + (((unsigned long)(pMode->vblankend - 1)) << 16); + WRITE_REG32(DC_V_TIMING_2, value); + value = (unsigned long)(pMode->vsyncstart - 1) | + (((unsigned long)(pMode->vsyncend - 1)) << 16); + WRITE_REG32(DC_V_TIMING_3, value); + value = (unsigned long)(pMode->vsyncstart - 2) | + (((unsigned long)(pMode->vsyncend - 2)) << 16); + WRITE_REG32(DC_FP_V_TIMING, value); + + WRITE_REG32(DC_OUTPUT_CFG, ocfg); + WRITE_REG32(DC_TIMING_CFG, tcfg); + gfx_delay_milliseconds(1); /* delay after TIMING_CFG */ + WRITE_REG32(DC_GENERAL_CFG, gcfg); + + /* ENABLE FLAT PANEL CENTERING */ + /* For 640x480 modes displayed with the 9211 within a 800x600 */ + /* flat panel display, turn on flat panel centering. */ + + if (PanelEnable) { + if (ModeWidth < PanelWidth) { + tcfg = READ_REG32(DC_TIMING_CFG); + tcfg = tcfg | DC_TCFG_FCEN; + WRITE_REG32(DC_TIMING_CFG, tcfg); + gfx_delay_milliseconds(1); /* delay after TIMING_CFG */ + } + } + + /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */ + + gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) | + ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0)); + + /* RESTORE VALUE OF DC_UNLOCK */ + + WRITE_REG32(DC_UNLOCK, unlock); + + /* ALSO WRITE GP_BLIT_STATUS FOR PITCH AND 8/18 BPP */ + /* Remember, only Pyramid supports 4K line pitch */ + + value = 0; + if (bpp > 8) + value |= BC_16BPP; + if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) + value |= BC_FB_WIDTH_4096; + else if (pitch > 1024) + value |= BC_FB_WIDTH_2048; + WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value); + + return GFX_STATUS_OK; + +} /* end gfx_set_specified_mode() */ + +/*---------------------------------------------------------------------------- + * GFX_IS_DISPLAY_MODE_SUPPORTED + * + * This routine sets the specified display mode. + * + * Returns the index of the mode if successful and mode returned, -1 if the mode + * could not be found. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz) +#else +int +gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz) +#endif +{ + unsigned int mode = 0; + unsigned long hz_flag = 0, bpp_flag = 0; + + /* SET FLAGS TO MATCH REFRESH RATE */ + + if (hz == 56) + hz_flag = GFX_MODE_56HZ; + else if (hz == 60) + hz_flag = GFX_MODE_60HZ; + else if (hz == 70) + hz_flag = GFX_MODE_70HZ; + else if (hz == 72) + hz_flag = GFX_MODE_72HZ; + else if (hz == 75) + hz_flag = GFX_MODE_75HZ; + else if (hz == 85) + hz_flag = GFX_MODE_85HZ; + else + return -1; + + /* SET BPP FLAGS TO LIMIT MODE SELECTION */ + + if (bpp == 8) + bpp_flag = GFX_MODE_8BPP; + else if (bpp == 15) + bpp_flag = GFX_MODE_15BPP; + else if (bpp == 16) + bpp_flag = GFX_MODE_16BPP; + else + return -1; + + /* ONLY PYRAMID SUPPORTS 4K PITCH */ + + if (gfx_cpu_version != GFX_CPU_PYRAMID && xres > 1024) { + if (bpp > 8) + return (-1); /* return with mode not found */ + } + + /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ + + for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) { + if ((DisplayParams[mode].hactive == (unsigned short)xres) && + (DisplayParams[mode].vactive == (unsigned short)yres) && + (DisplayParams[mode].flags & hz_flag) && + (DisplayParams[mode].flags & bpp_flag)) { + + /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */ + + return (mode); + } + } + return (-1); +} + +/*---------------------------------------------------------------------------- + * GFX_SET_DISPLAY_MODE + * + * This routine sets the specified display mode. + * + * Returns 1 if successful, 0 if mode could not be set. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_display_mode(int xres, int yres, int bpp, int hz) +#else +int +gfx_set_display_mode(int xres, int yres, int bpp, int hz) +#endif +{ + int mode; + + /* DISABLE FLAT PANEL */ + /* Flat Panel settings are enabled by the function gfx_set_fixed_timings */ + /* and disabled by gfx_set_display_mode. */ + + PanelEnable = 0; + + mode = gfx_is_display_mode_supported(xres, yres, bpp, hz); + if (mode >= 0) { + if (gu1_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK) + return (1); + } + return (0); +} + +/*---------------------------------------------------------------------------- + * GFX_SET_DISPLAY_TIMINGS + * + * This routine sets the display controller mode using the specified timing + * values (as opposed to using the tables internal to Durango). + * + * Returns GFX_STATUS_OK on success, GFX_STATUS_ERROR otherwise. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_display_timings(unsigned short bpp, unsigned short flags, + unsigned short hactive, unsigned short hblankstart, + unsigned short hsyncstart, unsigned short hsyncend, + unsigned short hblankend, unsigned short htotal, + unsigned short vactive, unsigned short vblankstart, + unsigned short vsyncstart, unsigned short vsyncend, + unsigned short vblankend, unsigned short vtotal, + unsigned long frequency) +#else +int +gfx_set_display_timings(unsigned short bpp, unsigned short flags, + unsigned short hactive, unsigned short hblankstart, + unsigned short hsyncstart, unsigned short hsyncend, + unsigned short hblankend, unsigned short htotal, + unsigned short vactive, unsigned short vblankstart, + unsigned short vsyncstart, unsigned short vsyncend, + unsigned short vblankend, unsigned short vtotal, + unsigned long frequency) +#endif +{ + /* SET MODE STRUCTURE WITH SPECIFIED VALUES */ + + gfx_display_mode.flags = 0; + if (flags & 1) + gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC; + if (flags & 2) + gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC; + if (flags & 0x1000) + gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING; + gfx_display_mode.hactive = hactive; + gfx_display_mode.hblankstart = hblankstart; + gfx_display_mode.hsyncstart = hsyncstart; + gfx_display_mode.hsyncend = hsyncend; + gfx_display_mode.hblankend = hblankend; + gfx_display_mode.htotal = htotal; + gfx_display_mode.vactive = vactive; + gfx_display_mode.vblankstart = vblankstart; + gfx_display_mode.vsyncstart = vsyncstart; + gfx_display_mode.vsyncend = vsyncend; + gfx_display_mode.vblankend = vblankend; + gfx_display_mode.vtotal = vtotal; + gfx_display_mode.frequency = frequency; + + /* CALL ROUTINE TO SET MODE */ + + return (gu1_set_specified_mode(&gfx_display_mode, bpp)); +} + +/*---------------------------------------------------------------------------- + * GFX_SET_VTOTAL + * + * This routine sets the display controller vertical total to + * "vtotal". As a side effect it also sets vertical blank end. + * It should be used when only this value needs to be changed, + * due to speed considerations. + * + * Note: it is the caller's responsibility to make sure that + * a legal vtotal is used, i.e. that "vtotal" is greater than or + * equal to vsync end. + * + * Always returns 0. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_vtotal(unsigned short vtotal) +#else +int +gfx_set_vtotal(unsigned short vtotal) +#endif +{ + unsigned long unlock, tcfg, timing1, timing2; + + /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ + + unlock = READ_REG32(DC_UNLOCK); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + + /* READ THE CURRENT GX VALUES */ + + tcfg = READ_REG32(DC_TIMING_CFG); + timing1 = READ_REG32(DC_V_TIMING_1); + timing2 = READ_REG32(DC_V_TIMING_2); + + /* DISABLE THE TIMING GENERATOR */ + + WRITE_REG32(DC_TIMING_CFG, tcfg & ~(unsigned long)DC_TCFG_TGEN); + + /* WRITE NEW TIMING VALUES */ + + WRITE_REG32(DC_V_TIMING_1, + (timing1 & 0xffff) | (unsigned long)(vtotal - 1) << 16); + WRITE_REG32(DC_V_TIMING_2, + (timing2 & 0xffff) | (unsigned long)(vtotal - 1) << 16); + + /* RESTORE GX VALUES */ + + WRITE_REG32(DC_TIMING_CFG, tcfg); + WRITE_REG32(DC_UNLOCK, unlock); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_pitch + * + * This routine sets the pitch of the frame buffer to the specified value. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_display_pitch(unsigned short pitch) +#else +void +gfx_set_display_pitch(unsigned short pitch) +#endif +{ + unsigned long value = 0; + unsigned long lock = READ_REG32(DC_UNLOCK); + + value = READ_REG32(DC_LINE_DELTA) & 0xFFFFF000; + value |= (pitch >> 2); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_LINE_DELTA, value); + WRITE_REG32(DC_UNLOCK, lock); + + /* ALSO UPDATE PITCH IN GRAPHICS ENGINE */ + /* Pyramid alone supports 4K line pitch */ + + value = (unsigned long)READ_REG16(GP_BLIT_STATUS); + value &= ~(BC_FB_WIDTH_2048 | BC_FB_WIDTH_4096); + + if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) + value |= BC_FB_WIDTH_4096; + + else if (pitch > 1024) + value |= BC_FB_WIDTH_2048; + + WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value); + return; +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_offset + * + * This routine sets the start address of the frame buffer. It is + * typically used to pan across a virtual desktop (frame buffer larger than + * the displayed screen) or to flip the display between multiple buffers. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_display_offset(unsigned long offset) +#else +void +gfx_set_display_offset(unsigned long offset) +#endif +{ + /* UPDATE FRAME BUFFER OFFSET */ + + unsigned long lock; + + lock = READ_REG32(DC_UNLOCK); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + + /* START ADDRESS EFFECTS DISPLAY COMPRESSION */ + /* Disable compression for non-zero start addresss values. */ + /* Enable compression if offset is zero and comression is intended to */ + /* be enabled from a previous call to "gfx_set_compression_enable". */ + /* Compression should be disabled BEFORE the offset is changed */ + /* and enabled AFTER the offset is changed. */ + + if (offset == 0) { + WRITE_REG32(DC_FB_ST_OFFSET, offset); + if (gfx_compression_enabled) { + /* WAIT FOR THE OFFSET TO BE LATCHED */ + gfx_wait_vertical_blank(); + gu1_enable_compression(); + } + } else { + /* ONLY DISABLE COMPRESSION ONCE */ + + if (gfx_compression_active) + gu1_disable_compression(); + + WRITE_REG32(DC_FB_ST_OFFSET, offset); + } + + WRITE_REG32(DC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_palette_entry + * + * This routine sets an palette entry in the display controller. + * A 32-bit X:R:G:B value. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_display_palette_entry(unsigned long index, unsigned long palette) +#else +int +gfx_set_display_palette_entry(unsigned long index, unsigned long palette) +#endif +{ + unsigned long data; + + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_REG32(DC_PAL_ADDRESS, index); + data = ((palette >> 2) & 0x0003F) | + ((palette >> 4) & 0x00FC0) | ((palette >> 6) & 0x3F000); + WRITE_REG32(DC_PAL_DATA, data); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_palette + * + * This routine sets the entire palette in the display controller. + * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values. + * Restriction: + * Due to SC1200 Issue #748 (in Notes DB) this function should be called only + * when DCLK is active, i.e PLL is already powered up and genlock is not active. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_display_palette(unsigned long *palette) +#else +int +gfx_set_display_palette(unsigned long *palette) +#endif +{ + unsigned long data, i; + + WRITE_REG32(DC_PAL_ADDRESS, 0); + if (palette) { + for (i = 0; i < 256; i++) { + /* CONVERT 24 BPP COLOR DATA TO 18 BPP COLOR DATA */ + + data = ((palette[i] >> 2) & 0x0003F) | + ((palette[i] >> 4) & 0x00FC0) | ((palette[i] >> 6) & 0x3F000); + WRITE_REG32(DC_PAL_DATA, data); + } + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_enable + * + * This routine enables or disables the hardware cursor. + * + * WARNING: The cusrsor start offset must be set by setting the cursor + * position before calling this routine to assure that memory reads do not + * go past the end of graphics memory (this can hang GXm). + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_cursor_enable(int enable) +#else +void +gfx_set_cursor_enable(int enable) +#endif +{ + unsigned long unlock, gcfg; + + /* SET OR CLEAR CURSOR ENABLE BIT */ + + unlock = READ_REG32(DC_UNLOCK); + gcfg = READ_REG32(DC_GENERAL_CFG); + if (enable) + gcfg |= DC_GCFG_CURE; + else + gcfg &= ~(DC_GCFG_CURE); + + /* WRITE NEW REGISTER VALUE */ + + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_GENERAL_CFG, gcfg); + WRITE_REG32(DC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_colors + * + * This routine sets the colors of the hardware cursor. + * Restriction: + * Due to SC1200 Issue #748 (in Notes DB) this function should be called only + * when DCLK is active, i.e PLL is already powered up. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) +#else +void +gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) +#endif +{ + unsigned long value; + + /* If genlock is enabled DCLK might be disabled in vertical blank. */ + /* Due to SC1200 Issue #748 in Notes DB this would fail the cursor color settings */ + /* So Wait for vertical blank to end */ + +#if GFX_VIDEO_SC1200 + if (gfx_test_timing_active()) + while ((gfx_get_vline()) > gfx_get_vactive()) ; +#endif + + /* SET CURSOR COLORS */ + + WRITE_REG32(DC_PAL_ADDRESS, 0x100); + value = ((bkcolor & 0x000000FC) >> 2) | + ((bkcolor & 0x0000FC00) >> (2 + 8 - 6)) | + ((bkcolor & 0x00FC0000) >> (2 + 16 - 12)); + WRITE_REG32(DC_PAL_DATA, value); + value = ((fgcolor & 0x000000FC) >> 2) | + ((fgcolor & 0x0000FC00) >> (2 + 8 - 6)) | + ((fgcolor & 0x00FC0000) >> (2 + 16 - 12)); + WRITE_REG32(DC_PAL_DATA, value); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_position + * + * This routine sets the position of the hardware cusror. The starting + * offset of the cursor buffer must be specified so that the routine can + * properly clip scanlines if the cursor is off the top of the screen. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, unsigned short yhotspot) +#else +void +gfx_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, unsigned short yhotspot) +#endif +{ + unsigned long unlock; + + short x, y; + short xoffset = 0; + short yoffset = 0; + + /* SUPPORT CURSOR IN EMULATED VGA MODES */ + /* Timings are for twice the resolution */ + + if (gfx_pixel_double) + xpos <<= 1; + if (gfx_line_double) + ypos <<= 1; + + x = (short)xpos - (short)xhotspot; + y = (short)ypos - (short)yhotspot; + if (x < -31) + return; + if (y < -31) + return; + if (x < 0) { + xoffset = -x; + x = 0; + } + if (y < 0) { + yoffset = -y; + y = 0; + } + memoffset += (unsigned long)yoffset << 3; + + if (PanelEnable) { + if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) { + gfx_enable_panning(xpos, ypos); + x = x - (short)panelLeft; + y = y - (short)panelTop; + } + } + + /* SET CURSOR POSITION */ + + unlock = READ_REG32(DC_UNLOCK); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_CURS_ST_OFFSET, memoffset); + WRITE_REG32(DC_CURSOR_X, (unsigned long)x | + (((unsigned long)xoffset) << 11)); + WRITE_REG32(DC_CURSOR_Y, (unsigned long)y | + (((unsigned long)yoffset) << 11)); + WRITE_REG32(DC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_shape32 + * + * This routine loads 32x32 cursor data into the specified location in + * graphics memory. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_cursor_shape32(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +#else +void +gfx_set_cursor_shape32(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +#endif +{ + int i; + unsigned long value; + + for (i = 0; i < 32; i++) { + /* CONVERT TO 16 BITS AND MASK, 16 BITS XOR MASK PER DWORD */ + + value = (andmask[i] & 0xFFFF0000) | (xormask[i] >> 16); + WRITE_FB32(memoffset, value); + memoffset += 4; + value = (andmask[i] << 16) | (xormask[i] & 0x0000FFFF); + WRITE_FB32(memoffset, value); + memoffset += 4; + } +} + +/*--------------------------------------------------------------------------- + * gu1_enable_compression + * + * This is a private routine to this module (not exposed in the Durango API). + * It enables display compression. + *--------------------------------------------------------------------------- + */ +void +gu1_enable_compression(void) +{ + int i; + unsigned long unlock, gcfg, offset; + + /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */ + + offset = READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF; + if (offset != 0) + return; + + /* DO NOT ENABLE IF WE ARE WITHIN AN EMULATED VGA MODE */ + + if (gfx_line_double || gfx_pixel_double) + return; + + /* SET GLOBAL INDICATOR */ + + gfx_compression_active = 1; + + /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */ + /* Software is required to do this before enabling compression. */ + /* Don't want controller to think that old lines are still valid. */ + + for (i = 0; i < 1024; i++) { + WRITE_REG32(MC_DR_ADD, i); + WRITE_REG32(MC_DR_ACC, 0); + } + + /* TURN ON COMPRESSION CONTROL BITS */ + + unlock = READ_REG32(DC_UNLOCK); + gcfg = READ_REG32(DC_GENERAL_CFG); + gcfg |= DC_GCFG_CMPE | DC_GCFG_DECE; + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_GENERAL_CFG, gcfg); + WRITE_REG32(DC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gu1_disable_compression + * + * This is a private routine to this module (not exposed in the Durango API). + * It disables display compression. + *--------------------------------------------------------------------------- + */ +void +gu1_disable_compression(void) +{ + unsigned long unlock, gcfg; + + /* SET GLOBAL INDICATOR */ + + gfx_compression_active = 0; + + /* TURN OFF COMPRESSION CONTROL BITS */ + + unlock = READ_REG32(DC_UNLOCK); + gcfg = READ_REG32(DC_GENERAL_CFG); + gcfg &= ~(DC_GCFG_CMPE | DC_GCFG_DECE); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_GENERAL_CFG, gcfg); + WRITE_REG32(DC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_enable + * + * This routine enables or disables display compression. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_compression_enable(int enable) +#else +int +gfx_set_compression_enable(int enable) +#endif +{ + /* SET GLOBAL VARIABLE FOR INTENDED STATE */ + /* Compression can only be enabled for non-zero start address values. */ + /* Keep state to enable compression on start address changes. */ + + gfx_compression_enabled = enable; + if (enable) + gu1_enable_compression(); + else + gu1_disable_compression(); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_offset + * + * This routine sets the base offset for the compression buffer. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_compression_offset(unsigned long offset) +#else +int +gfx_set_compression_offset(unsigned long offset) +#endif +{ + unsigned long lock; + + /* MUST BE 16-BYTE ALIGNED FOR GXLV */ + + if (offset & 0x0F) + return (1); + + /* SET REGISTER VALUE */ + + lock = READ_REG32(DC_UNLOCK); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_CB_ST_OFFSET, offset); + WRITE_REG32(DC_UNLOCK, lock); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_pitch + * + * This routine sets the pitch, in bytes, of the compression buffer. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_compression_pitch(unsigned short pitch) +#else +int +gfx_set_compression_pitch(unsigned short pitch) +#endif +{ + unsigned long lock, line_delta; + + /* SET REGISTER VALUE */ + + lock = READ_REG32(DC_UNLOCK); + line_delta = READ_REG32(DC_LINE_DELTA) & 0xFF800FFF; + line_delta |= ((unsigned long)pitch << 10l) & 0x007FF000; + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_LINE_DELTA, line_delta); + WRITE_REG32(DC_UNLOCK, lock); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_size + * + * This routine sets the line size of the compression buffer, which is the + * maximum number of bytes allowed to store a compressed line. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_compression_size(unsigned short size) +#else +int +gfx_set_compression_size(unsigned short size) +#endif +{ + unsigned long lock, buf_size; + + /* SUBTRACT 16 FROM SIZE */ + /* The display controller will actually write */ + /* 2 extra QWords. So, if we assume that "size" */ + /* refers to the allocated size, we must subtract */ + /* 16 bytes. */ + + size -= 16; + + /* SET REGISTER VALUE */ + + lock = READ_REG32(DC_UNLOCK); + buf_size = READ_REG32(DC_BUF_SIZE) & 0xFFFF01FF; + buf_size |= (((size >> 2) + 1) & 0x7F) << 9; + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + WRITE_REG32(DC_BUF_SIZE, buf_size); + WRITE_REG32(DC_UNLOCK, lock); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine enables/disables video on GX. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_display_video_enable(int enable) +#else +void +gfx_set_display_video_enable(int enable) +#endif +{ + unsigned long lock, gcfg, buf_size; + + lock = READ_REG32(DC_UNLOCK); + gcfg = READ_REG32(DC_GENERAL_CFG); + buf_size = READ_REG32(DC_BUF_SIZE); + + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + + vid_enabled = enable; + + /* SET THE BUFFER SIZE TO A NON-ZERO VALUE ONLY WHEN */ + /* ENABLING VIDEO */ + + if (enable) { + gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY); + WRITE_REG32(DC_GENERAL_CFG, gcfg); + + WRITE_REG32(DC_BUF_SIZE, (buf_size & 0x0000FFFFl) | vid_buf_size); + } + + /* CLEAR THE VIDEO BUFFER SIZE WHEN DISABLING VIDEO */ + + else { + gcfg &= ~(DC_GCFG_VIDE); + WRITE_REG32(DC_GENERAL_CFG, gcfg); + + vid_buf_size = buf_size & 0xFFFF0000l; + WRITE_REG32(DC_BUF_SIZE, buf_size & 0x0000FFFFl); + } + + WRITE_REG32(DC_UNLOCK, lock); + return; +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_size". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_display_video_size(unsigned short width, unsigned short height) +#else +void +gfx_set_display_video_size(unsigned short width, unsigned short height) +#endif +{ + unsigned long lock, size, value; + + size = (unsigned long)(width << 1) * (unsigned long)height; + + /* STORE THE VIDEO BUFFER SIZE AS A GLOBAL */ + + vid_buf_size = ((size + 63) >> 6) << 16; + + /* DO NOT SET THE VIDEO SIZE IF VIDEO IS DISABLED */ + + if (!vid_enabled) + return; + + lock = READ_REG32(DC_UNLOCK); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + value = READ_REG32(DC_BUF_SIZE) & 0x0000FFFF; + value |= vid_buf_size; + WRITE_REG32(DC_BUF_SIZE, value); + WRITE_REG32(DC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_offset". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_display_video_offset(unsigned long offset) +#else +void +gfx_set_display_video_offset(unsigned long offset) +#endif +{ + unsigned long lock; + + lock = READ_REG32(DC_UNLOCK); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + offset &= 0x003FFFFF; + WRITE_REG32(DC_VID_ST_OFFSET, offset); + WRITE_REG32(DC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_priority_high + * + * This routine controls the x-bus round robin arbitration mechanism. + * When enable is TRUE, graphics pipeline requests and non-critical display + * controller requests are arbitrated at the same priority as processor + * requests. When FALSE processor requests are arbitrated at a higher priority. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_set_display_priority_high(int enable) +#else +void +gfx_set_display_priority_high(int enable) +#endif +{ + unsigned long lock, control; + + lock = READ_REG32(DC_UNLOCK); + control = READ_REG32(MC_MEM_CNTRL1); + WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); + if (enable) + control |= MC_XBUSARB; + else + control &= ~(MC_XBUSARB); + WRITE_REG32(MC_MEM_CNTRL1, control); + WRITE_REG32(DC_UNLOCK, lock); + return; +} + +/*--------------------------------------------------------------------------- + * gfx_test_timing_active + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_test_timing_active(void) +#else +int +gfx_test_timing_active(void) +#endif +{ + if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_TGEN) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_test_vertical_active + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_test_vertical_active(void) +#else +int +gfx_test_vertical_active(void) +#endif +{ + if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_VNA) + return (0); + else + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_wait_vertical_blank + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_wait_vertical_blank(void) +#else +int +gfx_wait_vertical_blank(void) +#endif +{ + if (gfx_test_timing_active()) { + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_enable_panning + * + * This routine enables the panning when the Mode is bigger than the panel + * size. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_enable_panning(int x, int y) +#else +void +gfx_enable_panning(int x, int y) +#endif +{ + unsigned long modeBytesPerPixel; + unsigned long modeBytesPerScanline = 0; + unsigned long startAddress = 0; + + modeBytesPerPixel = (gbpp + 7) / 8; + modeBytesPerScanline = + (((ModeWidth + 1023) / 1024) * 1024) * modeBytesPerPixel; + + /* TEST FOR NO-WORK */ + + if (x >= DeltaX && (unsigned short)x < (PanelWidth + DeltaX) && + y >= DeltaY && (unsigned short)y < (PanelHeight + DeltaY)) + return; + + /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */ + /* Test the boundary conditions for each coordinate and update */ + /* all variables and the starting offset accordingly. */ + + if (x < DeltaX) + DeltaX = x; + + else if ((unsigned short)x >= (DeltaX + PanelWidth)) + DeltaX = x - PanelWidth + 1; + + if (y < DeltaY) + DeltaY = y; + + else if ((unsigned short)y >= (DeltaY + PanelHeight)) + DeltaY = y - PanelHeight + 1; + + /* CALCULATE THE START OFFSET */ + + startAddress = + (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline); + + gfx_set_display_offset(startAddress); + + /* SET PANEL COORDINATES */ + /* Panel's x position must be DWORD aligned */ + + panelTop = DeltaY; + panelLeft = DeltaX * modeBytesPerPixel; + + if (panelLeft & 3) + panelLeft = (panelLeft & 0xFFFFFFFC) + 4; + + panelLeft /= modeBytesPerPixel; + +} + +/*--------------------------------------------------------------------------- + * gfx_set_fixed_timings + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +#else +int +gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +#endif +{ + unsigned int mode; + + ModeWidth = width; + ModeHeight = height; + PanelWidth = (unsigned short)panelResX; + PanelHeight = (unsigned short)panelResY; + PanelEnable = 1; + + /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ + for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) { + if ((FixedParams[mode].xres == width) && + (FixedParams[mode].yres == height) && + (FixedParams[mode].panelresx == panelResX) && + (FixedParams[mode].panelresy == panelResY)) { + + /* SET THE 92xx FOR THE SELECTED MODE */ + FIXEDTIMINGS *fmode = &FixedParams[mode]; + + gfx_set_display_timings(bpp, 3, fmode->hactive, fmode->hblankstart, + fmode->hsyncstart, fmode->hsyncend, + fmode->hblankend, fmode->htotal, + fmode->vactive, fmode->vblankstart, + fmode->vsyncstart, fmode->vsyncend, + fmode->vblankend, fmode->vtotal, + fmode->frequency); + + return (1); + } /* end if() */ + } /* end for() */ + + return (-1); +} + +/*--------------------------------------------------------------------------- + * gfx_set_panel_present + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_set_panel_present(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +#else +int +gfx_set_panel_present(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +#endif +{ + /* SET VALID BPP */ + /* 16BPP is the default. */ + + if (bpp != 8 && bpp != 15 && bpp != 16) + bpp = 16; + + /* RECORD PANEL PARAMETERS */ + /* This routine does not touch any panel timings. It is used when custom panel */ + /* settings are set up in advance by the BIOS or an application, but the */ + /* application still requires access to other panel functionality provided by */ + /* Durango (i.e. panning). */ + + ModeWidth = width; + ModeHeight = height; + PanelWidth = (unsigned short)panelResX; + PanelHeight = (unsigned short)panelResY; + PanelEnable = 1; + gbpp = bpp; + + /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */ + + gfx_set_display_bpp(bpp); + + return (GFX_STATUS_OK); +} + +/*-----------------------------------------------------------------------* + * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: * + * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal * + * are used by the video overlay routines. * + * * + * gfx_get_vline and gfx_vactive are used to prevent an issue for the * + * SC1200. * + * * + * The others are part of the Durango API. * + *-----------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * gfx_get_display_pitch + * + * This routine returns the current pitch of the frame buffer, in bytes. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_display_pitch(void) +#else +unsigned short +gfx_get_display_pitch(void) +#endif +{ + unsigned long value; + + if (gfx_cpu_version == GFX_CPU_PYRAMID) { /* Pyramid update for 4KB line pitch */ + value = (READ_REG32(DC_LINE_DELTA) & 0x07FF) << 2; + } else { + value = (READ_REG32(DC_LINE_DELTA) & 0x03FF) << 2; + } + + return ((unsigned short)value); +} + +/*---------------------------------------------------------------------------- + * GFX_GET_DISPLAY_DETAILS + * + * This routine gets the specified display mode. + * + * Returns 1 if successful, 0 if mode could not be get. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) +#else +int +gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) +#endif +{ + if (mode < NUM_GX_DISPLAY_MODES) { + if (DisplayParams[mode].flags & GFX_MODE_56HZ) + *hz = 56; + else if (DisplayParams[mode].flags & GFX_MODE_60HZ) + *hz = 60; + else if (DisplayParams[mode].flags & GFX_MODE_70HZ) + *hz = 70; + else if (DisplayParams[mode].flags & GFX_MODE_72HZ) + *hz = 72; + else if (DisplayParams[mode].flags & GFX_MODE_75HZ) + *hz = 75; + else if (DisplayParams[mode].flags & GFX_MODE_85HZ) + *hz = 85; + + *xres = DisplayParams[mode].hactive; + *yres = DisplayParams[mode].vactive; + + return (1); + } + return (0); +} + +/*---------------------------------------------------------------------------- + * GFX_GET_DISPLAY_MODE_COUNT + * + * Returns number of modes supported. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_display_mode_count(void) +#else +int +gfx_get_display_mode_count(void) +#endif +{ + return (NUM_GX_DISPLAY_MODES); +} + +/*---------------------------------------------------------------------------- + * gfx_get_frame_buffer_line_size + * + * Returns the current frame buffer line size, in bytes + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_frame_buffer_line_size(void) +#else +unsigned long +gfx_get_frame_buffer_line_size(void) +#endif +{ + return ((READ_REG32(DC_BUF_SIZE) & 0x1FF) << 3); +} + +/*---------------------------------------------------------------------------- + * gfx_mode_frequency_supported + * + * This routine examines if the requested mode with pixel frequency is supported. + * + * Returns >0 if successful , <0 if freq. could not be found and matched. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_mode_frequency_supported(int xres, int yres, int bpp, + unsigned long frequency) +#else +int +gfx_mode_frequency_supported(int xres, int yres, int bpp, + unsigned long frequency) +#endif +{ + unsigned int index; + unsigned long value; + unsigned long bpp_flag = 0; + + bpp_flag = GFX_MODE_8BPP; + if (bpp > 8) + bpp_flag = GFX_MODE_16BPP; + + for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { + if ((DisplayParams[index].hactive == (unsigned short)xres) && + (DisplayParams[index].vactive == (unsigned short)yres) && + (DisplayParams[index].flags & bpp_flag) && + (DisplayParams[index].frequency == frequency)) { + int hz = 0; + + value = DisplayParams[index].flags; + + if (value & GFX_MODE_60HZ) + hz = 60; + else if (value & GFX_MODE_70HZ) + hz = 70; + else if (value & GFX_MODE_72HZ) + hz = 72; + else if (value & GFX_MODE_75HZ) + hz = 75; + else if (value & GFX_MODE_85HZ) + hz = 85; + return (hz); + } + } + return (-1); +} + +/*---------------------------------------------------------------------------- + * gfx_refreshrate_from_frequency + * + * This routine maps the frequency to close match refresh rate + * + * Returns . + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +#else +int +gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +#endif +{ + unsigned int index, closematch = 0; + unsigned long value; + unsigned long bpp_flag = 0; + long min, diff; + + *hz = 60; + + bpp_flag = GFX_MODE_8BPP; + if (bpp > 8) + bpp_flag = GFX_MODE_16BPP; + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + min = 0x7fffffff; + for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { + if ((DisplayParams[index].htotal == (unsigned short)xres) && + (DisplayParams[index].vtotal == (unsigned short)yres) && + (DisplayParams[index].flags & bpp_flag)) { + diff = (long)frequency - (long)DisplayParams[index].frequency; + if (diff < 0) + diff = -diff; + + if (diff < min) { + min = diff; + closematch = index; + } + } + } + + value = DisplayParams[closematch].flags; + + if (value & GFX_MODE_60HZ) + *hz = 60; + else if (value & GFX_MODE_70HZ) + *hz = 70; + else if (value & GFX_MODE_72HZ) + *hz = 72; + else if (value & GFX_MODE_75HZ) + *hz = 75; + else if (value & GFX_MODE_85HZ) + *hz = 85; + + return (1); +} + +/*---------------------------------------------------------------------------- + * gfx_refreshrate_from_mode + * + * This routine is identical to the gfx_get_refreshrate_from_frequency, + * except that the active timing values are compared instead of the total + * values. Some modes (such as 70Hz and 72Hz) may be confused in this routine. + * + * Returns . + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +#else +int +gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +#endif +{ + unsigned int index, closematch = 0; + unsigned long value; + unsigned long bpp_flag = 0; + long min, diff; + + *hz = 60; + + bpp_flag = GFX_MODE_8BPP; + if (bpp > 8) + bpp_flag = GFX_MODE_16BPP; + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + min = 0x7fffffff; + for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { + if ((DisplayParams[index].hactive == (unsigned short)xres) && + (DisplayParams[index].vactive == (unsigned short)yres) && + (DisplayParams[index].flags & bpp_flag)) { + diff = (long)frequency - (long)DisplayParams[index].frequency; + if (diff < 0) + diff = -diff; + + if (diff < min) { + min = diff; + closematch = index; + } + } + } + + value = DisplayParams[closematch].flags; + + if (value & GFX_MODE_60HZ) + *hz = 60; + else if (value & GFX_MODE_70HZ) + *hz = 70; + else if (value & GFX_MODE_72HZ) + *hz = 72; + else if (value & GFX_MODE_75HZ) + *hz = 75; + else if (value & GFX_MODE_85HZ) + *hz = 85; + + return (1); +} + +/*---------------------------------------------------------------------------- + * gfx_get_frequency_from_refreshrate + * + * This routine maps the refresh rate to the closest matching PLL frequency. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, + int *frequency) +#else +int +gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, + int *frequency) +#endif +{ + int retval = -1; + unsigned long hz_flag = 0; + unsigned long index, bpp_flag = 0; + + *frequency = 0; + + if (hz == 60) + hz_flag = GFX_MODE_60HZ; + else if (hz == 70) + hz_flag = GFX_MODE_70HZ; + else if (hz == 72) + hz_flag = GFX_MODE_72HZ; + else if (hz == 75) + hz_flag = GFX_MODE_75HZ; + else if (hz == 85) + hz_flag = GFX_MODE_85HZ; + + bpp_flag = GFX_MODE_8BPP; + if (bpp > 8) + bpp_flag = GFX_MODE_16BPP; + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + + for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { + if ((DisplayParams[index].hactive == (unsigned short)xres) && + (DisplayParams[index].vactive == (unsigned short)yres) && + (DisplayParams[index].flags & bpp_flag) && + (DisplayParams[index].flags & hz_flag)) { + *frequency = DisplayParams[index].frequency; + retval = 1; + } + } + return retval; +} + +/*--------------------------------------------------------------------------- + * gfx_get_max_supported_pixel_clock + * + * This routine returns the maximum recommended speed for the pixel clock. The + * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum + * floating point pixel clock speed. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_max_supported_pixel_clock(void) +#else +unsigned long +gfx_get_max_supported_pixel_clock(void) +#endif +{ + /* ALL CHIPS CAN HANDLE 1280X1024@85HZ - 157.5 MHz */ + + return 157500; +} + +/*---------------------------------------------------------------------------- + * gfx_get_display_mode + * + * This routine gets the specified display mode. + * + * Returns >0 if successful and mode returned, <0 if mode could not be found. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz) +#else +int +gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz) +#endif +{ + unsigned int mode = 0; + unsigned long pll_freq = 0, bpp_flag = 0; + + *xres = gfx_get_hactive(); + *yres = gfx_get_vactive(); + *bpp = gfx_get_display_bpp(); + pll_freq = gfx_get_clock_frequency(); + + /* SUPPORT EMULATED VGA MODES */ + + if (gfx_pixel_double) + *xres >>= 1; + + if (gfx_line_double) + *yres >>= 1; + + /* SET BPP FLAGS TO LIMIT MODE SELECTION */ + + bpp_flag = GFX_MODE_8BPP; + if (*bpp > 8) + bpp_flag = GFX_MODE_16BPP; + + for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) { + if ((DisplayParams[mode].hactive == (unsigned short)*xres) && + (DisplayParams[mode].vactive == (unsigned short)*yres) && + (DisplayParams[mode].frequency == pll_freq) && + (DisplayParams[mode].flags & bpp_flag)) { + + pll_freq = DisplayParams[mode].flags; + + if (pll_freq & GFX_MODE_56HZ) + *hz = 56; + else if (pll_freq & GFX_MODE_60HZ) + *hz = 60; + else if (pll_freq & GFX_MODE_70HZ) + *hz = 70; + else if (pll_freq & GFX_MODE_72HZ) + *hz = 72; + else if (pll_freq & GFX_MODE_75HZ) + *hz = 75; + else if (pll_freq & GFX_MODE_85HZ) + *hz = 85; + + return (1); + } + } + return (-1); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hactive + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_hactive(void) +#else +unsigned short +gfx_get_hactive(void) +#endif +{ + return ((unsigned short)((READ_REG32(DC_H_TIMING_1) & 0x07F8) + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hsync_start + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_hsync_start(void) +#else +unsigned short +gfx_get_hsync_start(void) +#endif +{ + return ((unsigned short)((READ_REG32(DC_H_TIMING_3) & 0x07F8) + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hsync_end + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_hsync_end(void) +#else +unsigned short +gfx_get_hsync_end(void) +#endif +{ + return ((unsigned short)(((READ_REG32(DC_H_TIMING_3) >> 16) & 0x07F8) + + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_htotal + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_htotal(void) +#else +unsigned short +gfx_get_htotal(void) +#endif +{ + return ((unsigned short)(((READ_REG32(DC_H_TIMING_1) >> 16) & 0x07F8) + + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vactive + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_vactive(void) +#else +unsigned short +gfx_get_vactive(void) +#endif +{ + return ((unsigned short)((READ_REG32(DC_V_TIMING_1) & 0x07FF) + 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vsync_end + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_vsync_end(void) +#else +unsigned short +gfx_get_vsync_end(void) +#endif +{ + return ((unsigned short)(((READ_REG32(DC_V_TIMING_3) >> 16) & 0x07FF) + + 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vtotal + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_vtotal(void) +#else +unsigned short +gfx_get_vtotal(void) +#endif +{ + return ((unsigned short)(((READ_REG32(DC_V_TIMING_1) >> 16) & 0x07FF) + + 1)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_bpp + * + * This routine returns the current color depth of the active display. + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_display_bpp(void) +#else +unsigned short +gfx_get_display_bpp(void) +#endif +{ + switch (READ_REG32(DC_OUTPUT_CFG) & 3) { + case 0: + return (16); + case 2: + return (15); + } + return (8); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vline + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_vline(void) +#else +unsigned short +gfx_get_vline(void) +#endif +{ + unsigned short current_scan_line; + + /* Read similar value twice to ensure that the value is not transitioning */ + + do + current_scan_line = (unsigned short)READ_REG32(DC_V_LINE_CNT) & 0x07FF; + while (current_scan_line != + (unsigned short)(READ_REG32(DC_V_LINE_CNT) & 0x07FF)); + + return (current_scan_line); +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_offset + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_display_offset(void) +#else +unsigned long +gfx_get_display_offset(void) +#endif +{ + return (READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_offset + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_cursor_offset(void) +#else +unsigned long +gfx_get_cursor_offset(void) +#endif +{ + return (READ_REG32(DC_CURS_ST_OFFSET) & 0x003FFFFF); +} + +#if GFX_READ_ROUTINES + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +/*--------------------------------------------------------------------------- + * gfx_get_hblank_start + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_hblank_start(void) +#else +unsigned short +gfx_get_hblank_start(void) +#endif +{ + return ((unsigned short)((READ_REG32(DC_H_TIMING_2) & 0x07F8) + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hblank_end + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_hblank_end(void) +#else +unsigned short +gfx_get_hblank_end(void) +#endif +{ + return ((unsigned short)(((READ_REG32(DC_H_TIMING_2) >> 16) & 0x07F8) + + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vblank_start + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_vblank_start(void) +#else +unsigned short +gfx_get_vblank_start(void) +#endif +{ + return ((unsigned short)((READ_REG32(DC_V_TIMING_2) & 0x07FF) + 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vsync_start + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_vsync_start(void) +#else +unsigned short +gfx_get_vsync_start(void) +#endif +{ + return ((unsigned short)((READ_REG32(DC_V_TIMING_3) & 0x07FF) + 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vblank_end + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_vblank_end(void) +#else +unsigned short +gfx_get_vblank_end(void) +#endif +{ + return ((unsigned short)(((READ_REG32(DC_V_TIMING_2) >> 16) & 0x07FF) + + 1)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_palette_entry + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_display_palette_entry(unsigned long index, unsigned long *palette) +#else +int +gfx_get_display_palette_entry(unsigned long index, unsigned long *palette) +#endif +{ + unsigned long data; + + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_REG32(DC_PAL_ADDRESS, index); + data = READ_REG32(DC_PAL_DATA); + data = ((data << 2) & 0x000000FC) | + ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000); + + *palette = data; + + return 0; +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_palette + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu1_get_display_palette(unsigned long *palette) +#else +void +gfx_get_display_palette(unsigned long *palette) +#endif +{ + unsigned long i, data; + + WRITE_REG32(DC_PAL_ADDRESS, 0); + for (i = 0; i < 256; i++) { + data = READ_REG32(DC_PAL_DATA); + data = ((data << 2) & 0x000000FC) | + ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000); + palette[i] = data; + } +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_enable + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_cursor_enable(void) +#else +unsigned long +gfx_get_cursor_enable(void) +#endif +{ + return (READ_REG32(DC_GENERAL_CFG) & DC_GCFG_CURE); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_position + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_cursor_position(void) +#else +unsigned long +gfx_get_cursor_position(void) +#endif +{ + return ((READ_REG32(DC_CURSOR_X) & 0x07FF) | + ((READ_REG32(DC_CURSOR_Y) << 16) & 0x03FF0000)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_clip + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_cursor_clip(void) +#else +unsigned long +gfx_get_cursor_clip(void) +#endif +{ + return (((READ_REG32(DC_CURSOR_X) >> 11) & 0x01F) | + ((READ_REG32(DC_CURSOR_Y) << 5) & 0x1F0000)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_color + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_cursor_color(int color) +#else +unsigned long +gfx_get_cursor_color(int color) +#endif +{ + unsigned long data; + + if (color) { + WRITE_REG32(DC_PAL_ADDRESS, 0x101); + } else { + WRITE_REG32(DC_PAL_ADDRESS, 0x100); + } + data = READ_REG32(DC_PAL_DATA); + data = ((data << 6) & 0x00FC0000) | + ((data << 4) & 0x0000FC00) | ((data << 2) & 0x000000FC); + return (data); +} + +/*----------------------------------------------------------------------------- + * gfx_get_compression_enable + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_compression_enable(void) +#else +int +gfx_get_compression_enable(void) +#endif +{ + unsigned long gcfg; + + gcfg = READ_REG32(DC_GENERAL_CFG); + if (gcfg & DC_GCFG_CMPE) + return (1); + else + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_compression_offset + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_compression_offset(void) +#else +unsigned long +gfx_get_compression_offset(void) +#endif +{ + unsigned long offset; + + offset = READ_REG32(DC_CB_ST_OFFSET) & 0x003FFFFF; + return (offset); +} + +/*----------------------------------------------------------------------------- + * gfx_get_compression_pitch + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_compression_pitch(void) +#else +unsigned short +gfx_get_compression_pitch(void) +#endif +{ + unsigned short pitch; + + pitch = (unsigned short)(READ_REG32(DC_LINE_DELTA) >> 12) & 0x07FF; + return (pitch << 2); +} + +/*----------------------------------------------------------------------------- + * gfx_get_compression_size + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu1_get_compression_size(void) +#else +unsigned short +gfx_get_compression_size(void) +#endif +{ + unsigned short size; + + size = (unsigned short)((READ_REG32(DC_BUF_SIZE) >> 9) & 0x7F) - 1; + return ((size << 2) + 16); +} + +/*----------------------------------------------------------------------------- + * gfx_get_valid_bit + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_valid_bit(int line) +#else +int +gfx_get_valid_bit(int line) +#endif +{ + int valid; + + WRITE_REG32(MC_DR_ADD, line); + valid = (int)READ_REG32(MC_DR_ACC) & 1; + return (valid); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_get_video_offset". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_display_video_offset(void) +#else +unsigned long +gfx_get_display_video_offset(void) +#endif +{ + return (READ_REG32(DC_VID_ST_OFFSET) & 0x003FFFFF); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_get_video_size". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu1_get_display_video_size(void) +#else +unsigned long +gfx_get_display_video_size(void) +#endif +{ + /* RETURN TOTAL SIZE, IN BYTES */ + + return ((READ_REG32(DC_BUF_SIZE) >> 10) & 0x000FFFC0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_priority_high + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu1_get_display_priority_high(void) +#else +int +gfx_get_display_priority_high(void) +#endif +{ + if (READ_REG32(MC_MEM_CNTRL1) & MC_XBUSARB) + return (1); + else + return (0); +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu2.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu2.c new file mode 100644 index 000000000..ba72e88aa --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu2.c @@ -0,0 +1,3156 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu2.c,v 1.4 2003/02/06 17:46:02 alanh Exp $ */ +/* + * $Workfile: disp_gu2.c $ + * + * This file contains routines for the second generation display controller. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +void gu2_enable_compression(void); /* private routine definition */ +void gu2_disable_compression(void); /* private routine definition */ +int gu2_set_display_bpp(unsigned short bpp); +int gu2_is_display_mode_supported(int xres, int yres, int bpp, int hz); +int gu2_set_display_mode(int xres, int yres, int bpp, int hz); +int gu2_set_display_timings(unsigned short bpp, unsigned short flags, + unsigned short hactive, + unsigned short hblank_start, + unsigned short hsync_start, + unsigned short hsync_end, + unsigned short hblank_end, unsigned short htotal, + unsigned short vactive, + unsigned short vblank_start, + unsigned short vsync_start, + unsigned short vsync_end, + unsigned short vblank_end, unsigned short vtotal, + unsigned long frequency); +int gu2_set_vtotal(unsigned short vtotal); +void gu2_set_display_pitch(unsigned short pitch); +void gu2_set_display_offset(unsigned long offset); +int gu2_set_display_palette_entry(unsigned long index, unsigned long palette); +int gu2_set_display_palette(unsigned long *palette); +void gu2_video_shutdown(void); +void gu2_set_clock_frequency(unsigned long frequency); +int gu2_set_crt_enable(int enable); +void gu2_set_cursor_enable(int enable); +void gu2_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor); +void gu2_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, + unsigned short yhotspot); +void gu2_set_cursor_shape32(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask); +void gu2_set_cursor_shape64(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask); +void gu2_set_icon_enable(int enable); +void gu2_set_icon_colors(unsigned long color0, unsigned long color1, + unsigned long color2); +void gu2_set_icon_position(unsigned long memoffset, unsigned short xpos); +void gu2_set_icon_shape64(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask, unsigned int lines); + +int gu2_set_compression_enable(int enable); +int gu2_set_compression_offset(unsigned long offset); +int gu2_set_compression_pitch(unsigned short pitch); +int gu2_set_compression_size(unsigned short size); +void gu2_set_display_priority_high(int enable); +int gu2_test_timing_active(void); +int gu2_test_vertical_active(void); +int gu2_wait_vertical_blank(void); +void gu2_delay_milliseconds(unsigned long milliseconds); +void gu2_delay_microseconds(unsigned long microseconds); +void gu2_enable_panning(int x, int y); +int gu2_set_fixed_timings(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp); +int gu2_set_panel_present(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp); +void gu2_reset_timing_lock(void); + +int gu2_get_display_details(unsigned int mode, int *xres, int *yres, int *hz); +unsigned short gu2_get_display_pitch(void); +int gu2_get_vsa2_softvga_enable(void); +int gu2_get_sync_polarities(void); +unsigned long gu2_get_clock_frequency(void); +unsigned long gu2_get_max_supported_pixel_clock(void); +int gu2_mode_frequency_supported(int xres, int yres, int bpp, + unsigned long frequency); +int gu2_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, + unsigned long frequency); +int gu2_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, + unsigned long frequency); +int gu2_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, + int *frequency); +int gu2_get_display_mode_count(void); +int gu2_get_display_mode(int *xres, int *yres, int *bpp, int *hz); +unsigned long gu2_get_frame_buffer_line_size(void); +unsigned short gu2_get_hactive(void); +unsigned short gu2_get_hblank_start(void); +unsigned short gu2_get_hsync_start(void); +unsigned short gu2_get_hsync_end(void); +unsigned short gu2_get_hblank_end(void); +unsigned short gu2_get_htotal(void); +unsigned short gu2_get_vactive(void); +unsigned short gu2_get_vline(void); +unsigned short gu2_get_vblank_start(void); +unsigned short gu2_get_vsync_start(void); +unsigned short gu2_get_vsync_end(void); +unsigned short gu2_get_vblank_end(void); +unsigned short gu2_get_vtotal(void); +unsigned short gu2_get_display_bpp(void); +unsigned long gu2_get_display_offset(void); +int gu2_get_display_palette_entry(unsigned long index, + unsigned long *palette); +void gu2_get_display_palette(unsigned long *palette); +unsigned long gu2_get_cursor_enable(void); +unsigned long gu2_get_cursor_offset(void); +unsigned long gu2_get_cursor_position(void); +unsigned long gu2_get_cursor_clip(void); +unsigned long gu2_get_cursor_color(int color); +unsigned long gu2_get_icon_enable(void); +unsigned long gu2_get_icon_offset(void); +unsigned long gu2_get_icon_position(void); +unsigned long gu2_get_icon_color(int color); +int gu2_get_compression_enable(void); +unsigned long gu2_get_compression_offset(void); +unsigned short gu2_get_compression_pitch(void); +unsigned short gu2_get_compression_size(void); +int gu2_get_display_priority_high(void); +int gu2_get_valid_bit(int line); +int gu2_set_specified_mode(DISPLAYMODE * pMode, int bpp); +void gu2_set_display_video_size(unsigned short width, unsigned short height); +void gu2_set_display_video_offset(unsigned long offset); +unsigned long gu2_get_display_video_offset(void); +unsigned long gu2_get_display_video_size(void); +void gu2_get_display_video_yuv_pitch(unsigned long *ypitch, + unsigned long *uvpitch); +int gu2_get_display_video_downscale_enable(void); +void gu2_set_display_video_format(unsigned long format); +void gu2_set_display_video_enable(int enable); +void gu2_set_display_video_yuv_offsets(unsigned long yoffset, + unsigned long uoffset, + unsigned long voffset); +void gu2_set_display_video_yuv_pitch(unsigned long ypitch, + unsigned long uvpitch); +void gu2_set_display_video_downscale(unsigned short srch, + unsigned short dsth); +void gu2_set_display_video_vertical_downscale_enable(int enable); +void gu2_get_display_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset); +unsigned long gu2_get_display_video_downscale_delta(void); + + /*----------------------------------------------------------------------------- + * WARNING!!!! INACCURATE DELAY MECHANISM + * + * In an effort to keep the code self contained and operating system + * independent, the delay loop just performs reads of a display controller + * register. This time will vary for faster processors. The delay can always + * be longer than intended, only effecting the time of the mode switch + * (obviously want it to still be under a second). Problems with the hardware + * only arise if the delay is not long enough. + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_delay_milliseconds(unsigned long milliseconds) +#else +void +gfx_delay_milliseconds(unsigned long milliseconds) +#endif +{ + /* ASSUME 300 MHZ 20 CLOCKS PER READ */ + +# define RC_READS_PER_MILLISECOND 15000L + + unsigned long loop; + + loop = milliseconds * RC_READS_PER_MILLISECOND; + while (loop-- > 0) { + READ_REG32(MDC_UNLOCK); + } +} + +#if GFX_DISPLAY_DYNAMIC +void +gu2_delay_microseconds(unsigned long microseconds) +#else +void +gfx_delay_microseconds(unsigned long microseconds) +#endif +{ + /* ASSUME 400 MHz, 2 CLOCKS PER INCREMENT */ + + unsigned long loop_count = microseconds * 15; + + while (loop_count-- > 0) { + READ_REG32(MDC_UNLOCK); + } +} + +/*----------------------------------------------------------------------------- + * GFX_SET_DISPLAY_BPP + * + * This routine programs the bpp in the display controller. + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_display_bpp(unsigned short bpp) +#else +int +gfx_set_display_bpp(unsigned short bpp) +#endif +{ + unsigned long dcfg, lock; + + dcfg = READ_REG32(MDC_DISPLAY_CFG) & ~(MDC_DCFG_DISP_MODE_MASK | + MDC_DCFG_16BPP_MODE_MASK); + lock = READ_REG32(MDC_UNLOCK); + + switch (bpp) { + case 12: + dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_12BPP); + break; + case 15: + dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_15BPP); + break; + case 16: + dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_16BPP); + break; + case 32: + dcfg |= (MDC_DCFG_DISP_MODE_24BPP); + break; + case 8: + dcfg |= (MDC_DCFG_DISP_MODE_8BPP); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_DISPLAY_CFG, dcfg); + WRITE_REG32(MDC_UNLOCK, lock); + + /* SET BPP IN GRAPHICS PIPELINE */ + + gfx_set_bpp(bpp); + + return 0; +} + +/*----------------------------------------------------------------------------- + * gu2_set_specified_mode (private routine) + * This routine uses the parameters in the specified display mode structure + * to program the display controller hardware. + *----------------------------------------------------------------------------- + */ +int +gu2_set_specified_mode(DISPLAYMODE * pMode, int bpp) +{ + unsigned long unlock, value; + unsigned long gcfg, dcfg; + unsigned long size, pitch; + unsigned long vid_buf_size; + unsigned long bpp_mask, temp, dv_size; + + /* CHECK WHETHER TIMING CHANGE IS ALLOWED */ + /* Flag used for locking also overrides timing change restriction */ + + if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING)) + return GFX_STATUS_ERROR; + + /* CLEAR PANNING OFFSETS */ + + DeltaX = 0; + DeltaY = 0; + panelLeft = 0; + panelTop = 0; + + /* SET GLOBAL FLAG */ + + if (pMode->flags & GFX_MODE_LOCK_TIMING) + gfx_timing_lock = 1; + + /* CHECK FOR VALID BPP */ + /* As this function can be called directly from */ + /* gfx_set_display_timings, we must correct any */ + /* invalid bpp settings. */ + + switch (bpp) { + case 12: + bpp_mask = 0x00000900; + break; + case 15: + bpp_mask = 0x00000500; + break; + case 16: + bpp_mask = 0x00000100; + break; + case 32: + bpp_mask = 0x00000200; + break; + default: + bpp_mask = 0x00000000; + bpp = 8; + break; + } + + gbpp = bpp; + + /* DISABLE COMPRESSION */ + + gu2_disable_compression(); + + /* ALSO DISABLE VIDEO */ + /* Use private "reset video" routine to do all that is needed. */ + /* SC1200, for example, also disables the alpha blending regions. */ + + gfx_reset_video(); + + /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ + + unlock = READ_REG32(MDC_UNLOCK); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + + /* READ THE CURRENT REGISTER VALUES */ + + gcfg = READ_REG32(MDC_GENERAL_CFG); + dcfg = READ_REG32(MDC_DISPLAY_CFG); + + /* BLANK THE DISPLAY IN THE DISPLAY FILTER */ + + gfx_set_crt_enable(0); + + /* DISABLE THE TIMING GENERATOR */ + + dcfg &= ~(unsigned long)MDC_DCFG_TGEN; + WRITE_REG32(MDC_DISPLAY_CFG, dcfg); + + /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */ + /* This delay is used to make sure that all pending requests to the */ + /* memory controller have completed before disabling the FIFO load. */ + + gfx_delay_milliseconds(5); + + /* DISABLE DISPLAY FIFO LOAD */ + + gcfg &= ~(unsigned long)MDC_GCFG_DFLE; + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + + /* PRESERVE VIDEO INFORMATION */ + + gcfg &= (unsigned long)(MDC_GCFG_YUVM | MDC_GCFG_VDSE); + dcfg = 0; + + /* SET THE DOT CLOCK FREQUENCY */ + /* Mask off the divide by two bit (bit 31) */ + + gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF); + + /* DELAY: WAIT FOR THE PLL TO SETTLE */ + /* This allows the dot clock frequency that was just set to settle. */ + + gfx_delay_milliseconds(10); + + /* SET THE GX DISPLAY CONTROLLER PARAMETERS */ + + WRITE_REG32(MDC_FB_ST_OFFSET, 0); + WRITE_REG32(MDC_CB_ST_OFFSET, 0); + WRITE_REG32(MDC_CURS_ST_OFFSET, 0); + WRITE_REG32(MDC_ICON_ST_OFFSET, 0); + + /* SET LINE SIZE AND PITCH */ + /* 1. Flat Panels must use the mode width and not */ + /* the timing width to set the pitch. */ + /* 2. Mode sets will use a pitch that is aligned */ + /* on a 1K boundary to preserve legacy. The */ + /* pitch can be overridden by a subsequent call */ + /* to gfx_set_display_pitch. */ + + if (PanelEnable) + size = ModeWidth; + else + size = pMode->hactive; + + if (bpp > 8) + size <<= 1; + if (bpp > 16) + size <<= 1; + + pitch = 1024; + dv_size = MDC_DV_LINE_SIZE_1024; + + if (size > 1024) { + pitch = 2048; + dv_size = MDC_DV_LINE_SIZE_2048; + } + if (size > 2048) { + pitch = 4096; + dv_size = MDC_DV_LINE_SIZE_4096; + } + if (size > 4096) { + pitch = 8192; + dv_size = MDC_DV_LINE_SIZE_8192; + } + WRITE_REG32(MDC_GFX_PITCH, pitch >> 3); + + /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ + + temp = READ_REG32(MDC_DV_CTL); + WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); + + if (PanelEnable) { + size = pMode->hactive; + if (bpp > 8) + size <<= 1; + if (bpp > 16) + size <<= 1; + } + + /* SAVE PREVIOUSLY STORED VIDEO LINE SIZE */ + + vid_buf_size = READ_REG32(MDC_LINE_SIZE) & 0xFF000000; + + /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */ + + WRITE_REG32(MDC_LINE_SIZE, ((size >> 3) + 2) | vid_buf_size); + + /* ALWAYS ENABLE VIDEO AND GRAPHICS DATA */ + /* These bits are relics from a previous design and */ + /* should always be enabled. */ + + dcfg |= (unsigned long)(MDC_DCFG_VDEN | MDC_DCFG_GDEN); + + /* SET PIXEL FORMAT */ + + dcfg |= bpp_mask; + + /* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */ + /* AND VERT. INT. SELECT */ + + dcfg |= + (unsigned long)(MDC_DCFG_TGEN | MDC_DCFG_TRUP | MDC_DCFG_PALB | + MDC_DCFG_VISL); + + /* DISABLE ADDRESS MASKS */ + + dcfg |= MDC_DCFG_A20M; + dcfg |= MDC_DCFG_A18M; + + /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE */ + /* Set the priorities higher for high resolution modes. */ + + if (pMode->hactive > 1024 || bpp == 32) + gcfg |= 0x000A901; + else + gcfg |= 0x0006501; + + /* ENABLE FLAT PANEL CENTERING */ + /* For panel modes having a resolution smaller than the */ + /* panel resolution, turn on data centering. */ + + if (PanelEnable && ModeWidth < PanelWidth) + dcfg |= MDC_DCFG_DCEN; + + /* COMBINE AND SET TIMING VALUES */ + + value = (unsigned long)(pMode->hactive - 1) | + (((unsigned long)(pMode->htotal - 1)) << 16); + WRITE_REG32(MDC_H_ACTIVE_TIMING, value); + value = (unsigned long)(pMode->hblankstart - 1) | + (((unsigned long)(pMode->hblankend - 1)) << 16); + WRITE_REG32(MDC_H_BLANK_TIMING, value); + value = (unsigned long)(pMode->hsyncstart - 1) | + (((unsigned long)(pMode->hsyncend - 1)) << 16); + WRITE_REG32(MDC_H_SYNC_TIMING, value); + value = (unsigned long)(pMode->vactive - 1) | + (((unsigned long)(pMode->vtotal - 1)) << 16); + WRITE_REG32(MDC_V_ACTIVE_TIMING, value); + value = (unsigned long)(pMode->vblankstart - 1) | + (((unsigned long)(pMode->vblankend - 1)) << 16); + WRITE_REG32(MDC_V_BLANK_TIMING, value); + value = (unsigned long)(pMode->vsyncstart - 1) | + (((unsigned long)(pMode->vsyncend - 1)) << 16); + WRITE_REG32(MDC_V_SYNC_TIMING, value); + + WRITE_REG32(MDC_DISPLAY_CFG, dcfg); + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + + /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */ + + gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) | + ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0)); + + /* RESTORE VALUE OF MDC_UNLOCK */ + + WRITE_REG32(MDC_UNLOCK, unlock); + + /* RESET THE PITCH VALUES IN THE GP */ + + gfx_reset_pitch((unsigned short)pitch); + + gfx_set_bpp((unsigned short)bpp); + + return GFX_STATUS_OK; +} + + /*---------------------------------------------------------------------------- + * GFX_IS_DISPLAY_MODE_SUPPORTED + * + * This routine sets the specified display mode. + * + * Returns 1 if successful, 0 if mode could not be set. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_is_display_mode_supported(int xres, int yres, int bpp, int hz) +#else +int +gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz) +#endif +{ + unsigned int mode; + unsigned long hz_flag = 0, bpp_flag = 0; + + /* SET FLAGS TO MATCH REFRESH RATE */ + + if (hz == 56) + hz_flag = GFX_MODE_56HZ; + if (hz == 60) + hz_flag = GFX_MODE_60HZ; + if (hz == 70) + hz_flag = GFX_MODE_70HZ; + if (hz == 72) + hz_flag = GFX_MODE_72HZ; + if (hz == 75) + hz_flag = GFX_MODE_75HZ; + if (hz == 85) + hz_flag = GFX_MODE_85HZ; + + /* SET BPP FLAGS TO LIMIT MODE SELECTION */ + + switch (bpp) { + case 8: + bpp_flag = GFX_MODE_8BPP; + break; + case 12: + bpp_flag = GFX_MODE_12BPP; + break; + case 15: + bpp_flag = GFX_MODE_15BPP; + break; + case 16: + bpp_flag = GFX_MODE_16BPP; + break; + case 32: + bpp_flag = GFX_MODE_24BPP; + break; + default: + return (-1); + } + + /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ + + for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) { + if ((DisplayParams[mode].hactive == (unsigned short)xres) && + (DisplayParams[mode].vactive == (unsigned short)yres) && + (DisplayParams[mode].flags & hz_flag) && + (DisplayParams[mode].flags & bpp_flag)) { + + /* REDCLOUD DOES NOT SUPPORT EMULATED VGA MODES */ + + if ((DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE) || + (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE)) + continue; + + /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */ + + return (mode); + } + } + return (-1); +} + +/*---------------------------------------------------------------------------- + * gfx_set_display_mode + * + * This routine sets the specified display mode. + * + * Returns 1 if successful, 0 if mode could not be set. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_display_mode(int xres, int yres, int bpp, int hz) +#else +int +gfx_set_display_mode(int xres, int yres, int bpp, int hz) +#endif +{ + int mode; + + /* DISABLE FLAT PANEL */ + /* Flat Panel settings are enabled by the function gfx_set_fixed_timings */ + /* and disabled by gfx_set_display_mode. */ + + PanelEnable = 0; + + mode = gfx_is_display_mode_supported(xres, yres, bpp, hz); + if (mode >= 0) { + if (gu2_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK) + return (1); + } + return (0); +} + +/*---------------------------------------------------------------------------- + * GFX_SET_DISPLAY_TIMINGS + * + * This routine sets the display controller mode using the specified timing + * values (as opposed to using the tables internal to Durango). + * + * Returns GFX_STATUS_OK ON SUCCESS, GFX_STATUS_ERROR otherwise. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_display_timings(unsigned short bpp, unsigned short flags, + unsigned short hactive, unsigned short hblankstart, + unsigned short hsyncstart, unsigned short hsyncend, + unsigned short hblankend, unsigned short htotal, + unsigned short vactive, unsigned short vblankstart, + unsigned short vsyncstart, unsigned short vsyncend, + unsigned short vblankend, unsigned short vtotal, + unsigned long frequency) +#else +int +gfx_set_display_timings(unsigned short bpp, unsigned short flags, + unsigned short hactive, unsigned short hblankstart, + unsigned short hsyncstart, unsigned short hsyncend, + unsigned short hblankend, unsigned short htotal, + unsigned short vactive, unsigned short vblankstart, + unsigned short vsyncstart, unsigned short vsyncend, + unsigned short vblankend, unsigned short vtotal, + unsigned long frequency) +#endif +{ + /* SET MODE STRUCTURE WITH SPECIFIED VALUES */ + + gfx_display_mode.flags = 0; + if (flags & 1) + gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC; + if (flags & 2) + gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC; + if (flags & 0x1000) + gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING; + gfx_display_mode.hactive = hactive; + gfx_display_mode.hblankstart = hblankstart; + gfx_display_mode.hsyncstart = hsyncstart; + gfx_display_mode.hsyncend = hsyncend; + gfx_display_mode.hblankend = hblankend; + gfx_display_mode.htotal = htotal; + gfx_display_mode.vactive = vactive; + gfx_display_mode.vblankstart = vblankstart; + gfx_display_mode.vsyncstart = vsyncstart; + gfx_display_mode.vsyncend = vsyncend; + gfx_display_mode.vblankend = vblankend; + gfx_display_mode.vtotal = vtotal; + gfx_display_mode.frequency = frequency; + + /* CALL ROUTINE TO SET MODE */ + + return (gu2_set_specified_mode(&gfx_display_mode, bpp)); +} + +/*---------------------------------------------------------------------------- + * GFX_SET_VTOTAL + * + * This routine sets the display controller vertical total to + * "vtotal". As a side effect it also sets vertical blank end. + * It should be used when only this value needs to be changed, + * due to speed considerations. + * + * Note: it is the caller's responsibility to make sure that + * a legal vtotal is used, i.e. that "vtotal" is greater than or + * equal to vsync end. + * + * Always returns 0. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_vtotal(unsigned short vtotal) +#else +int +gfx_set_vtotal(unsigned short vtotal) +#endif +{ + unsigned long unlock, dcfg, vactive, vblank; + + /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ + + unlock = READ_REG32(MDC_UNLOCK); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + + /* READ THE CURRENT RC VALUES */ + + dcfg = READ_REG32(MDC_DISPLAY_CFG); + vactive = READ_REG32(MDC_V_ACTIVE_TIMING); + vblank = READ_REG32(MDC_V_BLANK_TIMING); + + /* DISABLE TIMING REGISTER UPDATES */ + + WRITE_REG32(MDC_DISPLAY_CFG, dcfg & ~(unsigned long)MDC_DCFG_TRUP); + + /* WRITE NEW TIMING VALUES */ + + WRITE_REG32(MDC_V_ACTIVE_TIMING, + (vactive & MDC_VAT_VA_MASK) | (unsigned long)(vtotal - + 1) << 16); + WRITE_REG32(MDC_V_BLANK_TIMING, + (vblank & MDC_VBT_VBS_MASK) | (unsigned long)(vtotal - + 1) << 16); + + /* RESTORE OLD RC VALUES */ + + WRITE_REG32(MDC_DISPLAY_CFG, dcfg); + WRITE_REG32(MDC_UNLOCK, unlock); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_pitch + * + * This routine sets the pitch of the frame buffer to the specified value. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_pitch(unsigned short pitch) +#else +void +gfx_set_display_pitch(unsigned short pitch) +#endif +{ + unsigned long value = 0; + unsigned long lock = READ_REG32(MDC_UNLOCK); + + value = READ_REG32(MDC_GFX_PITCH) & 0xFFFF0000; + value |= (pitch >> 3); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GFX_PITCH, value); + + /* SET RENDERING PITCHES TO MATCH */ + + gfx_reset_pitch(pitch); + + /* SET THE FRAME DIRTY MODE */ + /* Non-standard pitches, i.e. pitches that */ + /* are not 1K, 2K or 4K must mark the entire */ + /* frame as dirty when writing to the frame */ + /* buffer. */ + + value = READ_REG32(MDC_GENERAL_CFG); + + if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192) + value &= ~(unsigned long)(MDC_GCFG_FDTY); + else + value |= (unsigned long)(MDC_GCFG_FDTY); + + WRITE_REG32(MDC_GENERAL_CFG, value); + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_offset + * + * This routine sets the start address of the frame buffer. It is + * typically used to pan across a virtual desktop (frame buffer larger than + * the displayed screen) or to flip the display between multiple buffers. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_offset(unsigned long offset) +#else +void +gfx_set_display_offset(unsigned long offset) +#endif +{ + /* UPDATE FRAME BUFFER OFFSET */ + unsigned long lock; + + lock = READ_REG32(MDC_UNLOCK); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + + /* START ADDRESS EFFECTS DISPLAY COMPRESSION */ + /* Disable compression for non-zero start addresss values. */ + /* Enable compression if offset is zero and comression is intended to */ + /* be enabled from a previous call to "gfx_set_compression_enable". */ + /* Compression should be disabled BEFORE the offset is changed */ + /* and enabled AFTER the offset is changed. */ + + if (offset == 0) { + WRITE_REG32(MDC_FB_ST_OFFSET, offset); + if (gfx_compression_enabled) { + /* WAIT FOR THE OFFSET TO BE LATCHED */ + gfx_wait_vertical_blank(); + gu2_enable_compression(); + } + } else { + /* ONLY DISABLE COMPRESSION ONCE */ + + if (gfx_compression_active) + gu2_disable_compression(); + + WRITE_REG32(MDC_FB_ST_OFFSET, offset); + } + + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_palette_entry + * + * This routine sets an palette entry in the display controller. + * A 32-bit X:R:G:B value. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_display_palette_entry(unsigned long index, unsigned long palette) +#else +int +gfx_set_display_palette_entry(unsigned long index, unsigned long palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_REG32(MDC_PAL_ADDRESS, index); + WRITE_REG32(MDC_PAL_DATA, palette); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_palette + * + * This routine sets the entire palette in the display controller. + * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_display_palette(unsigned long *palette) +#else +int +gfx_set_display_palette(unsigned long *palette) +#endif +{ + unsigned long i; + + WRITE_REG32(MDC_PAL_ADDRESS, 0); + + if (palette) { + for (i = 0; i < 256; i++) { + WRITE_REG32(MDC_PAL_DATA, palette[i]); + } + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_enable + * + * This routine enables or disables the hardware cursor. + * + * WARNING: The cursor start offset must be set by setting the cursor + * position before calling this routine to assure that memory reads do not + * go past the end of graphics memory (this can hang GXm). + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_cursor_enable(int enable) +#else +void +gfx_set_cursor_enable(int enable) +#endif +{ + unsigned long unlock, gcfg; + + /* SET OR CLEAR CURSOR ENABLE BIT */ + + unlock = READ_REG32(MDC_UNLOCK); + gcfg = READ_REG32(MDC_GENERAL_CFG); + if (enable) + gcfg |= MDC_GCFG_CURE; + else + gcfg &= ~(MDC_GCFG_CURE); + + /* WRITE NEW REGISTER VALUE */ + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + WRITE_REG32(MDC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_colors + * + * This routine sets the colors of the hardware cursor. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) +#else +void +gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) +#endif +{ + /* SET CURSOR COLORS */ + + WRITE_REG32(MDC_PAL_ADDRESS, 0x100); + WRITE_REG32(MDC_PAL_DATA, bkcolor); + WRITE_REG32(MDC_PAL_DATA, fgcolor); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_position + * + * This routine sets the position of the hardware cusror. The starting + * offset of the cursor buffer must be specified so that the routine can + * properly clip scanlines if the cursor is off the top of the screen. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, unsigned short yhotspot) +#else +void +gfx_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, unsigned short yhotspot) +#endif +{ + unsigned long unlock; + + short x = (short)xpos - (short)xhotspot; + short y = (short)ypos - (short)yhotspot; + short xoffset = 0; + short yoffset = 0; + + if (x < -63) + return; + if (y < -63) + return; + + if (PanelEnable) { + if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) { + gfx_enable_panning(xpos, ypos); + x = x - (unsigned short)panelLeft; + y = y - (unsigned short)panelTop; + } + } + + /* ADJUST OFFSETS */ + /* Cursor movement and panning work as follows: The cursor position */ + /* refers to where the hotspot of the cursor is located. However, for */ + /* non-zero hotspots, the cursor buffer actually begins before the */ + /* specified position. */ + + if (x < 0) { + xoffset = -x; + x = 0; + } + if (y < 0) { + yoffset = -y; + y = 0; + } + memoffset += (unsigned long)yoffset << 4; + + /* SET CURSOR POSITION */ + + unlock = READ_REG32(MDC_UNLOCK); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_CURS_ST_OFFSET, memoffset); + WRITE_REG32(MDC_CURSOR_X, (unsigned long)x | + (((unsigned long)xoffset) << 11)); + WRITE_REG32(MDC_CURSOR_Y, (unsigned long)y | + (((unsigned long)yoffset) << 11)); + WRITE_REG32(MDC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_shape32 + * + * This routine loads 32x32 cursor data into the cursor buffer in graphics memory. + * As the Redcloud cursor is actually 64x64, we must pad the outside of the + * cursor data with transparent pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_cursor_shape32(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +#else +void +gfx_set_cursor_shape32(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +#endif +{ + int i; + + for (i = 0; i < 32; i++) { + /* EVEN QWORDS CONTAIN THE AND MASK */ + + WRITE_FB32(memoffset, 0xFFFFFFFF); + WRITE_FB32(memoffset + 4, andmask[i]); + + /* ODD QWORDS CONTAIN THE XOR MASK */ + + WRITE_FB32(memoffset + 8, 0x00000000); + WRITE_FB32(memoffset + 12, xormask[i]); + + memoffset += 16; + } + + /* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */ + + for (i = 0; i < 32; i++) { + WRITE_FB32(memoffset, 0xFFFFFFFF); + WRITE_FB32(memoffset + 4, 0xFFFFFFFF); + WRITE_FB32(memoffset + 8, 0x00000000); + WRITE_FB32(memoffset + 12, 0x00000000); + + memoffset += 16; + } +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_shape64 + * + * This routine loads 64x64 cursor data into the cursor buffer in graphics memory. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_cursor_shape64(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +#else +void +gfx_set_cursor_shape64(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +#endif +{ + int i; + + for (i = 0; i < 128; i += 2) { + /* EVEN QWORDS CONTAIN THE AND MASK */ + /* We invert the dwords to prevent the calling */ + /* application from having to think in terms of Qwords. */ + /* The hardware data order is actually 63:0, or 31:0 of */ + /* the second dword followed by 31:0 of the first dword. */ + + WRITE_FB32(memoffset, andmask[i + 1]); + WRITE_FB32(memoffset + 4, andmask[i]); + + /* ODD QWORDS CONTAIN THE XOR MASK */ + + WRITE_FB32(memoffset + 8, xormask[i + 1]); + WRITE_FB32(memoffset + 12, xormask[i]); + + memoffset += 16; + } +} + +/*--------------------------------------------------------------------------- + * gfx_set_icon_enable + * + * This routine enables or disables the hardware icon. The icon position + * and colors should be programmed prior to calling this routine for the + * first time. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_icon_enable(int enable) +#else +void +gfx_set_icon_enable(int enable) +#endif +{ + unsigned long unlock, gcfg; + + /* SET OR CLEAR ICON ENABLE BIT */ + + unlock = READ_REG32(MDC_UNLOCK); + gcfg = READ_REG32(MDC_GENERAL_CFG); + if (enable) + gcfg |= MDC_GCFG_ICNE; + else + gcfg &= ~(MDC_GCFG_ICNE); + + /* WRITE NEW REGISTER VALUE */ + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + WRITE_REG32(MDC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_icon_colors + * + * This routine sets the three icon colors. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_icon_colors(unsigned long color0, unsigned long color1, + unsigned long color2) +#else +void +gfx_set_icon_colors(unsigned long color0, unsigned long color1, + unsigned long color2) +#endif +{ + /* ICON COLORS LOCATED AT PALETTE INDEXES 102-104h */ + + WRITE_REG32(MDC_PAL_ADDRESS, 0x102); + + WRITE_REG32(MDC_PAL_DATA, color0); + WRITE_REG32(MDC_PAL_DATA, color1); + WRITE_REG32(MDC_PAL_DATA, color2); +} + +/*--------------------------------------------------------------------------- + * gfx_set_icon_position + * + * This routine sets the starting X coordinate for the hardware icon and the + * memory offset for the icon buffer. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_icon_position(unsigned long memoffset, unsigned short xpos) +#else +void +gfx_set_icon_position(unsigned long memoffset, unsigned short xpos) +#endif +{ + unsigned long lock = READ_REG32(MDC_UNLOCK); + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + + /* PROGRAM THE MEMORY OFFSET */ + + WRITE_REG32(MDC_ICON_ST_OFFSET, memoffset & 0x0FFFFFFF); + + /* PROGRAM THE XCOORDINATE */ + + WRITE_REG32(MDC_ICON_X, (unsigned long)(xpos & 0x07FF)); + + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_icon_shape64 + * + * This routine initializes the icon buffer according to the current mode. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_icon_shape64(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask, unsigned int lines) +#else +void +gfx_set_icon_shape64(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask, unsigned int lines) +#endif +{ + unsigned short i, height; + + height = lines << 1; + + for (i = 0; i < height; i += 2) { + /* EVEN QWORDS CONTAIN THE AND MASK */ + /* Swap dwords to hide qword constraint */ + + WRITE_FB32(memoffset, andmask[i + 1]); + WRITE_FB32(memoffset + 4, andmask[i]); + + /* ODD QWORDS CONTAIN THE XOR MASK */ + + WRITE_FB32(memoffset + 8, xormask[i + 1]); + WRITE_FB32(memoffset + 12, xormask[i]); + + memoffset += 16; + } +} + +/*--------------------------------------------------------------------------- + * gu2_enable_compression + * + * This is a private routine to this module (not exposed in the Durango API). + * It enables display compression. + *--------------------------------------------------------------------------- + */ +void +gu2_enable_compression(void) +{ + unsigned long unlock, gcfg, temp; + + /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */ + + if (READ_REG32(MDC_FB_ST_OFFSET) & 0x0FFFFFFF) + return; + + /* SET GLOBAL INDICATOR */ + + gfx_compression_active = 1; + + /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */ + /* Software is required to do this before enabling compression. */ + /* Don't want controller to think that old lines are still valid. */ + /* Writing a 1 to bit 0 of the DV Control register will force the */ + /* hardware to clear all the valid bits. */ + + temp = READ_REG32(MDC_DV_CTL); + WRITE_REG32(MDC_DV_CTL, temp | 0x00000001); + + /* TURN ON COMPRESSION CONTROL BITS */ + + unlock = READ_REG32(MDC_UNLOCK); + gcfg = READ_REG32(MDC_GENERAL_CFG); + gcfg |= MDC_GCFG_CMPE | MDC_GCFG_DECE; + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + WRITE_REG32(MDC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gu2_disable_compression + * + * This is a private routine to this module (not exposed in the Durango API). + * It disables display compression. + *--------------------------------------------------------------------------- + */ +void +gu2_disable_compression(void) +{ + unsigned long unlock, gcfg; + + /* SET GLOBAL INDICATOR */ + + gfx_compression_active = 0; + + /* TURN OFF COMPRESSION CONTROL BITS */ + + unlock = READ_REG32(MDC_UNLOCK); + gcfg = READ_REG32(MDC_GENERAL_CFG); + gcfg &= ~(MDC_GCFG_CMPE | MDC_GCFG_DECE); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + WRITE_REG32(MDC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_enable + * + * This routine enables or disables display compression. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_compression_enable(int enable) +#else +int +gfx_set_compression_enable(int enable) +#endif +{ + /* SET GLOBAL VARIABLE FOR INDENDED STATE */ + /* Compression can only be enabled for non-zero start address values. */ + /* Keep state to enable compression on start address changes. */ + + gfx_compression_enabled = enable; + if (enable) + gu2_enable_compression(); + else + gu2_disable_compression(); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_offset + * + * This routine sets the base offset for the compression buffer. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_compression_offset(unsigned long offset) +#else +int +gfx_set_compression_offset(unsigned long offset) +#endif +{ + unsigned long lock; + + /* MUST BE 16-BYTE ALIGNED FOR REDCLOUD */ + + if (offset & 0x0F) + return (1); + + /* SET REGISTER VALUE */ + + lock = READ_REG32(MDC_UNLOCK); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_CB_ST_OFFSET, offset & 0x0FFFFFFF); + WRITE_REG32(MDC_UNLOCK, lock); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_pitch + * + * This routine sets the pitch, in bytes, of the compression buffer. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_compression_pitch(unsigned short pitch) +#else +int +gfx_set_compression_pitch(unsigned short pitch) +#endif +{ + unsigned long lock, line_delta; + + lock = READ_REG32(MDC_UNLOCK); + + /* SET REGISTER VALUE */ + + line_delta = READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF; + line_delta |= (((unsigned long)pitch << 13) & 0xFFFF0000); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GFX_PITCH, line_delta); + WRITE_REG32(MDC_UNLOCK, lock); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_size + * + * This routine sets the line size of the compression buffer, which is the + * maximum number of bytes allowed to store a compressed line. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_compression_size(unsigned short size) +#else +int +gfx_set_compression_size(unsigned short size) +#endif +{ + unsigned long lock, buf_size; + + /* SUBTRACT 32 FROM SIZE */ + /* The display controller will actually write */ + /* 4 extra QWords. So, if we assume that "size" */ + /* refers to the allocated size, we must subtract */ + /* 32 bytes. */ + + size -= 32; + + /* SET REGISTER VALUE */ + + lock = READ_REG32(MDC_UNLOCK); + buf_size = READ_REG32(MDC_LINE_SIZE) & 0xFF80FFFF; + buf_size |= ((((unsigned long)size >> 3) + 1) & 0x7F) << 16; + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_LINE_SIZE, buf_size); + WRITE_REG32(MDC_UNLOCK, lock); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_format". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_video_format(unsigned long format) +#else +void +gfx_set_display_video_format(unsigned long format) +#endif +{ + unsigned long gcfg, lock; + + lock = READ_REG32(MDC_UNLOCK); + gcfg = READ_REG32(MDC_GENERAL_CFG); + + switch (format) { + case VIDEO_FORMAT_Y0Y1Y2Y3: + case VIDEO_FORMAT_Y3Y2Y1Y0: + case VIDEO_FORMAT_Y1Y0Y3Y2: + case VIDEO_FORMAT_Y1Y2Y3Y0: + + gcfg |= MDC_GCFG_YUVM; + break; + + default: + + gcfg &= ~MDC_GCFG_YUVM; + break; + } + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_enable". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_video_enable(int enable) +#else +void +gfx_set_display_video_enable(int enable) +#endif +{ + unsigned long lock, gcfg, dcfg; + + /* READ CURRENT VALUES */ + + lock = READ_REG32(MDC_UNLOCK); + gcfg = READ_REG32(MDC_GENERAL_CFG); + dcfg = READ_REG32(MDC_DISPLAY_CFG); + + /* SET OR CLEAR VIDEO ENABLE IN GENERAL_CFG */ + + if (enable) + gcfg |= MDC_GCFG_VIDE; + else + gcfg &= ~MDC_GCFG_VIDE; + + /* WRITE REGISTER */ + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_size". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_video_size(unsigned short width, unsigned short height) +#else +void +gfx_set_display_video_size(unsigned short width, unsigned short height) +#endif +{ + unsigned long lock, value, yuv_420; + + /* READ CURRENT VALUES */ + + lock = READ_REG32(MDC_UNLOCK); + value = READ_REG32(MDC_LINE_SIZE) & 0x00FFFFFF; + yuv_420 = READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_YUVM; + + /* LINE WIDTH IS 1/4 FOR 4:2:0 VIDEO */ + /* All data must be 32-byte aligned. */ + + if (yuv_420) { + width >>= 1; + width = (width + 7) & 0xFFF8; + } else { + width <<= 1; + width = (width + 31) & 0xFFE0; + } + + /* ONLY THE LINE SIZE IS PROGRAMMED IN THE DISPLAY CONTROLLER */ + + value |= ((unsigned long)width << 21); + + /* WRITE THE REGISTER */ + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_LINE_SIZE, value); + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_offset". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_video_offset(unsigned long offset) +#else +void +gfx_set_display_video_offset(unsigned long offset) +#endif +{ + unsigned long lock; + + lock = READ_REG32(MDC_UNLOCK); + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + offset &= 0x0FFFFFF0; + WRITE_REG32(MDC_VID_Y_ST_OFFSET, offset); + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by gfx_set_video_yuv_offsets. It abstracts the version + * of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_video_yuv_offsets(unsigned long yoffset, + unsigned long uoffset, + unsigned long voffset) +#else +void +gfx_set_display_video_yuv_offsets(unsigned long yoffset, + unsigned long uoffset, + unsigned long voffset) +#endif +{ + unsigned long lock; + + lock = READ_REG32(MDC_UNLOCK); + + yoffset &= 0x0FFFFFF0; + uoffset &= 0x0FFFFFF8; + voffset &= 0x0FFFFFF8; + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_VID_Y_ST_OFFSET, yoffset); + WRITE_REG32(MDC_VID_U_ST_OFFSET, uoffset); + WRITE_REG32(MDC_VID_V_ST_OFFSET, voffset); + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by gfx_set_video_yuv_pitch. It abstracts the version + * of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch) +#else +void +gfx_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch) +#endif +{ + unsigned long lock, pitch; + + lock = READ_REG32(MDC_UNLOCK); + + pitch = ((uvpitch << 13) & 0xFFFF0000) | ((ypitch >> 3) & 0xFFFF); + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_VID_YUV_PITCH, pitch); + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_downscale (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by gfx_set_video_vertical_downscale. It abstracts the version + * of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_video_downscale(unsigned short srch, unsigned short dsth) +#else +void +gfx_set_display_video_downscale(unsigned short srch, unsigned short dsth) +#endif +{ + unsigned long lock, delta; + + lock = READ_REG32(MDC_UNLOCK); + + /* CLIP SCALING LIMITS */ + /* Upscaling is performed in a separate function. */ + /* Maximum scale ratio is 1/2. */ + + if (dsth > srch || dsth <= (srch >> 1)) + delta = 0; + else + delta = (((unsigned long)srch << 14) / (unsigned long)dsth) << 18; + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_VID_DS_DELTA, delta); + WRITE_REG32(MDC_UNLOCK, lock); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_downscale_enable (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_vertical_downscale_enable". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_set_display_video_vertical_downscale_enable(int enable) +#else +void +gfx_set_display_video_vertical_downscale_enable(int enable) +#endif +{ + unsigned long gcfg, unlock; + + unlock = READ_REG32(MDC_UNLOCK); + gcfg = READ_REG32(MDC_GENERAL_CFG); + + if (enable) + gcfg |= MDC_GCFG_VDSE; + else + gcfg &= ~MDC_GCFG_VDSE; + + WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE); + WRITE_REG32(MDC_GENERAL_CFG, gcfg); + WRITE_REG32(MDC_UNLOCK, unlock); +} + +/*--------------------------------------------------------------------------- + * gfx_test_timing_active + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_test_timing_active(void) +#else +int +gfx_test_timing_active(void) +#endif +{ + if (READ_REG32(MDC_DISPLAY_CFG) & MDC_DCFG_TGEN) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_test_vertical_active + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_test_vertical_active(void) +#else +int +gfx_test_vertical_active(void) +#endif +{ + if (READ_REG32(MDC_LINE_CNT_STATUS) & MDC_LNCNT_VNA) + return (0); + + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_wait_vertical_blank + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_wait_vertical_blank(void) +#else +int +gfx_wait_vertical_blank(void) +#endif +{ + if (gfx_test_timing_active()) { + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_enable_panning + * + * This routine enables the panning when the Mode is bigger than the panel + * size. + *--------------------------------------------------------------------------- + */ + +#if GFX_DISPLAY_DYNAMIC +void +gu2_enable_panning(int x, int y) +#else +void +gfx_enable_panning(int x, int y) +#endif +{ + unsigned long modeBytesPerPixel; + unsigned long modeBytesPerScanline = 0; + unsigned long startAddress = 0; + + modeBytesPerPixel = (gbpp + 7) / 8; + modeBytesPerScanline = (READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF) << 3; + + /* TEST FOR NO-WORK */ + + if (x >= DeltaX && x < ((int)PanelWidth + DeltaX) && + y >= DeltaY && y < ((int)PanelHeight + DeltaY)) + return; + + /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */ + /* Test the boundary conditions for each coordinate and update */ + /* all variables and the starting offset accordingly. */ + + if (x < DeltaX) + DeltaX = x; + + else if (x >= (DeltaX + (int)PanelWidth)) + DeltaX = x - (int)PanelWidth + 1; + + if (y < DeltaY) + DeltaY = y; + + else if (y >= (DeltaY + (int)PanelHeight)) + DeltaY = y - (int)PanelHeight + 1; + + /* CALCULATE THE START OFFSET */ + + startAddress = + (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline); + + gfx_set_display_offset(startAddress); + + /* SET PANEL COORDINATES */ + /* Panel's x position must be DWORD aligned */ + + panelTop = DeltaY; + panelLeft = DeltaX * modeBytesPerPixel; + + if (panelLeft & 3) + panelLeft = (panelLeft & 0xFFFFFFFC) + 4; + + panelLeft /= modeBytesPerPixel; +} + +/*--------------------------------------------------------------------------- + * gfx_set_fixed_timings + *--------------------------------------------------------------------------- + */ + +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_fixed_timings(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +#else +int +gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +#endif +{ + unsigned int mode; + + ModeWidth = width; + ModeHeight = height; + PanelWidth = (unsigned short)panelResX; + PanelHeight = (unsigned short)panelResY; + PanelEnable = 1; + + /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ + for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) { + if ((FixedParams[mode].xres == width) && + (FixedParams[mode].yres == height) && + (FixedParams[mode].panelresx == panelResX) && + (FixedParams[mode].panelresy == panelResY)) { + + /* SET THE 92xx FOR THE SELECTED MODE */ + FIXEDTIMINGS *fmode = &FixedParams[mode]; + + gfx_set_display_timings(bpp, 3, fmode->hactive, fmode->hblankstart, + fmode->hsyncstart, fmode->hsyncend, + fmode->hblankend, fmode->htotal, + fmode->vactive, fmode->vblankstart, + fmode->vsyncstart, fmode->vsyncend, + fmode->vblankend, fmode->vtotal, + fmode->frequency); + + return (1); + } /* end if() */ + } /* end for() */ + + return (-1); +} + +/*--------------------------------------------------------------------------- + * gfx_set_panel_present + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_set_panel_present(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +#else +int +gfx_set_panel_present(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +#endif +{ + /* SET VALID BPP */ + /* 16BPP is the default. */ + + if (bpp != 8 && bpp != 12 && bpp != 15 && bpp != 16 && bpp != 32) + bpp = 16; + + /* RECORD PANEL PARAMETERS */ + /* This routine does not touch any panel timings. It is used when custom panel */ + /* settings are set up in advance by the BIOS or an application, but the */ + /* application still requires access to other panel functionality provided by */ + /* Durango (i.e. panning). */ + + ModeWidth = width; + ModeHeight = height; + PanelWidth = (unsigned short)panelResX; + PanelHeight = (unsigned short)panelResY; + PanelEnable = 1; + gbpp = bpp; + + /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */ + + gfx_set_display_bpp(bpp); + + return (GFX_STATUS_OK); +} + +/* THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: */ + +/*--------------------------------------------------------------------------- + * gfx_get_display_pitch + * + * This routine returns the current pitch of the frame buffer, in bytes. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_display_pitch(void) +#else +unsigned short +gfx_get_display_pitch(void) +#endif +{ + return ((unsigned short)(READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF) << 3); +} + +/*---------------------------------------------------------------------------- + * gfx_mode_frequency_supported + * + * This routine examines if the requested mode with pixel frequency is supported. + * + * Returns >0 if successful , <0 if freq. could not be found and matched. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_mode_frequency_supported(int xres, int yres, int bpp, + unsigned long frequency) +#else +int +gfx_mode_frequency_supported(int xres, int yres, int bpp, + unsigned long frequency) +#endif +{ + unsigned int index; + unsigned long value; + unsigned long bpp_flag = 0; + + switch (bpp) { + case 8: + bpp_flag = GFX_MODE_8BPP; + break; + case 12: + bpp_flag = GFX_MODE_12BPP; + break; + case 15: + bpp_flag = GFX_MODE_15BPP; + break; + case 16: + bpp_flag = GFX_MODE_16BPP; + break; + case 32: + bpp_flag = GFX_MODE_24BPP; + break; + default: + bpp_flag = GFX_MODE_8BPP; + break; + } + + for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) { + if ((DisplayParams[index].hactive == (unsigned int)xres) && + (DisplayParams[index].vactive == (unsigned int)yres) && + (DisplayParams[index].flags & bpp_flag) && + (DisplayParams[index].frequency == frequency)) { + int hz = 0; + + value = DisplayParams[index].flags; + + if (value & GFX_MODE_60HZ) + hz = 60; + else if (value & GFX_MODE_70HZ) + hz = 70; + else if (value & GFX_MODE_72HZ) + hz = 72; + else if (value & GFX_MODE_75HZ) + hz = 75; + else if (value & GFX_MODE_85HZ) + hz = 85; + return (hz); + } + } + + return (-1); +} + +/*---------------------------------------------------------------------------- + * gfx_refreshrate_from_frequency + * + * This routine maps the frequency to close match refresh rate + * + * Returns . + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +#else +int +gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +#endif +{ + unsigned int index, closematch = 0; + unsigned long value; + unsigned long bpp_flag = 0; + long min, diff; + + *hz = 60; + + switch (bpp) { + case 8: + bpp_flag = GFX_MODE_8BPP; + break; + case 12: + bpp_flag = GFX_MODE_12BPP; + break; + case 15: + bpp_flag = GFX_MODE_15BPP; + break; + case 16: + bpp_flag = GFX_MODE_16BPP; + break; + case 32: + bpp_flag = GFX_MODE_24BPP; + break; + default: + bpp_flag = GFX_MODE_8BPP; + break; + } + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + min = 0x7fffffff; + for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) { + if ((DisplayParams[index].htotal == (unsigned int)xres) && + (DisplayParams[index].vtotal == (unsigned int)yres) && + (DisplayParams[index].flags & bpp_flag)) { + diff = (long)frequency - (long)DisplayParams[index].frequency; + if (diff < 0) + diff = -diff; + + if (diff < min) { + min = diff; + closematch = index; + } + } + } + + value = DisplayParams[closematch].flags; + + if (value & GFX_MODE_56HZ) + *hz = 56; + else if (value & GFX_MODE_60HZ) + *hz = 60; + else if (value & GFX_MODE_70HZ) + *hz = 70; + else if (value & GFX_MODE_72HZ) + *hz = 72; + else if (value & GFX_MODE_75HZ) + *hz = 75; + else if (value & GFX_MODE_85HZ) + *hz = 85; + + return (1); +} + +/*---------------------------------------------------------------------------- + * gfx_refreshrate_from_mode + * + * This routine is identical to the gfx_get_refreshrate_from_frequency, + * except that the active timing values are compared instead of the total + * values. Some modes (such as 70Hz and 72Hz) may be confused in this routine. + * + * Returns . + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +#else +int +gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +#endif +{ + unsigned int index, closematch = 0; + unsigned long value; + unsigned long bpp_flag = 0; + long min, diff; + + *hz = 60; + + switch (bpp) { + case 8: + bpp_flag = GFX_MODE_8BPP; + break; + case 12: + bpp_flag = GFX_MODE_12BPP; + break; + case 15: + bpp_flag = GFX_MODE_15BPP; + break; + case 16: + bpp_flag = GFX_MODE_16BPP; + break; + case 32: + bpp_flag = GFX_MODE_24BPP; + break; + default: + bpp_flag = GFX_MODE_8BPP; + break; + } + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + min = 0x7fffffff; + for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) { + if ((DisplayParams[index].hactive == (unsigned int)xres) && + (DisplayParams[index].vactive == (unsigned int)yres) && + (DisplayParams[index].flags & bpp_flag)) { + diff = (long)frequency - (long)DisplayParams[index].frequency; + if (diff < 0) + diff = -diff; + + if (diff < min) { + min = diff; + closematch = index; + } + } + } + + value = DisplayParams[closematch].flags; + + if (value & GFX_MODE_56HZ) + *hz = 56; + else if (value & GFX_MODE_60HZ) + *hz = 60; + else if (value & GFX_MODE_70HZ) + *hz = 70; + else if (value & GFX_MODE_72HZ) + *hz = 72; + else if (value & GFX_MODE_75HZ) + *hz = 75; + else if (value & GFX_MODE_85HZ) + *hz = 85; + + return (1); +} + +/*---------------------------------------------------------------------------- + * gfx_get_frequency_from_refreshrate + * + * This routine maps the refresh rate to the closest matching PLL frequency. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, + int *frequency) +#else +int +gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, + int *frequency) +#endif +{ + int retval = -1; + unsigned long hz_flag = 0; + unsigned long index, bpp_flag = 0; + + *frequency = 0; + + if (hz == 60) + hz_flag = GFX_MODE_60HZ; + else if (hz == 70) + hz_flag = GFX_MODE_70HZ; + else if (hz == 72) + hz_flag = GFX_MODE_72HZ; + else if (hz == 75) + hz_flag = GFX_MODE_75HZ; + else if (hz == 85) + hz_flag = GFX_MODE_85HZ; + + switch (bpp) { + case 8: + bpp_flag = GFX_MODE_8BPP; + break; + case 12: + bpp_flag = GFX_MODE_12BPP; + break; + case 15: + bpp_flag = GFX_MODE_15BPP; + break; + case 16: + bpp_flag = GFX_MODE_16BPP; + break; + case 32: + bpp_flag = GFX_MODE_24BPP; + break; + default: + bpp_flag = GFX_MODE_8BPP; + break; + } + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) { + if ((DisplayParams[index].hactive == (unsigned short)xres) && + (DisplayParams[index].vactive == (unsigned short)yres) && + (DisplayParams[index].flags & bpp_flag) && + (DisplayParams[index].flags & hz_flag)) { + *frequency = DisplayParams[index].frequency; + retval = 1; + } + } + return retval; +} + +/*--------------------------------------------------------------------------- + * gfx_get_max_supported_pixel_clock + * + * This routine returns the maximum recommended speed for the pixel clock. The + * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum + * floating point pixel clock speed. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_max_supported_pixel_clock(void) +#else +unsigned long +gfx_get_max_supported_pixel_clock(void) +#endif +{ + return 229500; +} + +/*---------------------------------------------------------------------------- + * gfx_get_display_mode + * + * This routine gets the specified display mode. + * + * Returns >0 if successful and mode returned, <0 if mode could not be found. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_display_mode(int *xres, int *yres, int *bpp, int *hz) +#else +int +gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz) +#endif +{ + unsigned int mode = 0; + unsigned long pll_freq = 0, bpp_flag = 0; + + *xres = gfx_get_hactive(); + *yres = gfx_get_vactive(); + *bpp = gfx_get_display_bpp(); + pll_freq = gfx_get_clock_frequency(); + + /* SET BPP FLAGS TO LIMIT MODE SELECTION */ + + switch (*bpp) { + case 8: + bpp_flag = GFX_MODE_8BPP; + break; + case 12: + bpp_flag = GFX_MODE_12BPP; + break; + case 15: + bpp_flag = GFX_MODE_15BPP; + break; + case 16: + bpp_flag = GFX_MODE_16BPP; + break; + case 32: + bpp_flag = GFX_MODE_24BPP; + break; + default: + bpp_flag = GFX_MODE_8BPP; + break; + } + + for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) { + if ((DisplayParams[mode].hactive == (unsigned int)*xres) && + (DisplayParams[mode].vactive == (unsigned int)*yres) && + (DisplayParams[mode].frequency == pll_freq) && + (DisplayParams[mode].flags & bpp_flag)) { + + pll_freq = DisplayParams[mode].flags; + + if (pll_freq & GFX_MODE_56HZ) + *hz = 56; + else if (pll_freq & GFX_MODE_60HZ) + *hz = 60; + else if (pll_freq & GFX_MODE_70HZ) + *hz = 70; + else if (pll_freq & GFX_MODE_72HZ) + *hz = 72; + else if (pll_freq & GFX_MODE_75HZ) + *hz = 75; + else if (pll_freq & GFX_MODE_85HZ) + *hz = 85; + + return (1); + } + } + return (-1); +} + +/*---------------------------------------------------------------------------- + * GFX_GET_DISPLAY_DETAILS + * + * This routine gets the specified display mode. + * + * Returns 1 if successful, 0 if mode could not be get. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) +#else +int +gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) +#endif +{ + if (mode < NUM_RC_DISPLAY_MODES) { + if (DisplayParams[mode].flags & GFX_MODE_56HZ) + *hz = 56; + else if (DisplayParams[mode].flags & GFX_MODE_60HZ) + *hz = 60; + else if (DisplayParams[mode].flags & GFX_MODE_70HZ) + *hz = 70; + else if (DisplayParams[mode].flags & GFX_MODE_72HZ) + *hz = 72; + else if (DisplayParams[mode].flags & GFX_MODE_75HZ) + *hz = 75; + else if (DisplayParams[mode].flags & GFX_MODE_85HZ) + *hz = 85; + + *xres = DisplayParams[mode].hactive; + *yres = DisplayParams[mode].vactive; + + if (DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE) + *xres >>= 1; + if (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE) + *yres >>= 1; + + return (1); + } + return (0); +} + +/*---------------------------------------------------------------------------- + * GFX_GET_DISPLAY_MODE_COUNT + * + * This routine gets the number of available display modes. + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_display_mode_count(void) +#else +int +gfx_get_display_mode_count(void) +#endif +{ + return (NUM_RC_DISPLAY_MODES); +} + +/*---------------------------------------------------------------------------- + * gfx_get_frame_buffer_line_size + * + * Returns the current frame buffer line size, in bytes + *---------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_frame_buffer_line_size(void) +#else +unsigned long +gfx_get_frame_buffer_line_size(void) +#endif +{ + return ((READ_REG32(MDC_LINE_SIZE) & 0x7FF) << 3); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hactive + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_hactive(void) +#else +unsigned short +gfx_get_hactive(void) +#endif +{ + return ((unsigned short)((READ_REG32(MDC_H_ACTIVE_TIMING) & 0x0FF8) + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hsync_start + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_hsync_start(void) +#else +unsigned short +gfx_get_hsync_start(void) +#endif +{ + return ((unsigned short)((READ_REG32(MDC_H_SYNC_TIMING) & 0x0FF8) + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hsync_end + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_hsync_end(void) +#else +unsigned short +gfx_get_hsync_end(void) +#endif +{ + return ((unsigned short)(((READ_REG32(MDC_H_SYNC_TIMING) >> 16) & 0x0FF8) + + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_htotal + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_htotal(void) +#else +unsigned short +gfx_get_htotal(void) +#endif +{ + return ((unsigned short)(((READ_REG32(MDC_H_ACTIVE_TIMING) >> 16) & 0x0FF8) + + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vactive + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_vactive(void) +#else +unsigned short +gfx_get_vactive(void) +#endif +{ + return ((unsigned short)((READ_REG32(MDC_V_ACTIVE_TIMING) & 0x07FF) + 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vsync_end + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_vsync_end(void) +#else +unsigned short +gfx_get_vsync_end(void) +#endif +{ + return ((unsigned short)(((READ_REG32(MDC_V_SYNC_TIMING) >> 16) & 0x07FF) + + 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vtotal + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_vtotal(void) +#else +unsigned short +gfx_get_vtotal(void) +#endif +{ + return ((unsigned short)(((READ_REG32(MDC_V_ACTIVE_TIMING) >> 16) & 0x07FF) + + 1)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_bpp + * + * This routine returns the current color depth of the active display. + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_display_bpp(void) +#else +unsigned short +gfx_get_display_bpp(void) +#endif +{ + unsigned long dcfg = READ_REG32(MDC_DISPLAY_CFG); + + switch ((dcfg & MDC_DCFG_DISP_MODE_MASK) >> 8) { + case 0: + return (8); + case 2: + return (32); + + case 1: + + switch ((dcfg & MDC_DCFG_16BPP_MODE_MASK) >> 10) { + case 0: + return (16); + case 1: + return (15); + case 2: + return (12); + default: + return (0); + } + } + + /* INVALID SETTING */ + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vline + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_vline(void) +#else +unsigned short +gfx_get_vline(void) +#endif +{ + unsigned short current_scan_line; + + /* Read similar value twice to ensure that the value is not transitioning */ + + do + current_scan_line = + (unsigned short)(READ_REG32(MDC_LINE_CNT_STATUS) & + MDC_LNCNT_V_LINE_CNT); + while (current_scan_line != + (unsigned short)(READ_REG32(MDC_LINE_CNT_STATUS) & + MDC_LNCNT_V_LINE_CNT)); + + return (current_scan_line >> 16); +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_offset + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_display_offset(void) +#else +unsigned long +gfx_get_display_offset(void) +#endif +{ + return (READ_REG32(MDC_FB_ST_OFFSET) & 0x0FFFFFFF); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_offset + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_cursor_offset(void) +#else +unsigned long +gfx_get_cursor_offset(void) +#endif +{ + return (READ_REG32(MDC_CURS_ST_OFFSET) & 0x0FFFFFFF); +} + +#if GFX_READ_ROUTINES + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +/*--------------------------------------------------------------------------- + * gfx_get_hblank_start + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_hblank_start(void) +#else +unsigned short +gfx_get_hblank_start(void) +#endif +{ + return ((unsigned short)((READ_REG32(MDC_H_BLANK_TIMING) & 0x0FF8) + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hblank_end + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_hblank_end(void) +#else +unsigned short +gfx_get_hblank_end(void) +#endif +{ + return ((unsigned short)(((READ_REG32(MDC_H_BLANK_TIMING) >> 16) & 0x0FF8) + + 8)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vblank_start + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_vblank_start(void) +#else +unsigned short +gfx_get_vblank_start(void) +#endif +{ + return ((unsigned short)((READ_REG32(MDC_V_BLANK_TIMING) & 0x07FF) + 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vsync_start + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_vsync_start(void) +#else +unsigned short +gfx_get_vsync_start(void) +#endif +{ + return ((unsigned short)((READ_REG32(MDC_V_SYNC_TIMING) & 0x07FF) + 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vblank_end + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_vblank_end(void) +#else +unsigned short +gfx_get_vblank_end(void) +#endif +{ + return ((unsigned short)(((READ_REG32(MDC_V_BLANK_TIMING) >> 16) & 0x07FF) + + 1)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_palette_entry + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_display_palette_entry(unsigned long index, unsigned long *palette) +#else +int +gfx_get_display_palette_entry(unsigned long index, unsigned long *palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_REG32(MDC_PAL_ADDRESS, index); + *palette = READ_REG32(MDC_PAL_DATA); + + return 0; +} + +/*----------------------------------------------------------------------------- + * gfx_get_display_palette + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_get_display_palette(unsigned long *palette) +#else +void +gfx_get_display_palette(unsigned long *palette) +#endif +{ + unsigned long i; + + WRITE_REG32(MDC_PAL_ADDRESS, 0); + for (i = 0; i < 256; i++) { + palette[i] = READ_REG32(MDC_PAL_DATA); + } +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_enable + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_cursor_enable(void) +#else +unsigned long +gfx_get_cursor_enable(void) +#endif +{ + return (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_CURE); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_position + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_cursor_position(void) +#else +unsigned long +gfx_get_cursor_position(void) +#endif +{ + return ((READ_REG32(MDC_CURSOR_X) & 0x07FF) | + ((READ_REG32(MDC_CURSOR_Y) << 16) & 0x03FF0000)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_offset + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_cursor_clip(void) +#else +unsigned long +gfx_get_cursor_clip(void) +#endif +{ + return (((READ_REG32(MDC_CURSOR_X) >> 11) & 0x03F) | + ((READ_REG32(MDC_CURSOR_Y) << 5) & 0x3F0000)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cursor_color + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_cursor_color(int color) +#else +unsigned long +gfx_get_cursor_color(int color) +#endif +{ + if (color) { + WRITE_REG32(MDC_PAL_ADDRESS, 0x101); + } else { + WRITE_REG32(MDC_PAL_ADDRESS, 0x100); + } + return READ_REG32(MDC_PAL_DATA); +} + +/*----------------------------------------------------------------------------- + * gfx_get_icon_enable + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_icon_enable(void) +#else +unsigned long +gfx_get_icon_enable(void) +#endif +{ + return (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_ICNE); +} + +/*----------------------------------------------------------------------------- + * gfx_get_icon_offset + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_icon_offset(void) +#else +unsigned long +gfx_get_icon_offset(void) +#endif +{ + return (READ_REG32(MDC_ICON_ST_OFFSET) & 0x0FFFFFFF); +} + +/*----------------------------------------------------------------------------- + * gfx_get_icon_position + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_icon_position(void) +#else +unsigned long +gfx_get_icon_position(void) +#endif +{ + return (READ_REG32(MDC_ICON_X) & 0x07FF); +} + +/*----------------------------------------------------------------------------- + * gfx_get_icon_color + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_icon_color(int color) +#else +unsigned long +gfx_get_icon_color(int color) +#endif +{ + if (color >= 3) + return 0; + + WRITE_REG32(MDC_PAL_ADDRESS, 0x102 + color); + + return READ_REG32(MDC_PAL_DATA); +} + +/*----------------------------------------------------------------------------- + * gfx_get_compression_enable + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_compression_enable(void) +#else +int +gfx_get_compression_enable(void) +#endif +{ + if (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_CMPE) + return (1); + + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_compression_offset + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_compression_offset(void) +#else +unsigned long +gfx_get_compression_offset(void) +#endif +{ + return (READ_REG32(MDC_CB_ST_OFFSET) & 0x007FFFFF); +} + +/*----------------------------------------------------------------------------- + * gfx_get_compression_pitch + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_compression_pitch(void) +#else +unsigned short +gfx_get_compression_pitch(void) +#endif +{ + unsigned short pitch; + + pitch = (unsigned short)(READ_REG32(MDC_GFX_PITCH) >> 16); + return (pitch << 3); +} + +/*----------------------------------------------------------------------------- + * gfx_get_compression_size + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned short +gu2_get_compression_size(void) +#else +unsigned short +gfx_get_compression_size(void) +#endif +{ + unsigned short size; + + size = (unsigned short)((READ_REG32(MDC_LINE_SIZE) >> 16) & 0x7F) - 1; + return ((size << 3) + 32); +} + +/*----------------------------------------------------------------------------- + * gfx_get_valid_bit + *----------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_valid_bit(int line) +#else +int +gfx_get_valid_bit(int line) +#endif +{ + unsigned long offset; + int valid; + + offset = READ_REG32(MDC_PHY_MEM_OFFSET) & 0xFF000000; + offset |= line; + + WRITE_REG32(MDC_PHY_MEM_OFFSET, offset); + valid = (int)READ_REG32(MDC_DV_ACC) & 2; + + if (valid) + return 1; + return 0; +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_get_video_offset". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_display_video_offset(void) +#else +unsigned long +gfx_get_display_video_offset(void) +#endif +{ + return (READ_REG32(MDC_VID_Y_ST_OFFSET) & 0x0FFFFFFF); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_get_video_yuv_offsets". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_get_display_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset) +#else +void +gfx_get_display_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset) +#endif +{ + *yoffset = (READ_REG32(MDC_VID_Y_ST_OFFSET) & 0x0FFFFFFF); + *uoffset = (READ_REG32(MDC_VID_U_ST_OFFSET) & 0x0FFFFFFF); + *voffset = (READ_REG32(MDC_VID_V_ST_OFFSET) & 0x0FFFFFFF); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_get_video_yuv_pitch". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +void +gu2_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch) +#else +void +gfx_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch) +#endif +{ + unsigned long pitch = READ_REG32(MDC_VID_YUV_PITCH); + + *ypitch = ((pitch & 0xFFFF) << 3); + *uvpitch = (pitch >> 13) & 0x7FFF8; +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_downscale_delta (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_get_video_downscale_delta". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_display_video_downscale_delta(void) +#else +unsigned long +gfx_get_display_video_downscale_delta(void) +#endif +{ + return (READ_REG32(MDC_VID_DS_DELTA) >> 18); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_downscale_enable (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_get_video_vertical_downscale_enable". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +int +gu2_get_display_video_downscale_enable(void) +#else +int +gfx_get_display_video_downscale_enable(void) +#endif +{ + return ((int)((READ_REG32(MDC_GENERAL_CFG) >> 19) & 1)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_get_video_size". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +#if GFX_DISPLAY_DYNAMIC +unsigned long +gu2_get_display_video_size(void) +#else +unsigned long +gfx_get_display_video_size(void) +#endif +{ + /* RETURN THE LINE SIZE, AS THIS IS ALL THAT IS AVAILABLE */ + + return ((READ_REG32(MDC_LINE_SIZE) >> 21) & 0x000007FF); +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/durango.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/durango.c new file mode 100644 index 000000000..56bc65a91 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/durango.c @@ -0,0 +1,627 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/durango.c,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: durango.c $ + * + * This is the main file used to add Durango graphics support to a software + * project. The main reason to have a single file include the other files + * is that it centralizes the location of the compiler options. This file + * should be tuned for a specific implementation, and then modified as needed + * for new Durango releases. The releases.txt file indicates any updates to + * this main file, such as a new definition for a new hardware platform. + * + * In other words, this file should be copied from the Durango source files + * once when a software project starts, and then maintained as necessary. + * It should not be recopied with new versions of Durango unless the + * developer is willing to tune the file again for the specific project. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* COMPILER OPTIONS + * These compiler options specify how the Durango routines are compiled + * for the different hardware platforms. For best performance, a driver + * would build for a specific platform. The "dynamic" switches are set + * by diagnostic applications such as Darwin that will run on a variety + * of platforms and use the appropriate code at runtime. Each component + * may be separately dynamic, so that a driver has the option of being + * tuned for a specific 2D accelerator, but will still run with a variety + * of chipsets. + */ + +#define GFX_DISPLAY_DYNAMIC 1 /* runtime selection */ +#define GFX_DISPLAY_GU1 1 /* 1st generation display controller */ +#define GFX_DISPLAY_GU2 1 /* 2nd generation display controller */ + +#define GFX_INIT_DYNAMIC 1 /* runtime selection */ +#define GFX_INIT_GU1 1 /* Geode family */ +#define GFX_INIT_GU2 1 /* Redcloud */ + +#define GFX_MSR_DYNAMIC 1 /* runtime selection */ +#define GFX_MSR_REDCLOUD 1 /* Redcloud */ + +#define GFX_2DACCEL_DYNAMIC 1 /* runtime selection */ +#define GFX_2DACCEL_GU1 1 /* 1st generation 2D accelerator */ +#define GFX_2DACCEL_GU2 1 /* 2nd generation 2D accelerator */ + +#define GFX_VIDEO_DYNAMIC 1 /* runtime selection */ +#define GFX_VIDEO_CS5530 1 /* support for CS5530 */ +#define GFX_VIDEO_SC1200 1 /* support for SC1200 */ +#define GFX_VIDEO_REDCLOUD 1 /* support for Redcloud */ + +#define GFX_VIP_DYNAMIC 1 /* runtime selection */ +#define GFX_VIP_SC1200 1 /* support for SC1200 */ + +#define GFX_DECODER_DYNAMIC 1 /* runtime selection */ +#define GFX_DECODER_SAA7114 1 /* Philips SAA7114 decoder */ + +#define GFX_TV_DYNAMIC 1 /* runtime selection */ +#define GFX_TV_FS451 1 /* Focus Enhancements FS450 */ +#define GFX_TV_SC1200 1 /* SC1200 integrated TV encoder */ + +#define GFX_I2C_DYNAMIC 1 /* runtime selection */ +#define GFX_I2C_ACCESS 1 /* support for ACCESS.BUS */ +#define GFX_I2C_GPIO 1 /* support for CS5530 GPIOs */ + +#define GFX_VGA_DYNAMIC 1 /* runtime selection */ +#define GFX_VGA_GU1 1 /* 1st generation graphics unit */ + +#define FB4MB 1 /* Set to use 4Mb video ram for Pyramid */ + +#define GFX_NO_IO_IN_WAIT_MACROS 0 /* Set to remove I/O accesses in GP bit testing */ + +/* ROUTINES TO READ VALUES + * These are routines used by Darwin or other diagnostics to read the + * current state of the hardware. Display drivers or embedded applications can + * reduce the size of the Durango code by not including these routines. + */ +#define GFX_READ_ROUTINES 1 /* add routines to read values */ + +/* VARIABLES USED FOR RUNTIME SELECTION + * If part of the graphics subsystem is declared as dynamic, then the + * following variables are used to specify which platform has been detected. + * The variables are set in the "gfx_detect_cpu" routine. The values should + * be bit flags to allow masks to be used to check for multiple platforms. + */ + +#if GFX_DISPLAY_DYNAMIC +int gfx_display_type = 0; +#endif + +#if GFX_INIT_DYNAMIC +int gfx_init_type = 0; +#endif + +#if GFX_MSR_DYNAMIC +int gfx_msr_type = 0; +#endif + +#if GFX_2DACCEL_DYNAMIC +int gfx_2daccel_type = 0; +#endif + +#if GFX_VIDEO_DYNAMIC +int gfx_video_type = 0; +#endif + +#if GFX_VIP_DYNAMIC +int gfx_vip_type = 0; +#endif + +#if GFX_DECODER_DYNAMIC +int gfx_decoder_type = 0; +#endif + +#if GFX_TV_DYNAMIC +int gfx_tv_type = 0; +#endif + +#if GFX_I2C_DYNAMIC +int gfx_i2c_type = 0; +#endif + +#if GFX_VGA_DYNAMIC +int gfx_vga_type = 0; +#endif + +/* HEADER FILE FOR DURANGO ROUTINE DEFINITIONS + * Needed since some of the Durango routines call other Durango routines. + * Also defines the size of chipset array (GFX_CSPTR_SIZE). + */ +#include "gfx_rtns.h" /* routine definitions */ + +/* DEFINE POINTERS TO MEMORY MAPPED REGIONS + * These pointers are used by the Durango routines to access the hardware. + * The variables must be set by the project's initialization code after + * mapping the regions in the appropriate manner. + */ + +/* DEFINE VIRTUAL ADDRESSES */ +/* Note: These addresses define the starting base expected by all */ +/* Durango offsets. Under an OS that requires these pointers */ +/* to be mapped to linear addresses (i.e Windows), it may not */ +/* be possible to keep these base offsets. In these cases, */ +/* the addresses are modified to point to the beginning of the */ +/* relevant memory region and the access macros are adjusted */ +/* to subtract the offset from the default base. For example, */ +/* the register pointer could be moved to be 0x40008000, while */ +/* the WRITE_REG* macros are modified to subtract 0x8000 from */ +/* the offset. */ + +unsigned char *gfx_virt_regptr = (unsigned char *)0x40000000; +unsigned char *gfx_virt_fbptr = (unsigned char *)0x40800000; +unsigned char *gfx_virt_vidptr = (unsigned char *)0x40010000; +unsigned char *gfx_virt_vipptr = (unsigned char *)0x40015000; +unsigned char *gfx_virt_spptr = (unsigned char *)0x40000000; +unsigned char *gfx_virt_gpptr = (unsigned char *)0x40000000; + +/* DEFINE PHYSICAL ADDRESSES */ + +unsigned char *gfx_phys_regptr = (unsigned char *)0x40000000; +unsigned char *gfx_phys_fbptr = (unsigned char *)0x40800000; +unsigned char *gfx_phys_vidptr = (unsigned char *)0x40010000; +unsigned char *gfx_phys_vipptr = (unsigned char *)0x40015000; + +/* HEADER FILE FOR GRAPHICS REGISTER DEFINITIONS + * This contains only constant definitions, so it should be able to be + * included in any software project as is. + */ +#include "gfx_regs.h" /* graphics register definitions */ + +/* HEADER FILE FOR REGISTER ACCESS MACROS + * This file contains the definitions of the WRITE_REG32 and similar macros + * used by the Durango routines to access the hardware. The file assumes + * that the environment can handle 32-bit pointer access. If this is not + * the case, or if there are special requirements, then this header file + * should not be included and the project must define the macros itself. + * (A project may define WRITE_REG32 to call a routine, for example). + */ +#include "gfx_defs.h" /* register access macros */ + +/* IO MACROS AND ROUTINES + * These macros must be defined before the initialization or I2C + * routines will work properly. + */ + +#if defined(OS_WIN32) /* For Windows */ + +/* VSA II CALL */ + +void +gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ + unsigned long temp1, temp2; + + _asm { + mov dx, 0x0AC1C + mov eax, 0x0FC530007 + out dx, eax + add dl, 2 + mov ecx, msrAddr + mov cx, msrReg + in ax, dx; + ;EDX:EAX will contain MSR contents. + mov temp1, edx + mov temp2, eax + } + + *ptrHigh = temp1; + *ptrLow = temp2; +} + +void +gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ + unsigned long temp1 = *ptrHigh; + unsigned long temp2 = *ptrLow; + + _asm { + mov dx, 0x0AC1C + mov eax, 0x0FC530007 + out dx, eax i + add dl, 2 + ;ECX contains msrAddr | msrReg + mov ecx, msrAddr + mov cx, msrReg + ;<OR_mask_hi > + mov ebx, temp1 + + ;<OR_mask_hi > + mov eax, temp2 + ;<AND_mask_hi > + mov esi, 0 + ;<AND_mask_lo > + mov edi, 0 + ;MSR is written at this point + out dx, ax + } +} + +unsigned char +gfx_inb(unsigned short port) +{ + unsigned char data; + + _asm { + pushf + mov dx, port + in al, dx + mov data, al + popf + } + return (data); +} + +unsigned short +gfx_inw(unsigned short port) +{ + unsigned short data; + + _asm { + pushf + mov dx, port + in ax, dx + mov data, ax + popf + } + return (data); +} + +unsigned long +gfx_ind(unsigned short port) +{ + unsigned long data; + + _asm { + pushf + mov dx, port + in eax, dx + mov data, eax + popf + } + return (data); +} + +void +gfx_outb(unsigned short port, unsigned char data) +{ + _asm { + pushf + mov al, data + mov dx, port + out dx, al + popf + } +} + +void +gfx_outw(unsigned short port, unsigned short data) +{ + _asm { + pushf + mov ax, data + mov dx, port + out dx, ax + popf + } +} + +void +gfx_outd(unsigned short port, unsigned long data) +{ + _asm { + pushf + mov eax, data + mov dx, port + out dx, eax + popf + } +} + + +#elif defined(OS_VXWORKS) || defined (OS_LINUX) /* VxWorks and Linux */ + +#if defined(OS_LINUX) +#include "asm/msr.h" +#endif + +void +gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ + unsigned long addr, val1, val2; + + addr = msrAddr | (unsigned long)msrReg; + rdmsr(addr, val1, val2); + + *ptrHigh = val2; + *ptrLow = val1; +} + +void +gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow) +{ + unsigned long addr, val1, val2; + + val2 = *ptrHigh; + val1 = *ptrLow; + + addr = (msrAddr & 0xFFFF0000) | (unsigned long)msrReg; + wrmsr(addr, val1, val2); +} + +unsigned char +gfx_inb(unsigned short port) +{ + unsigned char value; + __asm__ volatile ("inb %1,%0":"=a" (value):"d"(port)); + + return value; +} + +unsigned short +gfx_inw(unsigned short port) +{ + unsigned short value; + __asm__ volatile ("in %1,%0":"=a" (value):"d"(port)); + + return value; +} + +unsigned long +gfx_ind(unsigned short port) +{ + unsigned long value; + __asm__ volatile ("inl %1,%0":"=a" (value):"d"(port)); + + return value; +} + +void +gfx_outb(unsigned short port, unsigned char data) +{ + __asm__ volatile ("outb %0,%1"::"a" (data), "d"(port)); +} + +void +gfx_outw(unsigned short port, unsigned short data) +{ + __asm__ volatile ("out %0,%1"::"a" (data), "d"(port)); +} + +void +gfx_outd(unsigned short port, unsigned long data) +{ + __asm__ volatile ("outl %0,%1"::"a" (data), "d"(port)); +} + +#else /* else nothing */ + +unsigned char +gfx_inb(unsigned short port) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ + return (0); +} + +unsigned short +gfx_inw(unsigned short port) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ + return (0); +} + +unsigned long +gfx_ind(unsigned short port) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ + return (0); +} + +void +gfx_outb(unsigned short port, unsigned char data) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ +} + +void +gfx_outw(unsigned short port, unsigned short data) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ +} + +void +gfx_outd(unsigned short port, unsigned long data) +{ + /* ADD OS SPECIFIC IMPLEMENTATION */ +} +#endif + +#define INB(port) gfx_inb(port) +#define INW(port) gfx_inw(port) +#define IND(port) gfx_ind(port) +#define OUTB(port, data) gfx_outb(port, data) +#define OUTW(port, data) gfx_outw(port, data) +#define OUTD(port, data) gfx_outd(port, data) + +/* INITIALIZATION ROUTINES + * These routines are used during the initialization of the driver to + * perform such tasks as detecting the type of CPU and video hardware. + * The routines require the use of IO, so the above IO routines need + * to be implemented before the initialization routines will work + * properly. + */ + +#include "gfx_init.c" + +/* INCLUDE MSR ACCESS ROUTINES */ + +#include "gfx_msr.c" + +/* INCLUDE GRAPHICS ENGINE ROUTINES + * These routines are used to program the 2D graphics accelerator. If + * the project does not use graphics acceleration (direct frame buffer + * access only), then this file does not need to be included. + */ +#include "gfx_rndr.c" /* graphics engine routines */ + +/* INCLUDE DISPLAY CONTROLLER ROUTINES + * These routines are used if the display mode is set directly. If the + * project uses VGA registers to set a display mode, then these files + * do not need to be included. + */ +#include "gfx_mode.h" /* display mode tables */ +#include "gfx_disp.c" /* display controller routines */ + +/* INCLUDE VIDEO OVERLAY ROUTINES + * These routines control the video overlay hardware. + */ +#include "gfx_vid.c" /* video overlay routines */ + +/* VIDEO PORT AND VIDEO DECODER ROUTINES + * These routines rely on the I2C routines. + */ +#include "gfx_vip.c" /* video port routines */ +#include "gfx_dcdr.c" /* video decoder routines */ + +/* I2C BUS ACCESS ROUTINES + * These routines are used by the video decoder and possibly an + * external TV encoer. + */ +#include "gfx_i2c.c" /* I2C bus access routines */ + +/* TV ENCODER ROUTINES + * This file does not need to be included if the system does not + * support TV output. + */ +#include "gfx_tv.c" /* TV encoder routines */ + +/* VGA ROUTINES + * This file is used if setting display modes using VGA registers. + */ +#include "gfx_vga.c" /* VGA routines */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_dcdr.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_dcdr.c new file mode 100644 index 000000000..187b44065 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_dcdr.c @@ -0,0 +1,600 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_dcdr.c,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: gfx_dcdr.c $ + * + * This file contains routines to control the video decoder. + * + * gfx_set_decoder_defaults + * gfx_set_decoder_analog_input + * gfx_set_decoder_brightness + * gfx_set_decoder_contrast + * gfx_set_decoder_luminance_filter + * gfx_set_decoder_hue + * gfx_set_decoder_saturation + * gfx_set_decoder_input_offset + * gfx_set_decoder_input_size + * gfx_set_decoder_output_size + * gfx_set_decoder_scale + * gfx_set_decoder_TV_standard + * gfx_set_decoder_vbi_enable + * gfx_set_decoder_vbi_format + * gfx_set_decoder_vbi_upscale + * gfx_decoder_software_reset + * gfx_decoder_detect_macrovision + * gfx_decoder_detect_video + * + * And the following routines if GFX_READ_ROUTINES is set: + * + * gfx_get_decoder_brightness + * gfx_get_decoder_contrast + * gfx_get_decoder_hue + * gfx_get_decoder_saturation + * gfx_get_decoder_input_offset + * gfx_get_decoder_input_size + * gfx_get_decoder_output_size + * gfx_get_decoder_vbi_format + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* INCLUDE SUPPORT FOR PHILIPS SAA7114 DECODER, IF SPECIFIED */ + +#if GFX_DECODER_SAA7114 +#include "saa7114.c" +#endif + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call various decoders. Currently only the Pillips */ +/* decoder is supported, but still organized to easily expand later. */ + +#if GFX_DECODER_DYNAMIC + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_defaults + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_defaults(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_defaults(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_analog_input + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_analog_input(unsigned char input) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_analog_input(input); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_brightness + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_brightness(unsigned char brightness) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_brightness(brightness); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_contrast + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_contrast(unsigned char contrast) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_contrast(contrast); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_hue + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_hue(char hue) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_hue(hue); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_saturation + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_saturation(unsigned char saturation) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_saturation(saturation); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_input_offset + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_input_offset(unsigned short x, unsigned short y) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_input_offset(x, y); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_input_size + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_input_size(unsigned short width, unsigned short height) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_input_size(width, height); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_output_size + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_output_size(unsigned short width, unsigned short height) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_output_size(width, height); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_scale + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_scale(srcw, srch, dstw, dsth); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_vbi_format + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_vbi_format(int start, int end, int format) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_vbi_format(start, end, format); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_vbi_enable + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_vbi_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_vbi_enable(enable); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_vbi_upscale + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_vbi_upscale(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_vbi_upscale(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_TV_standard + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_TV_standard(TVStandardType TVStandard) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_TV_standard(TVStandard); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_luminance_filter + *----------------------------------------------------------------------------- + */ +int +gfx_set_decoder_luminance_filter(unsigned char lufi) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_set_decoder_luminance_filter(lufi); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_decoder_software_reset + *----------------------------------------------------------------------------- + */ +int +gfx_decoder_software_reset(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_decoder_software_reset(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_decoder_detect_macrovision + *----------------------------------------------------------------------------- + */ +int +gfx_decoder_detect_macrovision(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_decoder_detect_macrovision(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_decoder_detect_video + *----------------------------------------------------------------------------- + */ +int +gfx_decoder_detect_video(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + status = saa7114_decoder_detect_video(); +# endif + return (status); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_brightness + *----------------------------------------------------------------------------- + */ +unsigned char +gfx_get_decoder_brightness(void) +{ + unsigned char brightness = 0; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + brightness = saa7114_get_decoder_brightness(); +# endif + return (brightness); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_contrast + *----------------------------------------------------------------------------- + */ +unsigned char +gfx_get_decoder_contrast(void) +{ + unsigned char contrast = 0; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + contrast = saa7114_get_decoder_contrast(); +# endif + return (contrast); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_hue + *----------------------------------------------------------------------------- + */ +char +gfx_get_decoder_hue(void) +{ + unsigned char hue = 0; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + hue = saa7114_get_decoder_hue(); +# endif + return ((char)hue); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_saturation + *----------------------------------------------------------------------------- + */ +unsigned char +gfx_get_decoder_saturation(void) +{ + unsigned char saturation = 0; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + saturation = saa7114_get_decoder_saturation(); +# endif + return (saturation); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_input_offset + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_decoder_input_offset() +{ + unsigned long offset = 0; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + offset = saa7114_get_decoder_input_offset(); +# endif + return (offset); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_input_size + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_decoder_input_size() +{ + unsigned long size = 0; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + size = saa7114_get_decoder_input_size(); +# endif + return (size); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_output_size + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_decoder_output_size() +{ + unsigned long size = 0; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + size = saa7114_get_decoder_output_size(); +# endif + return (size); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_vbi_format + *----------------------------------------------------------------------------- + */ +int +gfx_get_decoder_vbi_format(int line) +{ + int format = 0; + +# if GFX_DECODER_SAA7114 + if (gfx_decoder_type == GFX_DECODER_SAA7114) + format = saa7114_get_decoder_vbi_format(line); +# endif + return (format); +} + +#endif /* GFX_READ_ROUTINES */ + +#endif /* GFX_DECODER_DYNAMIC */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_defs.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_defs.h new file mode 100644 index 000000000..8847e5b33 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_defs.h @@ -0,0 +1,435 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_defs.h,v 1.2 2002/12/11 22:51:01 dawes Exp $ */ +/* + * $Workfile: gfx_defs.h $ + * + * This header file contains the macros used to access the hardware. These + * macros assume that 32-bit access is possible, which is true for most + * applications. Projects using 16-bit compilers (the Windows98 display + * driver) and special purpose applications (such as Darwin) need to define + * their own versions of these macros, which typically call a subroutine. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef _gfx_defs_h +#define _gfx_defs_h + +/* ACCESS TO THE CPU REGISTERS */ + +#define WRITE_REG8(offset, value) \ + (*(volatile unsigned char *)(gfx_virt_regptr + (offset))) = (value) + +#define WRITE_REG16(offset, value) \ + (*(volatile unsigned short *)(gfx_virt_regptr + (offset))) = (value) + +#define WRITE_REG32(offset, value) \ + (*(volatile unsigned long *)(gfx_virt_regptr + (offset))) = (value) + +#define READ_REG16(offset) \ + (*(volatile unsigned short *)(gfx_virt_regptr + (offset))) + +#define READ_REG32(offset) \ + (*(volatile unsigned long *)(gfx_virt_regptr + (offset))) + +/* ACCESS TO THE ACCELERATOR REGISTERS (REDCLOUD ONLY) */ + +#define WRITE_GP8(offset, value) \ + (*(volatile unsigned char *)(gfx_virt_gpptr + (offset))) = (value) + +#define WRITE_GP16(offset, value) \ + (*(volatile unsigned short *)(gfx_virt_gpptr + (offset))) = (value) + +#define WRITE_GP32(offset, value) \ + (*(volatile unsigned long *)(gfx_virt_gpptr + (offset))) = (value) + +#define READ_GP16(offset) \ + (*(volatile unsigned short *)(gfx_virt_gpptr + (offset))) + +#define READ_GP32(offset) \ + (*(volatile unsigned long *)(gfx_virt_gpptr + (offset))) + +/* ACCESS TO THE FRAME BUFFER */ + +#define WRITE_FB32(offset, value) \ + (*(volatile unsigned long *)(gfx_virt_fbptr + (offset))) = (value) + +#define WRITE_FB16(offset, value) \ + (*(volatile unsigned short *)(gfx_virt_fbptr + (offset))) = (value) + +#define WRITE_FB8(offset, value) \ + (*(volatile unsigned char *)(gfx_virt_fbptr + (offset))) = (value) + +/* ACCESS TO THE VIDEO HARDWARE */ + +#define READ_VID32(offset) \ + (*(volatile unsigned long *)(gfx_virt_vidptr + (offset))) + +#define WRITE_VID32(offset, value) \ + (*(volatile unsigned long *)(gfx_virt_vidptr + (offset))) = (value) + +/* ACCESS TO THE VIP HARDWARE */ + +#define READ_VIP32(offset) \ + (*(volatile unsigned long *)(gfx_virt_vipptr + (offset))) + +#define WRITE_VIP32(offset, value) \ + (*(volatile unsigned long *)(gfx_virt_vipptr + (offset))) = (value) + +/* ACCESS TO THE SCRATCHPAD RAM */ + +#define WRITE_SCRATCH32(offset, value) \ + (*(volatile unsigned long *)(gfx_virt_spptr + (offset))) = (value) + +#define WRITE_SCRATCH16(offset, value) \ + (*(volatile unsigned short *)(gfx_virt_spptr + (offset))) = (value) + +#define WRITE_SCRATCH8(offset, value) \ + (*(volatile unsigned char *)(gfx_virt_spptr + (offset))) = (value) + +#define READ_SCRATCH16(offset) \ + (*(volatile unsigned short *)(gfx_virt_spptr + (offset))) + +#define READ_SCRATCH32(offset) \ + (*(volatile unsigned long *)(gfx_virt_spptr + (offset))) + +/* ACCESS TO MSRS */ + +void gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow); +void gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, + unsigned long *ptrHigh, unsigned long *ptrLow); + +#define MSR_READ( MBD_MSR_CAP, address, valueHigh_ptr, valueLow_ptr ) \ + gfx_msr_asm_read( ((unsigned short)(MBD_MSR_CAP)), address, valueHigh_ptr, valueLow_ptr ) + +#define MSR_WRITE( MBD_MSR_CAP, address, valueHigh_ptr, valueLow_ptr ) \ + gfx_msr_asm_write( ((unsigned short)(MBD_MSR_CAP)), address, valueHigh_ptr, valueLow_ptr ) + +/* OPTIMIZATION MACROS */ +/* The following macros have been added to allow more complete optimization of the */ +/* bitmap-to-screen routines in Durango. These routines also allow Durango to run */ +/* properly within a 16-bit environment. */ + +/************************************************************************************ + * Macro: SET_SCRATCH_BASE + * Purpose: Record the base address of the BLT buffers. The WRITE_SCRATCH_STRINGxx + * macros assume that this address is used as the base for all writes. + * + * Arguments: + * scratch_base - offset into the GX base for the first BLT buffer byte. + ************************************************************************************/ + +#define SET_SCRATCH_BASE(scratch_base) \ + { gfx_gx1_scratch_base = (unsigned long)gfx_virt_spptr + scratch_base; } + +#ifdef GFX_OPTIMIZE_ASSEMBLY + +/************************************************************************************ + * Macro: WRITE_SCRATCH_STRING + * Purpose: Write multiple bytes to the scratchpad buffer + * + * Arguments: + * dword_bytes - number of bytes to transfer. This number will always. + * be a multiple of 4. It cannot be modified within the + * macro (ex. bytes -= 4) + * bytes_extra - number of non-DWORD aligned bytes + * array - pointer to an array of unsigned characters. + * array_offset - offset into the array from which to pull the first character. + ************************************************************************************/ + +#define WRITE_SCRATCH_STRING(dwords, bytes, array, array_offset) \ +{ \ + _asm { mov edi, gfx_gx1_scratch_base } \ + _asm { mov esi, array } \ + _asm { add esi, array_offset } \ + _asm { mov ecx, dwords } \ + _asm { shr ecx, 2 } \ + _asm { rep movsd } \ + _asm { mov ecx, bytes } \ + _asm { rep movsb } \ +} + +/************************************************************************************ + * Macro: WRITE_FRAME_BUFFER_STRING32 + * Purpose: Write multiple dwords to the Frame buffer + * + * Arguments: + * fboffset - offset to the beginning frame buffer location. + * bytes - number of bytes to transfer. This number will always. + * be a multiple of 4. It cannot be modified within the + * macro (ex. bytes -= 4) + * array - pointer to an array of unsigned characters. + * array_offset - offset into the array from which to pull the first character. + ************************************************************************************/ + +#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset) \ +{ \ + _asm { mov ecx, bytes } \ + _asm { shr ecx, 2 } \ + _asm { cld } \ + _asm { mov edi, gfx_virt_fbptr } \ + _asm { add edi, fboffset } \ + _asm { mov esi, array } \ + _asm { add esi, array_offset } \ + _asm { rep movsd } \ +} + +#else + +/************************************************************************************ + * Macro: WRITE_SCRATCH_STRING + * Purpose: Write multiple bytes to the scratchpad buffer + * + * Arguments: + * dword_bytes - number of bytes to transfer. This number will always. + * be a multiple of 4. It cannot be modified within the + * macro (ex. bytes -= 4) + * bytes_extra - number of non-DWORD aligned bytes + * array - pointer to an array of unsigned characters. + * array_offset - offset into the array from which to pull the first character. + ************************************************************************************/ + +#define WRITE_SCRATCH_STRING(dword_bytes, bytes_extra, array, array_offset) \ +{ \ + unsigned long i, j; \ + unsigned long aroffset = (unsigned long)array + (array_offset); \ + \ + /* WRITE DWORDS */ \ + \ + for (i = 0; i < dword_bytes; i += 4) \ + *((volatile unsigned long *)(gfx_gx1_scratch_base + i)) = *((unsigned long *)(aroffset + i)); \ + \ + /* WRITE BYTES */ \ + \ + j = i + bytes_extra; \ + while (i < j) \ + { \ + *((volatile unsigned char *)(gfx_gx1_scratch_base + i)) = *((unsigned char *)(aroffset + i)); \ + i++; \ + } \ +} + +/************************************************************************************ + * Macro: WRITE_FRAME_BUFFER_STRING32 + * Purpose: Write multiple dwords to the Frame buffer + * + * Arguments: + * fboffset - offset to the beginning frame buffer location. + * bytes - number of bytes to transfer. This number will always. + * be a multiple of 4. It cannot be modified within the + * macro (ex. bytes -= 4) + * array - pointer to an array of unsigned characters. + * array_offset - offset into the array from which to pull the first character. + ************************************************************************************/ + +#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset) \ +{ \ + unsigned long i; \ + unsigned long aroffset = (unsigned long)array + (array_offset); \ + for (i = 0; i < bytes; i += 4) \ + WRITE_FB32 ((fboffset) + i, *((unsigned long *)(aroffset + i))); \ +} + +#endif + +/************************************************************************************ + * Macro: WRITE_FRAME_BUFFER_STRING8 + * Purpose: Write multiple bytes to the frame buffer + * + * Arguments: + * spoffset - offset to the beginning frame buffer location. + * bytes - number of bytes to transfer. This number cannot be modified within the + * macro (ex. bytes -= 4) + * array - pointer to an array of unsigned characters. + * array_offset - offset into the array from which to pull the first character. + ************************************************************************************/ + +#define WRITE_FRAME_BUFFER_STRING8(fboffset, bytes, array, array_offset) \ +{ \ + unsigned long i; \ + unsigned long aroffset = (unsigned long)array + (array_offset); \ + for (i = 0; i < bytes; i++) \ + WRITE_FB8 ((fboffset) + i, *((unsigned char *)(aroffset + i))); \ +} + +/************************************************************************************ + * Macro: WRITE_GPREG_STRING32 + * Purpose: Write multiple dwords to one GP register. + * + * Arguments: + * regoffset - Offset of the GP register to be written. + * dwords - number of dwords to transfer. It cannot be modified within the + * macro (ex. dwords--) + * counter - name of a counter variable that can be used in a loop. This + * is used to optimize macros written in C. + * array - pointer to an array of unsigned characters. + * array_offset - offset into the array from which to pull the first character. + * temp - name of a temporary variable that can be used for calculations. + * This argument is also used for C-only macros. + ************************************************************************************/ + +#define WRITE_GPREG_STRING32(regoffset, dwords, counter, array, array_offset, temp) \ +{ \ + temp = (unsigned long)array + (array_offset); \ + for (counter = 0; counter < dwords; counter++) \ + WRITE_GP32 (regoffset, *((unsigned long *)temp + counter)); \ +} + +/************************************************************************************ + * Macro: WRITE_GPREG_STRING8 + * Purpose: Write 4 or less bytes to one GP register. + * + * Arguments: + * regoffset - Offset of the GP register to be written. + * bytes - number of bytes to transfer. This number will always. + * be less than 4. It cannot be modified within the + * macro (ex. bytes--) + * shift - name of a shift variable that can be used as a shift count. + * This variable holds the initial shift value into the GP register. + * counter - name of a counter variable that can be used in a loop. This + * is used to optimize macros written in C. + * array - pointer to an array of unsigned characters. + * array_offset - offset into the array from which to pull the first character. + * temp1 - name of a temporary variable that can be used for calculations. + * This argument is also used for C-only macros. + * temp2 - name of a temporary variable that can be used for calculations. + * This argument is also used for C-only macros. + ************************************************************************************/ +#define WRITE_GPREG_STRING8(regoffset, bytes, shift, counter, array, array_offset, temp1, temp2) \ +{ \ + if (bytes) \ + { \ + temp1 = (unsigned long)array + (array_offset); \ + temp2 = 0; \ + for (counter = 0; counter < bytes; counter++) \ + { \ + temp2 |= ((unsigned long)(*((unsigned char *)(temp1 + counter)))) << shift; \ + shift += 8; \ + } \ + WRITE_GP32 (regoffset, temp2); \ + } \ +} +#endif /* _gfx_defs_h */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_disp.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_disp.c new file mode 100644 index 000000000..54adcb3ee --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_disp.c @@ -0,0 +1,2322 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_disp.c,v 1.2 2003/01/14 09:34:34 alanh Exp $ */ +/* + * $Workfile: gfx_disp.c $ + * + * This file contains routines to program the display controller. + * + * The "disp_gu1.c" and "disp_gu2.c" files implement the following routines: + * + * gfx_get_display_mode_count + * gfx_get_display_mode + * gfx_is_display_mode_supported + * gfx_get_display_details + * gfx_set_display_mode + * gfx_set_display_bpp + * gfx_set_display_timings + * gfx_set_vtotal + * gfx_get_display_pitch + * gfx_set_display_pitch + * gfx_set_display_offset + * gfx_set_display_palette + * gfx_set_display_palette_entry + * gfx_set_cursor_enable + * gfx_set_cursor_colors + * gfx_set_cursor_position + * gfx_set_cursor_shape32 + * gfx_set_cursor_shape64 + * gfx_set_icon_enable + * gfx_set_icon_colors + * gfx_set_icon_position + * gfx_set_icon_shape64 + * gfx_set_compression_enable + * gfx_set_compression_offset + * gfx_set_compression_pitch + * gfx_set_compression_size + * gfx_set_display_priority_high + * gfx_test_timing_active + * gfx_test_vertical_active + * gfx_wait_vertical_blank + * gfx_reset_timing_lock + * + * And the following routines if GFX_READ_ROUTINES is set: + * + * gfx_get_hactive + * gfx_get_hblank_start + * gfx_get_hsync_start + * gfx_get_hsync_end + * gfx_get_hblank_end + * gfx_get_htotal + * gfx_get_vactive + * gfx_get_vblank_start + * gfx_get_vsync_start + * gfx_get_vsync_end + * gfx_get_vblank_end + * gfx_get_vtotal + * gfx_get_vline + * gfx_get_display_bpp + * gfx_get_display_offset + * gfx_get_display_palette + * gfx_get_cursor_enable + * gfx_get_cursor_base + * gfx_get_cursor_position + * gfx_get_cursor_offset + * gfx_get_cursor_color + * gfx_get_icon_enable + * gfx_get_icon_color + * gfx_get_icon_offset + * gfx_get_icon_position + * gfx_get_compression_enable + * gfx_get_compression_offset + * gfx_get_compression_pitch + * gfx_get_compression_size + * gfx_get_display_priority_high + * gfx_get_valid_bit + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +unsigned short PanelWidth = 0; +unsigned short PanelHeight = 0; +unsigned short PanelEnable = 0; +unsigned short ModeWidth; +unsigned short ModeHeight; + +int DeltaX = 0; +int DeltaY = 0; +unsigned long prevstartAddr = 0; +unsigned long panelTop = 0; +unsigned long panelLeft = 0; + +int gbpp = 8; + +int gfx_compression_enabled = 0; +int gfx_compression_active = 0; +int gfx_line_double = 0; +int gfx_pixel_double = 0; +int gfx_timing_lock = 0; +DISPLAYMODE gfx_display_mode; + +/* DISPLAY MODE TIMINGS */ + +DISPLAYMODE DisplayParams[] = { + +/* 320 x 200 */ + + {GFX_MODE_70HZ | /* refresh rate = 60 */ + GFX_MODE_8BPP | GFX_MODE_16BPP | /* 8 and 16 BPP valid */ + GFX_MODE_NEG_HSYNC | /* negative HSYNC */ + GFX_MODE_PIXEL_DOUBLE | /* Double width */ + GFX_MODE_LINE_DOUBLE, /* Double height */ + 0x140, 0x288, 0x290, 0x2F0, 0x318, 0x320, /* horizontal timings */ + 0x0C8, 0x197, 0x19C, 0x19E, 0x1BA, 0x1C1, /* vertical timings */ + 0x00192CCC, /* freq = 25.175 MHz */ + }, + +/* 320 x 240 */ + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_16BPP | /* 8 and 16 BPP valid */ + GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC | /* negative syncs */ + GFX_MODE_PIXEL_DOUBLE | /* Double width */ + GFX_MODE_LINE_DOUBLE, /* Double height */ + 0x0140, 0x0280, 0x0290, 0x02D0, 0x0348, 0x0348, /* horizontal timings */ + 0x00F0, 0x01E0, 0x01E1, 0x01E4, 0x01F4, 0x01F4, /* vertical timings */ + 0x001F8000, /* freq = 31.5 MHz */ + }, + +/* 400 x 300 */ + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_16BPP | /* 8 and 16 BPP valid */ + GFX_MODE_PIXEL_DOUBLE | /* Double width */ + GFX_MODE_LINE_DOUBLE, /* Double height */ + 0x0190, 0x0320, 0x0330, 0x0380, 0x0420, 0x0420, /* horizontal timings */ + 0x012C, 0x0258, 0x0259, 0x025C, 0x0271, 0x0271, /* vertical timings */ + 0x00318000, /* freq = 49.5 MHz */ + }, + +/* 512 x 384 */ + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_16BPP | /* 8 and 16 BPP valid */ + GFX_MODE_PIXEL_DOUBLE | /* Double width */ + GFX_MODE_LINE_DOUBLE, /* Double height */ + 0x0200, 0x0400, 0x0410, 0x0470, 0x0520, 0x0520, /* horizontal timings */ + 0x0180, 0x0300, 0x0301, 0x0304, 0x0320, 0x0320, /* vertical timings */ + 0x004EC000, /* freq = 78.75 MHz */ + }, + +/* 640 x 400 */ + + {GFX_MODE_70HZ | /* refresh rate = 60 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC, /* negative HSYNC */ + 0x280, 0x288, 0x290, 0x2F0, 0x318, 0x320, /* horizontal timings */ + 0x190, 0x197, 0x19C, 0x19E, 0x1BA, 0x1C1, /* vertical timings */ + 0x00192CCC, /* freq = 25.175 MHz */ + }, + +/* 640x480 */ + + {GFX_MODE_60HZ | /* refresh rate = 60 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */ + 0x0280, 0x0288, 0x0290, 0x02E8, 0x0318, 0x0320, /* horizontal timings */ + 0x01E0, 0x01E8, 0x01EA, 0x01EC, 0x0205, 0x020D, /* vertical timings */ + 0x00192CCC, /* freq = 25.175 MHz */ + }, + + {GFX_MODE_72HZ | /* refresh rate = 72 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */ + 0x0280, 0x0288, 0x0298, 0x02c0, 0x0338, 0x0340, /* horizontal timings */ + 0x01e0, 0x01e8, 0x01e9, 0x01ec, 0x0200, 0x0208, /* vertical timings */ + 0x001F8000, /* freq = 31.5 MHz */ + }, + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */ + 0x0280, 0x0280, 0x0290, 0x02D0, 0x0348, 0x0348, /* horizontal timings */ + 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01F4, 0x01F4, /* vertical timings */ + 0x001F8000, /* freq = 31.5 MHz */ + }, + + {GFX_MODE_85HZ | /* refresh rate = 85 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */ + 0x0280, 0x0280, 0x02B8, 0x02F0, 0x0340, 0x0340, /* horizontal timings */ + 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FD, 0x01FD, /* vertical timings */ + 0x00240000, /* freq = 36.0 MHz */ + }, + +/* 800x600 */ + + {GFX_MODE_56HZ | /* refresh rate = 56 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0320, 0x0328, 0x0348, 0x03D0, 0x0418, 0x0420, /* horizontal timings */ + 0x0258, 0x0258, 0x0259, 0x025D, 0x0274, 0x0274, /* vertical timings */ + 0x00240000, /* freq = 36.00 MHz */ + }, + + {GFX_MODE_60HZ | /* refresh rate = 60 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0320, 0x0328, 0x0348, 0x03D0, 0x0418, 0x0420, /* horizontal timings */ + 0x0258, 0x0258, 0x0259, 0x025D, 0x0274, 0x0274, /* vertical timings */ + 0x00280000, /* freq = 40.00 MHz */ + }, + + {GFX_MODE_72HZ | /* refresh rate = 72 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0320, 0x0320, 0x0358, 0x03D0, 0x0410, 0x0410, /* horizontal timings */ + 0x0258, 0x0258, 0x027D, 0x0283, 0x029A, 0x029A, /* vertical timings */ + 0x00320000, /* freq = 49.5 MHz */ + }, + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0320, 0x0320, 0x0330, 0x0380, 0x0420, 0x0420, /* horizontal timings */ + 0x0258, 0x0258, 0x0259, 0x025C, 0x0271, 0x0271, /* vertical timings */ + 0x00318000, /* freq = 49.5 MHz */ + }, + + {GFX_MODE_85HZ | /* refresh rate = 85 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0320, 0x0320, 0x0340, 0x0380, 0x0418, 0x0418, /* horizontal timings */ + 0x0258, 0x0258, 0x0259, 0x025C, 0x0277, 0x0277, /* vertical timings */ + 0x00384000, /* freq = 56.25 MHz */ + }, + +/* 1024x768 */ + + {GFX_MODE_60HZ | /* refresh rate = 60 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */ + 0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540, /* horizontal timings */ + 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326, /* vertical timings */ + 0x00410000, /* freq = 65.00 MHz */ + }, + + {GFX_MODE_70HZ | /* refresh rate = 70 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */ + 0x0400, 0x0400, 0x0418, 0x04A0, 0x0530, 0x0530, /* horizontal timings */ + 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326, /* vertical timings */ + 0x004B0000, /* freq = 78.75 MHz */ + }, + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0400, 0x0400, 0x0410, 0x0470, 0x0520, 0x0520, /* horizontal timings */ + 0x0300, 0x0300, 0x0301, 0x0304, 0x0320, 0x0320, /* vertical timings */ + 0x004EC000, /* freq = 78.75 MHz */ + }, + + {GFX_MODE_85HZ | /* refresh rate = 85 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0400, 0x0400, 0x0430, 0x0490, 0x0560, 0x0560, /* horizontal timings */ + 0x0300, 0x0300, 0x0301, 0x0304, 0x0328, 0x0328, /* vertical timings */ + 0x005E8000, /* freq = 94.50 MHz */ + }, + +/* 1152x864 */ + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* all BPP valid */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0480, 0x0480, 0x04C0, 0x0540, 0x0640, 0x0640, /* horizontal timings */ + 0x0360, 0x0360, 0x0361, 0x0364, 0x0384, 0x0384, /* vertical timings */ + 0x006C0000, /* freq = 108.00 MHz */ + }, + +/* 1280x1024 */ + + {GFX_MODE_60HZ | /* refresh rate = 60 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* Up to 16 bpp */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0500, 0x0500, 0x0530, 0x05A0, 0x0698, 0x0698, /* horizontal timings */ + 0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A, /* vertical timings */ + 0x006C0000, /* freq = 108.0 MHz */ + }, + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* Up to 16 bpp */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0500, 0x0500, 0x0510, 0x05A0, 0x0698, 0x0698, /* horizontal timings */ + 0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A, /* vertical timings */ + 0x00870000, /* freq = 135.0 MHz */ + }, + + {GFX_MODE_85HZ | /* refresh rate = 85 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* Up to 16 bpp */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0500, 0x0500, 0x0540, 0x05E0, 0x06C0, 0x06C0, /* horizontal timings */ + 0x0400, 0x0400, 0x0401, 0x0404, 0x0430, 0x0430, /* vertical timings */ + 0x009D8000, /* freq = 157.5 MHz */ + }, + +/*********************************/ +/* BEGIN REDCLOUD-SPECIFIC MODES */ +/*-------------------------------*/ + +/* 1600 x 1200 */ + + {GFX_MODE_60HZ | /* refresh rate = 60 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* Up to 32 bpp */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */ + 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */ + 0x00A20000, /* freq = 162.0 MHz */ + }, + + {GFX_MODE_70HZ | /* refresh rate = 70 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* Up to 32 bpp */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */ + 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */ + 0x00BD0000, /* freq = 189.0 MHz */ + }, + + {GFX_MODE_75HZ | /* refresh rate = 75 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* Up to 32 bpp */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */ + 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */ + 0x00CA8000, /* freq = 202.5 MHz */ + }, + + {GFX_MODE_85HZ | /* refresh rate = 85 */ + GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP | /* Up to 32 bpp */ + GFX_MODE_16BPP | GFX_MODE_24BPP, + 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */ + 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */ + 0x00E58000, /* freq = 229.5 MHz */ + }, +}; + +/* UPDATE THIS VARIABLE WHENEVER NEW REDCLOUD-SPECIFIC MODES ARE ADDED */ + +#define REDCLOUD_SPECIFIC_MODES 4 + +#define NUM_RC_DISPLAY_MODES sizeof(DisplayParams) / sizeof(DISPLAYMODE) +#define NUM_GX_DISPLAY_MODES (NUM_RC_DISPLAY_MODES - REDCLOUD_SPECIFIC_MODES) + +FIXEDTIMINGS FixedParams[] = { +/* 640x480 Panel */ + {640, 480, 640, 480, + 0x0280, 0x280, 0x2a8, 0x328, 0x380, 0x380, + 0x1e0, 0x1e0, 0x1e1, 0x1e5, 0x1fc, 0x1fc, + 0x00192CCC, + }, + + {640, 480, 800, 600, + 0x0280, 0x280, 0x2a8, 0x328, 0x380, 0x380, + 0x1e0, 0x1e0, 0x1e1, 0x1e5, 0x1fc, 0x1fc, + 0x00192CCC, + }, + + {640, 480, 1024, 768, + 0x0280, 0x280, 0x2a8, 0x328, 0x380, 0x380, + 0x1e0, 0x1e0, 0x1e1, 0x1e5, 0x1fc, 0x1fc, + 0x00192CCC, + }, + + {640, 480, 1152, 864, + 0x0280, 0x280, 0x2a8, 0x328, 0x380, 0x380, + 0x1e0, 0x1e0, 0x1e1, 0x1e5, 0x1fc, 0x1fc, + 0x00192CCC, + }, + + {640, 480, 1280, 1024, + 0x0280, 0x280, 0x2a8, 0x328, 0x380, 0x380, + 0x1e0, 0x1e0, 0x1e1, 0x1e5, 0x1fc, 0x1fc, + 0x00192CCC, + }, + + {640, 480, 1600, 1200, + 0x0280, 0x280, 0x2a8, 0x328, 0x380, 0x380, + 0x1e0, 0x1e0, 0x1e1, 0x1e5, 0x1fc, 0x1fc, + 0x00192CCC, + }, + +/* 800x600 Panel */ + {800, 600, 640, 480, + 0x0280, 0x2d0, 0x2f8, 0x378, 0x3d0, 0x420, + 0x1e0, 0x21c, 0x21d, 0x221, 0x238, 0x274, + 0x00280000, + }, + + {800, 600, 800, 600, + 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420, + 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274, + 0x00280000, + }, + + {800, 600, 1024, 768, + 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420, + 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274, + 0x00280000, + }, + + {800, 600, 1152, 864, + 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420, + 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274, + 0x00280000, + }, + + {800, 600, 1280, 1024, + 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420, + 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274, + 0x00280000, + }, + + {800, 600, 1600, 1200, + 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420, + 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274, + 0x00280000, + }, + +/* 1024x768 panel */ + {1024, 768, 640, 480, + 0x0280, 0x340, 0x368, 0x3e8, 0x440, 0x500, + 0x1e0, 0x270, 0x271, 0x275, 0x28c, 0x31c, + 0x00410000, + }, + + {1024, 768, 800, 600, + 0x0320, 0x390, 0x3b8, 0x438, 0x490, 0x500, + 0x258, 0x2ac, 0x2ad, 0x2b1, 0x2c8, 0x31c, + 0x00410000, + }, + + {1024, 768, 1024, 768, + 0x0400, 0x400, 0x428, 0x4a8, 0x500, 0x500, + 0x300, 0x300, 0x301, 0x305, 0x31c, 0x31c, + 0x00410000, + }, + + {1024, 768, 1152, 864, + 0x0400, 0x400, 0x428, 0x4a8, 0x500, 0x500, + 0x300, 0x300, 0x301, 0x305, 0x31c, 0x31c, + 0x00410000, + }, + + {1024, 768, 1280, 1024, + 0x0400, 0x400, 0x428, 0x4a8, 0x500, 0x500, + 0x300, 0x300, 0x301, 0x305, 0x31c, 0x31c, + 0x00410000, + }, + + {1024, 768, 1600, 1200, + 0x0400, 0x400, 0x428, 0x4a8, 0x500, 0x500, + 0x300, 0x300, 0x301, 0x305, 0x31c, 0x31c, + 0x00410000, + }, + +}; + +#define NUM_FIXED_TIMINGS_MODES sizeof(FixedParams)/sizeof(FIXEDTIMINGS) + +/* INCLUDE SUPPORT FOR FIRST GENERATION, IF SPECIFIED. */ + +#if GFX_DISPLAY_GU1 +#include "disp_gu1.c" +#endif + +/* INCLUDE SUPPORT FOR SECOND GENERATION, IF SPECIFIED. */ + +#if GFX_DISPLAY_GU2 +#include "disp_gu2.c" +#endif + +void gfx_set_display_video_format(unsigned long format); +void gfx_set_display_video_enable(int enable); +void gfx_set_display_video_yuv_offsets(unsigned long yoffset, + unsigned long uoffset, + unsigned long voffset); +void gfx_set_display_video_yuv_pitch(unsigned long ypitch, + unsigned long uvpitch); +void gfx_set_display_video_downscale(unsigned short srch, + unsigned short dsth); +void gfx_set_display_video_vertical_downscale_enable(int enable); +void gfx_get_display_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset); +void gfx_get_display_video_yuv_pitch(unsigned long *ypitch, + unsigned long *uvpitch); +unsigned long gfx_get_display_video_downscale_delta(void); +int gfx_get_display_video_downscale_enable(void); +unsigned long gfx_get_display_video_size(void); +void gfx_set_display_video_size(unsigned short width, unsigned short height); +void gfx_set_display_video_offset(unsigned long offset); +unsigned long gfx_get_display_video_offset(void); + +/*--------------------------------------------------------------------------- + * gfx_reset_timing_lock + * + * This routine resets the timing change lock. The lock can only be set by + * setting a flag when calling mode set. + *--------------------------------------------------------------------------- + */ +void +gfx_reset_timing_lock(void) +{ + gfx_timing_lock = 0; +} + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call either first or second generation routines. */ + +#if GFX_DISPLAY_DYNAMIC + +/*--------------------------------------------------------------------------- + * gfx_set_display_bpp + *--------------------------------------------------------------------------- + */ +int +gfx_set_display_bpp(unsigned short bpp) +{ + int retval = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_set_display_bpp(bpp); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_set_display_bpp(bpp); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_is_display_mode_supported + * check if given mode supported, + * return the supported mode on success, -1 on fail + *--------------------------------------------------------------------------- + */ +int +gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz) +{ + int retval = -1; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_is_display_mode_supported(xres, yres, bpp, hz); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_is_display_mode_supported(xres, yres, bpp, hz); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_mode + *--------------------------------------------------------------------------- + */ +int +gfx_set_display_mode(int xres, int yres, int bpp, int hz) +{ + int retval = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_set_display_mode(xres, yres, bpp, hz); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_set_display_mode(xres, yres, bpp, hz); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_timings + *--------------------------------------------------------------------------- + */ +int +gfx_set_display_timings(unsigned short bpp, unsigned short flags, + unsigned short hactive, unsigned short hblankstart, + unsigned short hsyncstart, unsigned short hsyncend, + unsigned short hblankend, unsigned short htotal, + unsigned short vactive, unsigned short vblankstart, + unsigned short vsyncstart, unsigned short vsyncend, + unsigned short vblankend, unsigned short vtotal, + unsigned long frequency) +{ + int retval = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_set_display_timings(bpp, flags, + hactive, hblankstart, hsyncstart, + hsyncend, hblankend, htotal, vactive, + vblankstart, vsyncstart, vsyncend, + vblankend, vtotal, frequency); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_set_display_timings(bpp, flags, + hactive, hblankstart, hsyncstart, + hsyncend, hblankend, htotal, vactive, + vblankstart, vsyncstart, vsyncend, + vblankend, vtotal, frequency); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_pitch + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_pitch(unsigned short pitch) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_display_pitch(pitch); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_pitch(pitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_offset + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_offset(unsigned long offset) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_display_offset(offset); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_offset(offset); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_palette_entry + *--------------------------------------------------------------------------- + */ +int +gfx_set_display_palette_entry(unsigned long index, unsigned long palette) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_set_display_palette_entry(index, palette); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_set_display_palette_entry(index, palette); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_palette + *--------------------------------------------------------------------------- + */ +int +gfx_set_display_palette(unsigned long *palette) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_set_display_palette(palette); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_set_display_palette(palette); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_enable + *--------------------------------------------------------------------------- + */ +void +gfx_set_cursor_enable(int enable) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_cursor_enable(enable); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_cursor_enable(enable); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_colors + *--------------------------------------------------------------------------- + */ +void +gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_cursor_colors(bkcolor, fgcolor); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_cursor_colors(bkcolor, fgcolor); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_position + *--------------------------------------------------------------------------- + */ +void +gfx_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, unsigned short yhotspot) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_cursor_position(memoffset, xpos, ypos, xhotspot, yhotspot); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_cursor_position(memoffset, xpos, ypos, xhotspot, yhotspot); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_shape32 + *--------------------------------------------------------------------------- + */ +void +gfx_set_cursor_shape32(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_cursor_shape32(memoffset, andmask, xormask); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_cursor_shape32(memoffset, andmask, xormask); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_cursor_shape64 + *--------------------------------------------------------------------------- + */ +void +gfx_set_cursor_shape64(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_cursor_shape64(memoffset, andmask, xormask); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_icon_enable + *--------------------------------------------------------------------------- + */ +void +gfx_set_icon_enable(int enable) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_icon_enable(enable); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_icon_colors + *--------------------------------------------------------------------------- + */ +void +gfx_set_icon_colors(unsigned long color0, unsigned long color1, + unsigned long color2) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_icon_colors(color0, color1, color2); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_icon_position + *--------------------------------------------------------------------------- + */ +void +gfx_set_icon_position(unsigned long memoffset, unsigned short xpos) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_icon_position(memoffset, xpos); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_icon_shape64 + *--------------------------------------------------------------------------- + */ +void +gfx_set_icon_shape64(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask, + unsigned int lines) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_icon_shape64(memoffset, andmask, xormask, lines); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_enable + *--------------------------------------------------------------------------- + */ +int +gfx_set_compression_enable(int enable) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_set_compression_enable(enable); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_set_compression_enable(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_offset + *--------------------------------------------------------------------------- + */ +int +gfx_set_compression_offset(unsigned long offset) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_set_compression_offset(offset); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_set_compression_offset(offset); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_pitch + *--------------------------------------------------------------------------- + */ +int +gfx_set_compression_pitch(unsigned short pitch) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_set_compression_pitch(pitch); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_set_compression_pitch(pitch); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_compression_size + *--------------------------------------------------------------------------- + */ +int +gfx_set_compression_size(unsigned short size) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_set_compression_size(size); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_set_compression_size(size); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_priority_high + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_priority_high(int enable) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_display_priority_high(enable); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_format". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_video_format(unsigned long format) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_video_format(format); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_enable". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_video_enable(int enable) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_display_video_enable(enable); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_video_enable(enable); +# endif + return; +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_size". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_video_size(unsigned short width, unsigned short height) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_display_video_size(width, height); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_video_size(width, height); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_offset". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_video_offset(unsigned long offset) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_set_display_video_offset(offset); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_video_offset(offset); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_yuv_offsets". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_video_yuv_offsets(unsigned long yoffset, + unsigned long uoffset, + unsigned long voffset) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_video_yuv_offsets(yoffset, uoffset, voffset); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_yuv_pitch". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_video_yuv_pitch(ypitch, uvpitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_downscale (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_vertical_downscale". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_video_downscale(unsigned short srch, unsigned short dsth) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_video_downscale(srch, dsth); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_video_vertical_downscale_enable (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine is called by "gfx_set_video_vertical_downscale_enable". It abstracts the + * version of the display controller from the video overlay routines. + *--------------------------------------------------------------------------- + */ +void +gfx_set_display_video_vertical_downscale_enable(int enable) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_set_display_video_vertical_downscale_enable(enable); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_test_timing_active + *--------------------------------------------------------------------------- + */ +int +gfx_test_timing_active(void) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_test_timing_active(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_test_timing_active(); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_test_vertical_active + *--------------------------------------------------------------------------- + */ +int +gfx_test_vertical_active(void) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_test_vertical_active(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_test_vertical_active(); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_wait_vertical_blank + *--------------------------------------------------------------------------- + */ +int +gfx_wait_vertical_blank(void) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_wait_vertical_blank(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_wait_vertical_blank(); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_delay_milliseconds + *--------------------------------------------------------------------------- + */ +void +gfx_delay_milliseconds(unsigned long milliseconds) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_delay_milliseconds(milliseconds); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_delay_milliseconds(milliseconds); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_delay_microseconds + *--------------------------------------------------------------------------- + */ +void +gfx_delay_microseconds(unsigned long microseconds) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_delay_microseconds(microseconds); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_delay_microseconds(microseconds); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_enable_panning + * + * This routine enables the panning when the Mode is bigger than the panel + * size. + *--------------------------------------------------------------------------- + */ +void +gfx_enable_panning(int x, int y) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_enable_panning(x, y); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_enable_panning(x, y); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_fixed_timings + *--------------------------------------------------------------------------- + */ +int +gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = + gu1_set_fixed_timings(panelResX, panelResY, width, height, bpp); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = + gu2_set_fixed_timings(panelResX, panelResY, width, height, bpp); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_panel_present + *--------------------------------------------------------------------------- + */ +int +gfx_set_panel_present(int panelResX, int panelResY, unsigned short width, + unsigned short height, unsigned short bpp) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = + gu1_set_panel_present(panelResX, panelResY, width, height, bpp); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = + gu2_set_panel_present(panelResX, panelResY, width, height, bpp); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vtotal + *--------------------------------------------------------------------------- + */ +int +gfx_set_vtotal(unsigned short vtotal) +{ + int retval = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_set_vtotal(vtotal); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_set_vtotal(vtotal); +# endif + return (retval); +} + +/*-----------------------------------------------------------------------* + * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: * + * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal * + * are used by the video overlay routines. * + * * + * gfx_get_vline and gfx_vactive are used to prevent an issue for the * + * SC1200. * + * * + * The others are part of the Durango API. * + *-----------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * gfx_mode_frequency_supported + *---------------------------------------------------------------------------- + */ +int +gfx_mode_frequency_supported(int xres, int yres, int bpp, + unsigned long frequency) +{ + int freq = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + freq = gu1_mode_frequency_supported(xres, yres, bpp, frequency); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + freq = gu2_mode_frequency_supported(xres, yres, bpp, frequency); +# endif + return (freq); +} + +/*---------------------------------------------------------------------------- + * gfx_refreshrate_from_frequency + *---------------------------------------------------------------------------- + */ +int +gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_get_refreshrate_from_frequency(xres, yres, bpp, hz, frequency); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_get_refreshrate_from_frequency(xres, yres, bpp, hz, frequency); +# endif + + return (1); +} + +/*---------------------------------------------------------------------------- + * gfx_refreshrate_from_mode + *---------------------------------------------------------------------------- + */ +int +gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_get_refreshrate_from_mode(xres, yres, bpp, hz, frequency); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_get_refreshrate_from_mode(xres, yres, bpp, hz, frequency); +# endif + + return (1); +} + +/*---------------------------------------------------------------------------- + * gfx_get_frequency_from_refreshrate + *---------------------------------------------------------------------------- + */ +int +gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, + int *frequency) +{ + int retval = -1; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = + gu1_get_frequency_from_refreshrate(xres, yres, bpp, hz, + frequency); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = + gu2_get_frequency_from_refreshrate(xres, yres, bpp, hz, + frequency); +# endif + + return retval; +} + +/*--------------------------------------------------------------------------- + * gfx_get_max_supported_pixel_clock + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_max_supported_pixel_clock(void) +{ + unsigned long status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_get_max_supported_pixel_clock(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_get_max_supported_pixel_clock(); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_pitch + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_display_pitch(void) +{ + unsigned short pitch = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + pitch = gu1_get_display_pitch(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + pitch = gu2_get_display_pitch(); +# endif + return (pitch); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_mode_count + * return # of modes supported. + *--------------------------------------------------------------------------- + */ +int +gfx_get_display_mode_count(void) +{ + int retval = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_get_display_mode_count(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_get_display_mode_count(); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_frame_buffer_line_size + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_frame_buffer_line_size(void) +{ + unsigned long retval = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_get_frame_buffer_line_size(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_get_frame_buffer_line_size(); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_mode + * get the curent mode set, + * return the supported mode on success, -1 on fail + *--------------------------------------------------------------------------- + */ +int +gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz) +{ + int retval = -1; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_get_display_mode(xres, yres, bpp, hz); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_get_display_mode(xres, yres, bpp, hz); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_details + * given the mode get's the resoultion details, width, height, freq + *--------------------------------------------------------------------------- + */ +int +gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) +{ + int retval = -1; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + retval = gu1_get_display_details(mode, xres, yres, hz); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + retval = gu2_get_display_details(mode, xres, yres, hz); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hactive + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_hactive(void) +{ + unsigned short hactive = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + hactive = gu1_get_hactive(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + hactive = gu2_get_hactive(); +# endif + return (hactive); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hsync_start + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_hsync_start(void) +{ + unsigned short hsync_start = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + hsync_start = gu1_get_hsync_start(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + hsync_start = gu2_get_hsync_start(); +# endif + return (hsync_start); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hsync_end + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_hsync_end(void) +{ + unsigned short hsync_end = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + hsync_end = gu1_get_hsync_end(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + hsync_end = gu2_get_hsync_end(); +# endif + return (hsync_end); +} + +/*--------------------------------------------------------------------------- + * gfx_get_htotal + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_htotal(void) +{ + unsigned short htotal = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + htotal = gu1_get_htotal(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + htotal = gu2_get_htotal(); +# endif + return (htotal); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vactive + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_vactive(void) +{ + unsigned short vactive = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + vactive = gu1_get_vactive(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + vactive = gu2_get_vactive(); +# endif + return (vactive); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vsync_end + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_vsync_end(void) +{ + unsigned short vsync_end = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + vsync_end = gu1_get_vsync_end(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + vsync_end = gu2_get_vsync_end(); +# endif + return (vsync_end); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vtotal + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_vtotal(void) +{ + unsigned short vtotal = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + vtotal = gu1_get_vtotal(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + vtotal = gu2_get_vtotal(); +# endif + return (vtotal); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_bpp + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_display_bpp(void) +{ + unsigned short bpp = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + bpp = gu1_get_display_bpp(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + bpp = gu2_get_display_bpp(); +# endif + return (bpp); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vline + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_vline(void) +{ + unsigned short vline = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + vline = gu1_get_vline(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + vline = gu2_get_vline(); +# endif + return (vline); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_offset + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_display_offset(void) +{ + unsigned long offset = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + offset = gu1_get_display_offset(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + offset = gu2_get_display_offset(); +# endif + return (offset); +} + +/*--------------------------------------------------------------------------- + * gfx_get_cursor_offset + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_cursor_offset(void) +{ + unsigned long base = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + base = gu1_get_cursor_offset(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + base = gu2_get_cursor_offset(); +# endif + return (base); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*--------------------------------------------------------------------------- + * gfx_get_hblank_start + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_hblank_start(void) +{ + unsigned short hblank_start = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + hblank_start = gu1_get_hblank_start(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + hblank_start = gu2_get_hblank_start(); +# endif + return (hblank_start); +} + +/*--------------------------------------------------------------------------- + * gfx_get_hblank_end + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_hblank_end(void) +{ + unsigned short hblank_end = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + hblank_end = gu1_get_hblank_end(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + hblank_end = gu2_get_hblank_end(); +# endif + return (hblank_end); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vblank_start + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_vblank_start(void) +{ + unsigned short vblank_start = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + vblank_start = gu1_get_vblank_start(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + vblank_start = gu2_get_vblank_start(); +# endif + return (vblank_start); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vsync_start + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_vsync_start(void) +{ + unsigned short vsync_start = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + vsync_start = gu1_get_vsync_start(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + vsync_start = gu2_get_vsync_start(); +# endif + return (vsync_start); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vblank_end + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_vblank_end(void) +{ + unsigned short vblank_end = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + vblank_end = gu1_get_vblank_end(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + vblank_end = gu2_get_vblank_end(); +# endif + return (vblank_end); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_palette_entry + *--------------------------------------------------------------------------- + */ +int +gfx_get_display_palette_entry(unsigned long index, unsigned long *palette) +{ + int status = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + status = gu1_get_display_palette_entry(index, palette); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + status = gu2_get_display_palette_entry(index, palette); +# endif + + return status; +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_palette + *--------------------------------------------------------------------------- + */ +void +gfx_get_display_palette(unsigned long *palette) +{ +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + gu1_get_display_palette(palette); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_get_display_palette(palette); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_get_cursor_enable + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_cursor_enable(void) +{ + unsigned long enable = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + enable = gu1_get_cursor_enable(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + enable = gu2_get_cursor_enable(); +# endif + return (enable); +} + +/*--------------------------------------------------------------------------- + * gfx_get_cursor_position + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_cursor_position(void) +{ + unsigned long position = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + position = gu1_get_cursor_position(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + position = gu2_get_cursor_position(); +# endif + return (position); +} + +/*--------------------------------------------------------------------------- + * gfx_get_cursor_clip + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_cursor_clip(void) +{ + unsigned long offset = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + offset = gu1_get_cursor_clip(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + offset = gu2_get_cursor_clip(); +# endif + return (offset); +} + +/*--------------------------------------------------------------------------- + * gfx_get_cursor_color + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_cursor_color(int index) +{ + unsigned long color = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + color = gu1_get_cursor_color(index); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + color = gu2_get_cursor_color(index); +# endif + return (color); +} + +/*--------------------------------------------------------------------------- + * gfx_get_icon_enable + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_icon_enable(void) +{ + unsigned long enable = 0; + +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + enable = gu2_get_icon_enable(); +# endif + return (enable); +} + +/*--------------------------------------------------------------------------- + * gfx_get_icon_offset + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_icon_offset(void) +{ + unsigned long base = 0; + +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + base = gu2_get_icon_offset(); +# endif + + return (base); +} + +/*--------------------------------------------------------------------------- + * gfx_get_icon_position + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_icon_position(void) +{ + unsigned long position = 0; + +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + position = gu2_get_icon_position(); +# endif + + return (position); +} + +/*--------------------------------------------------------------------------- + * gfx_get_icon_color + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_icon_color(int index) +{ + unsigned long color = 0; + +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + color = gu2_get_icon_color(index); +# endif + + return (color); +} + +/*--------------------------------------------------------------------------- + * gfx_get_compression_enable + *--------------------------------------------------------------------------- + */ +int +gfx_get_compression_enable(void) +{ + int enable = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + enable = gu1_get_compression_enable(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + enable = gu2_get_compression_enable(); +# endif + return (enable); +} + +/*--------------------------------------------------------------------------- + * gfx_get_compression_offset + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_compression_offset(void) +{ + unsigned long offset = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + offset = gu1_get_compression_offset(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + offset = gu2_get_compression_offset(); +# endif + return (offset); +} + +/*--------------------------------------------------------------------------- + * gfx_get_compression_pitch + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_compression_pitch(void) +{ + unsigned short pitch = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + pitch = gu1_get_compression_pitch(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + pitch = gu2_get_compression_pitch(); +# endif + return (pitch); +} + +/*--------------------------------------------------------------------------- + * gfx_get_compression_size + *--------------------------------------------------------------------------- + */ +unsigned short +gfx_get_compression_size(void) +{ + unsigned short size = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + size = gu1_get_compression_size(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + size = gu2_get_compression_size(); +# endif + return (size); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_priority_high + *--------------------------------------------------------------------------- + */ +int +gfx_get_display_priority_high(void) +{ + int high = GFX_STATUS_UNSUPPORTED; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + high = gu1_get_display_priority_high(); +# endif + return (high); +} + +/*--------------------------------------------------------------------------- + * gfx_get_valid_bit + *--------------------------------------------------------------------------- + */ +int +gfx_get_valid_bit(int line) +{ + int valid = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + valid = gu1_get_valid_bit(line); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + valid = gu2_get_valid_bit(line); +# endif + return (valid); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_offset + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_display_video_offset(void) +{ + unsigned long offset = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + offset = gu1_get_display_video_offset(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + offset = gu2_get_display_video_offset(); +# endif + return (offset); +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_yuv_offsets + *--------------------------------------------------------------------------- + */ +void +gfx_get_display_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_get_display_video_yuv_offsets(yoffset, uoffset, voffset); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_yuv_offsets + *--------------------------------------------------------------------------- + */ +void +gfx_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch) +{ +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + gu2_get_display_video_yuv_pitch(ypitch, uvpitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_downscale_delta + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_display_video_downscale_delta(void) +{ + unsigned long ret_value = 0; + +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + ret_value = gu2_get_display_video_downscale_delta(); +# endif + + return ret_value; +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_downscale_delta + *--------------------------------------------------------------------------- + */ +int +gfx_get_display_video_downscale_enable(void) +{ + int ret_value = 0; + +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + ret_value = gu2_get_display_video_downscale_enable(); +# endif + + return ret_value; +} + +/*--------------------------------------------------------------------------- + * gfx_get_display_video_size + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_display_video_size(void) +{ + unsigned long size = 0; + +# if GFX_DISPLAY_GU1 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU1) + size = gu1_get_display_video_size(); +# endif +# if GFX_DISPLAY_GU2 + if (gfx_display_type & GFX_DISPLAY_TYPE_GU2) + size = gu2_get_display_video_size(); +# endif + return (size); +} + +#endif /* GFX_READ_ROUTINES */ + +#endif /* GFX_DISPLAY_DYNAMIC */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_i2c.c new file mode 100644 index 000000000..385ee9fe5 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_i2c.c @@ -0,0 +1,269 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_i2c.c,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: gfx_i2c.c $ + * + * This file contains routines to write to and read from the I2C bus. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* INCLUDE ROUTINES FOR ACCESS.BUS, IF SPECIFIED */ +/* This is for SC1200 systems. */ + +#if GFX_I2C_ACCESS +#include "i2c_acc.c" +#endif + +/* INCLUDE ROUTINES FOR CS5530 GPIOs, IF SPECIFIED */ +/* This is for GXLV systems that use GPIOs on the CS5530 for I2C. */ + +#if GFX_I2C_GPIO +#include "i2c_gpio.c" +#endif + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call either ACCESS.bus or GPIO routines. */ + +#if GFX_I2C_DYNAMIC + +/*--------------------------------------------------------------------------- + * gfx_i2c_reset + *--------------------------------------------------------------------------- + */ +int +gfx_i2c_reset(unsigned char busnum, short adr, char freq) +{ + int status = GFX_STATUS_UNSUPPORTED; + +#if GFX_I2C_ACCESS + if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS) + status = acc_i2c_reset(busnum, adr, freq); +#endif +#if GFX_I2C_GPIO + if (gfx_i2c_type & GFX_I2C_TYPE_GPIO) + status = gpio_i2c_reset(busnum, adr, freq); +#endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_select_gpio + *--------------------------------------------------------------------------- + */ +int +gfx_i2c_select_gpio(int clock, int data) +{ +#if GFX_I2C_ACCESS + if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS) + acc_i2c_select_gpio(clock, data); +#endif +#if GFX_I2C_GPIO + if (gfx_i2c_type & GFX_I2C_TYPE_GPIO) + gpio_i2c_select_gpio(clock, data); +#endif + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_write + *--------------------------------------------------------------------------- + */ +int +gfx_i2c_write(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, unsigned char *data) +{ + int status = -1; + +#if GFX_I2C_ACCESS + if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS) + status = acc_i2c_write(busnum, chipadr, subadr, bytes, data); +#endif +#if GFX_I2C_GPIO + if (gfx_i2c_type & GFX_I2C_TYPE_GPIO) + status = gpio_i2c_write(busnum, chipadr, subadr, bytes, data); +#endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_read + *--------------------------------------------------------------------------- + */ +int +gfx_i2c_read(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, unsigned char *data) +{ + int status = -1; + +#if GFX_I2C_ACCESS + if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS) + status = acc_i2c_read(busnum, chipadr, subadr, bytes, data); +#endif +#if GFX_I2C_GPIO + if (gfx_i2c_type & GFX_I2C_TYPE_GPIO) + status = gpio_i2c_read(busnum, chipadr, subadr, bytes, data); +#endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_init + *--------------------------------------------------------------------------- + */ +int +gfx_i2c_init(void) +{ + int status = -1; + +#if GFX_I2C_ACCESS + if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS) + status = acc_i2c_init(); +#endif +#if GFX_I2C_GPIO + if (gfx_i2c_type & GFX_I2C_TYPE_GPIO) + status = gpio_i2c_init(); +#endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_cleanup + *--------------------------------------------------------------------------- + */ +void +gfx_i2c_cleanup(void) +{ +#if GFX_I2C_ACCESS + if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS) + acc_i2c_cleanup(); +#endif +#if GFX_I2C_GPIO + if (gfx_i2c_type & GFX_I2C_TYPE_GPIO) + gpio_i2c_cleanup(); +#endif +} + +#endif /* GFX_I2C_DYNAMIC */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_init.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_init.c new file mode 100644 index 000000000..2aa93d523 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_init.c @@ -0,0 +1,688 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_init.c,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: gfx_init.c $ + * + * This file contains routines typically used in driver initialization. + * + * Routines: + * + * gfx_pci_config_read + * gfx_cpu_config_read + * gfx_detect_cpu + * gfx_detect_video + * gfx_get_cpu_register_base + * gfx_get_frame_buffer_base + * gfx_get_frame_buffer_size + * gfx_get_vid_register_base + * gfx_get_vip_register_base + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* CONSTANTS USED BY THE INITIALIZATION CODE */ + +#define PCI_CONFIG_ADDR 0x0CF8 +#define PCI_CONFIG_DATA 0x0CFC +#define PCI_VENDOR_DEVICE_GXM 0x00011078 +#define PCI_VENDOR_DEVICE_REDCLOUD 0x0028100B +#define REDCLOUD_VIDEO_PCI_VENDOR_DEVICE 0x0030100B + +#define GXM_CONFIG_GCR 0xB8 +#define GXM_CONFIG_CCR3 0xC3 +#define GXM_CONFIG_DIR0 0xFE +#define GXM_CONFIG_DIR1 0xFF + +/* STATIC VARIABLES FOR THIS FILE */ + +unsigned long gfx_cpu_version = 0; +unsigned long gfx_cpu_frequency = 0; +unsigned long gfx_vid_version = 0; +unsigned long gfx_gx1_scratch_base = 0; +unsigned long gfx_gx2_scratch_base = 0x7FC000; +ChipType gfx_chip_revision = CHIP_NOT_DETECTED; + +/* INCLUDE SUPPORT FOR FIRST GENERATION, IF SPECIFIED. */ + +ChipType gfx_detect_chip(void); + +#if GFX_INIT_GU1 +#include "init_gu1.c" +#endif + +/* INCLUDE SUPPORT FOR SECOND GENERATION, IF SPECIFIED. */ + +#if GFX_INIT_GU2 +#include "init_gu2.c" +#endif + +/* THE FOLLOWING ROUTINES ARE NEVER DYNAMIC */ +/* They are used to set the variables for future dynamic */ +/* function calls. */ + +/*----------------------------------------------------------------------------- + * gfx_detect_chip + * + * This routine returns the name and revision of the chip. This function is only + * relevant to the SC1200. + *----------------------------------------------------------------------------- + */ +ChipType +gfx_detect_chip(void) +{ + unsigned char pid = INB(SC1200_CB_BASE_ADDR + SC1200_CB_PID); + unsigned char rev = INB(SC1200_CB_BASE_ADDR + SC1200_CB_REV); + + gfx_chip_revision = CHIP_NOT_DETECTED; + + if (pid == 0x4) { + switch (rev) { + case 0: + gfx_chip_revision = SC1200_REV_A; + break; + case 1: + gfx_chip_revision = SC1200_REV_B1_B2; + break; + case 2: + gfx_chip_revision = SC1200_REV_B3; + break; + case 3: + gfx_chip_revision = SC1200_REV_C1; + break; + case 4: + gfx_chip_revision = SC1200_REV_D1; + break; + case 5: + gfx_chip_revision = SC1200_REV_D1_1; + break; + case 6: + gfx_chip_revision = SC1200_REV_D2_MVD; + break; + } + if (rev > 0x6) + gfx_chip_revision = SC1200_FUTURE_REV; + } else if (pid == 0x5) { + if (rev == 0x6) + gfx_chip_revision = SC1200_REV_D2_MVE; + else if (rev > 0x6) + gfx_chip_revision = SC1200_FUTURE_REV; + } + return (gfx_chip_revision); +} + +/*----------------------------------------------------------------------------- + * gfx_detect_cpu + * + * This routine returns the type and revison of the CPU. If a Geode + * processor is not present, the routine returns zero. + * + * The return value is as follows: + * bits[24:16] = minor version + * bits[15:8] = major version + * bits[7:0] = type (1 = GXm, 2 = SC1200, 3 = Redcloud) + * + * A return value of 0x00020501, for example, indicates GXm version 5.2. + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_detect_cpu(void) +{ + + unsigned long value = 0; + unsigned long version = 0; + + /* initialize core freq. to 0 */ + gfx_cpu_frequency = 0; + +#if GFX_INIT_GU1 + + value = gfx_pci_config_read(0x80000000); + + if (value == PCI_VENDOR_DEVICE_GXM) { + unsigned char dir0 = gfx_gxm_config_read(GXM_CONFIG_DIR0) & 0xF0; + unsigned char dir1 = gfx_gxm_config_read(GXM_CONFIG_DIR1); + + if (dir0 == 0x40) { + /* CHECK FOR GXLV (and GXm) (DIR1 = 0x30 THROUGH 0x82) */ + + if ((dir1 >= 0x30) && (dir1 <= 0x82)) { + /* Major version is one less than what appears in DIR1 */ + if ((dir1 & 0xF0) < 0x70) { + + version = GFX_CPU_GXLV | (((((unsigned long)dir1 >> 4) - 1) << 8)) | /* major - 1 */ + ((((unsigned long)dir1 & 0x0F)) << 16); /* minor */ + } else { + version = GFX_CPU_GXLV | ((((unsigned long)dir1 >> 4)) << 8) | /* major */ + ((((unsigned long)dir1 & 0x0F)) << 16); /* minor */ + + } + /* Currently always CS5530 for video overlay. */ + +# if GFX_VIDEO_DYNAMIC + gfx_video_type = GFX_VIDEO_TYPE_CS5530; +# endif + + /* Currently always CS5530 GPIOs for I2C access. */ + +# if GFX_I2C_DYNAMIC + gfx_i2c_type = GFX_I2C_TYPE_GPIO; +# endif + +# if GFX_TV_DYNAMIC + gfx_tv_type = GFX_TV_TYPE_FS451; +# endif + } + } else if (dir0 == 0xB0) { + /* CHECK FOR SC1200 */ + + if ((dir1 == 0x70) || (dir1 == 0x81)) { + version = GFX_CPU_SC1200 | ((((unsigned long)dir1 >> 4)) << 8) | /* major */ + ((((unsigned long)dir1 & 0x0F)) << 16); /* minor */ + + /* Detect SC1200 revision */ + + gfx_detect_chip(); + + /* SC1200 for video overlay and VIP. */ + +# if GFX_VIDEO_DYNAMIC + gfx_video_type = GFX_VIDEO_TYPE_SC1200; +# endif + +# if GFX_VIP_DYNAMIC + gfx_vip_type = GFX_VIP_TYPE_SC1200; +# endif + + /* Currently always SAA7114 decoder. */ + +# if GFX_DECODER_DYNAMIC + gfx_decoder_type = GFX_DECODER_TYPE_SAA7114; +# endif + + /* SC1200 for TV encoder */ + +# if GFX_TV_DYNAMIC + gfx_tv_type = GFX_TV_TYPE_SC1200; +# endif + + /* Currently always ACCESS.bus for I2C access. */ + +# if GFX_I2C_DYNAMIC + gfx_i2c_type = GFX_I2C_TYPE_ACCESS; +# endif + } + } + + if (version) { + /* ALWAYS FIRST GENERATION GRAPHICS UNIT */ + +# if GFX_DISPLAY_DYNAMIC + gfx_display_type = GFX_DISPLAY_TYPE_GU1; +# endif +# if GFX_2DACCEL_DYNAMIC + gfx_2daccel_type = GFX_2DACCEL_TYPE_GU1; +# endif +# if GFX_INIT_DYNAMIC + gfx_init_type = GFX_INIT_TYPE_GU1; +# endif + + /* READ THE CORE FREQUENCY */ + + gfx_cpu_frequency = gfx_get_core_freq(); + } + } +#endif + +#if GFX_INIT_GU2 + + value = gfx_pci_config_read(0x80000800); + + if (value == PCI_VENDOR_DEVICE_REDCLOUD) { + Q_WORD msr_value; + int valid, i; + + /* CHECK FOR SOFT VG */ + /* If SoftVG is not present, the base addresses for all devices */ + /* will not be allocated. Essentially, it is as if no Redcloud */ + /* video hardware is present. */ + + value = gfx_pci_config_read(0x80000900); + + if (value == REDCLOUD_VIDEO_PCI_VENDOR_DEVICE) { + valid = 1; + + /* BAR0 - BAR3 HOLD THE PERIPHERAL BASE ADDRESSES */ + + for (i = 0; i < 4; i++) { + value = gfx_pci_config_read(0x80000910 + (i << 2)); + if (value == 0x00000000 || value == 0xFFFFFFFF) { + valid = 0; + break; + } + } + + if (valid) { + /* REDCLOUD INTEGRATED VIDEO */ + +# if GFX_VIDEO_DYNAMIC + gfx_video_type = GFX_VIDEO_TYPE_REDCLOUD; +# endif + + /* CURRENTLY, ALWAYS GPIO FOR I2C ACCESS */ + +# if GFX_I2C_DYNAMIC + gfx_i2c_type = GFX_I2C_TYPE_GPIO; +# endif + + /* SECOND-GENERATION DISPLAY CONTROLLER */ + +# if GFX_DISPLAY_DYNAMIC + gfx_display_type = GFX_DISPLAY_TYPE_GU2; +# endif + + /* SECOND-GENERATION GRAPHICS UNIT */ + +# if GFX_2DACCEL_DYNAMIC + gfx_2daccel_type = GFX_2DACCEL_TYPE_GU2; +# endif + + /* SECOND-GENERATION INITIALIZATION */ + +# if GFX_INIT_DYNAMIC + gfx_init_type = GFX_INIT_TYPE_GU2; +# endif + + /* MBUS MSR ACCESSES */ + +# if GFX_MSR_DYNAMIC + gfx_msr_type = GFX_MSR_TYPE_REDCLOUD; +# endif + + /* CS5530 GPIO I2C */ + +# if GFX_I2C_DYNAMIC + gfx_i2c_type = GFX_I2C_TYPE_GPIO; +# endif + + /* READ VERSION */ + + gfx_msr_init(); + + gfx_msr_read(RC_ID_MCP, MCP_RC_REVID, &msr_value); + + /* SUBTRACT 1 FROM REV ID */ + /* REDCLOUD 1.X rev id is 1 less than the reported value */ + + if ((msr_value.low & 0xF0) == 0x10) + msr_value.low--; + + version = GFX_CPU_REDCLOUD | ((msr_value.low & 0xF0) << 4) | /* MAJOR */ + ((msr_value.low & 0x0F) << 16); /* MINOR */ + + /* READ THE CORE FREQUENCY */ + + gfx_cpu_frequency = gfx_get_core_freq(); + + /* SET THE GP SCRATCH AREA */ + /* Color bitmap BLTs use the last 16K of frame buffer space */ + + gfx_gx2_scratch_base = gfx_get_frame_buffer_size() - 0x4000; + } + } + } +#endif + + if (!version) { + /* ALWAYS SECOND GENERATION IF SIMULATING */ + /* For now, that is. This could change. */ + +# if GFX_DISPLAY_DYNAMIC + gfx_display_type = GFX_DISPLAY_TYPE_GU2; +# endif +# if GFX_2DACCEL_DYNAMIC + gfx_2daccel_type = GFX_2DACCEL_TYPE_GU2; +# endif +# if GFX_INIT_DYNAMIC + gfx_init_type = GFX_INIT_TYPE_GU2; +# endif +# if GFX_MSR_DYNAMIC + gfx_msr_type = GFX_MSR_TYPE_REDCLOUD; +# endif +# if GFX_VIDEO_DYNAMIC + gfx_video_type = GFX_VIDEO_TYPE_REDCLOUD; +# endif +# if GFX_I2C_DYNAMIC + gfx_i2c_type = GFX_I2C_TYPE_GPIO; +# endif + } + gfx_cpu_version = version; + + return (version); +} + +/*----------------------------------------------------------------------------- + * gfx_detect_video + * + * This routine returns the type of the video hardware. + * + * The return value is as follows: + * bits[7:0] = type (1 = CS5530, 2 = SC1200, 3 = Redcloud) + * + * Currently this routine does not actually detect any hardware, and bases + * the video hardware entirely on the detected CPU. + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_detect_video(void) +{ + unsigned long version = 0; + + if ((gfx_cpu_version & 0xFF) == GFX_CPU_GXLV) + version = GFX_VID_CS5530; + else if ((gfx_cpu_version & 0xFF) == GFX_CPU_SC1200) + version = GFX_VID_SC1200; + else if ((gfx_cpu_version & 0xFF) == GFX_CPU_REDCLOUD) + version = GFX_VID_REDCLOUD; + gfx_vid_version = version; + return (version); +} + +/*----------------------------------------------------------------------------- + * gfx_pci_config_read + * + * This routine reads a 32-bit value from the specified location in PCI + * configuration space. + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_pci_config_read(unsigned long address) +{ + unsigned long value = 0xFFFFFFFF; + + OUTD(PCI_CONFIG_ADDR, address); + value = IND(PCI_CONFIG_DATA); + return (value); +} + +/*----------------------------------------------------------------------------- + * gfx_pci_config_write + * + * This routine writes a 32-bit value to the specified location in PCI + * configuration space. + *----------------------------------------------------------------------------- + */ +void +gfx_pci_config_write(unsigned long address, unsigned long data) +{ + OUTD(PCI_CONFIG_ADDR, address); + OUTD(PCI_CONFIG_DATA, data); + return; +} + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call either first or second generation routines. */ + +#if GFX_INIT_DYNAMIC + +/*----------------------------------------------------------------------------- + * gfx_get_core_freq + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_core_freq(void) +{ + unsigned long freq = 0; + +# if GFX_INIT_GU1 + if (gfx_init_type & GFX_INIT_TYPE_GU1) + freq = gu1_get_core_freq(); +# endif +# if GFX_INIT_GU2 + if (gfx_init_type & GFX_INIT_TYPE_GU2) + freq = gu2_get_core_freq(); +# endif + return freq; +} + +/*----------------------------------------------------------------------------- + * gfx_get_cpu_register_base + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_cpu_register_base(void) +{ + unsigned long base = 0; + +# if GFX_INIT_GU1 + if (gfx_init_type & GFX_INIT_TYPE_GU1) + base = gu1_get_cpu_register_base(); +# endif +# if GFX_INIT_GU2 + if (gfx_init_type & GFX_INIT_TYPE_GU2) + base = gu2_get_cpu_register_base(); +# endif + + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_graphics_register_base + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_graphics_register_base(void) +{ + unsigned long base = 0; + +# if GFX_INIT_GU2 + if (gfx_init_type & GFX_INIT_TYPE_GU2) + base = gu2_get_graphics_register_base(); +# endif + + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_frame_buffer_base + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_frame_buffer_base(void) +{ + unsigned long base = 0; + +# if GFX_INIT_GU1 + if (gfx_init_type & GFX_INIT_TYPE_GU1) + base = gu1_get_frame_buffer_base(); +# endif +# if GFX_INIT_GU2 + if (gfx_init_type & GFX_INIT_TYPE_GU2) + base = gu2_get_frame_buffer_base(); +# endif + + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_frame_buffer_size + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_frame_buffer_size(void) +{ + unsigned long size = 0; + +# if GFX_INIT_GU1 + if (gfx_init_type & GFX_INIT_TYPE_GU1) + size = gu1_get_frame_buffer_size(); +# endif +# if GFX_INIT_GU2 + if (gfx_init_type & GFX_INIT_TYPE_GU2) + size = gu2_get_frame_buffer_size(); +# endif + + return size; +} + +/*----------------------------------------------------------------------------- + * gfx_get_vid_register_base + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vid_register_base(void) +{ + unsigned long base = 0; + +# if GFX_INIT_GU1 + if (gfx_init_type & GFX_INIT_TYPE_GU1) + base = gu1_get_vid_register_base(); +# endif +# if GFX_INIT_GU2 + if (gfx_init_type & GFX_INIT_TYPE_GU2) + base = gu2_get_vid_register_base(); +# endif + + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_register_base + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vip_register_base(void) +{ + unsigned long base = 0; + +# if GFX_INIT_GU1 + if (gfx_init_type & GFX_INIT_TYPE_GU1) + base = gu1_get_vip_register_base(); +# endif + + return (base); +} + +#endif + +/* END OF FILE */ + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_mode.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_mode.h new file mode 100644 index 000000000..100b36c18 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_mode.h @@ -0,0 +1,226 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_mode.h,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: gfx_mode.h $ + * + * This header file contains the mode tables. It is used by the "gfx_disp.c" + * file to set a display mode. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef _gfx_mode_h +#define _gfx_mode_h + +/* MODE FLAGS (BITWISE-OR) */ + +#define GFX_MODE_8BPP 0x00000001 +#define GFX_MODE_12BPP 0x00000002 +#define GFX_MODE_15BPP 0x00000004 +#define GFX_MODE_16BPP 0x00000008 +#define GFX_MODE_24BPP 0x00000010 +#define GFX_MODE_56HZ 0x00000020 +#define GFX_MODE_60HZ 0x00000040 +#define GFX_MODE_70HZ 0x00000080 +#define GFX_MODE_72HZ 0x00000100 +#define GFX_MODE_75HZ 0x00000200 +#define GFX_MODE_85HZ 0x00000400 +#define GFX_MODE_NEG_HSYNC 0x00000800 +#define GFX_MODE_NEG_VSYNC 0x00001000 +#define GFX_MODE_PIXEL_DOUBLE 0x00002000 +#define GFX_MODE_LINE_DOUBLE 0x00004000 +#define GFX_MODE_TV_NTSC 0x00008000 +#define GFX_MODE_TV_PAL 0x00010000 + +#define GFX_MODE_LOCK_TIMING 0x10000000 + +/* STRUCTURE DEFINITION */ + +typedef struct tagDISPLAYMODE +{ + /* DISPLAY MODE FLAGS */ + /* Specify valid color depths and the refresh rate. */ + + unsigned long flags; + + /* TIMINGS */ + + unsigned short hactive; + unsigned short hblankstart; + unsigned short hsyncstart; + unsigned short hsyncend; + unsigned short hblankend; + unsigned short htotal; + + unsigned short vactive; + unsigned short vblankstart; + unsigned short vsyncstart; + unsigned short vsyncend; + unsigned short vblankend; + unsigned short vtotal; + + /* CLOCK FREQUENCY */ + + unsigned long frequency; + +} +DISPLAYMODE; + +/* For Fixed timings */ +typedef struct tagFIXEDTIMINGS +{ + /* DISPLAY MODE FLAGS */ + /* Specify valid color depths and the refresh rate. */ + + int panelresx; + int panelresy; + unsigned short xres; + unsigned short yres; + + /* TIMINGS */ + + unsigned short hactive; + unsigned short hblankstart; + unsigned short hsyncstart; + unsigned short hsyncend; + unsigned short hblankend; + unsigned short htotal; + + unsigned short vactive; + unsigned short vblankstart; + unsigned short vsyncstart; + unsigned short vsyncend; + unsigned short vblankend; + unsigned short vtotal; + + /* CLOCK FREQUENCY */ + + unsigned long frequency; + +} +FIXEDTIMINGS; + +#endif /* !_gfx_mode_h */ + +/* END OF FILE */ + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_msr.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_msr.c new file mode 100644 index 000000000..c6b1caf49 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_msr.c @@ -0,0 +1,253 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_msr.c,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: gfx_msr.c $ + * + * This file contains routines to read machine-specific registers (MSRs) + * + * Routines: + * + * gfx_msr_init + * gfx_id_msr_device + * gfx_get_msr_dev_address + * gfx_get_glink_id_at_address + * gfx_msr_read + * gfx_msr_write + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* INCLUDE SUPPORT FOR REDCLOUD, IF SPECIFIED */ + +#if GFX_MSR_REDCLOUD +#include "msr_rdcl.c" +#endif + +/* EXTRA WRAPPERS FOR DYNAMIC SELECTION */ + +#if GFX_MSR_DYNAMIC + +/*----------------------------------------------------------------------------- + * gfx_msr_init + *----------------------------------------------------------------------------- + */ +int +gfx_msr_init() +{ + int ret_value = 0; + +# if GFX_MSR_REDCLOUD + if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD) + ret_value = redcloud_msr_init(); +# endif + + return ret_value; +} + +/*----------------------------------------------------------------------------- + * gfx_id_msr_device + *----------------------------------------------------------------------------- + */ +DEV_STATUS +gfx_id_msr_device(MSR * pDev, unsigned long address) +{ + DEV_STATUS ret_value = NOT_KNOWN; + +# if GFX_MSR_REDCLOUD + if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD) + ret_value = redcloud_id_msr_device(pDev, address); +# endif + + return ret_value; +} + +/*----------------------------------------------------------------------------- + * gfx_get_msr_dev_address + *----------------------------------------------------------------------------- + */ +DEV_STATUS +gfx_get_msr_dev_address(unsigned int device, unsigned long *address) +{ + DEV_STATUS ret_value = NOT_KNOWN; + +# if GFX_MSR_REDCLOUD + if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD) + ret_value = redcloud_get_msr_dev_address(device, address); +# endif + + return ret_value; +} + +/*----------------------------------------------------------------------------- + * gfx_get_glink_id_at_address + *----------------------------------------------------------------------------- + */ +DEV_STATUS +gfx_get_glink_id_at_address(unsigned int *device, unsigned long address) +{ + DEV_STATUS ret_value = NOT_KNOWN; + +# if GFX_MSR_REDCLOUD + if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD) + ret_value = redcloud_get_glink_id_at_address(device, address); +# endif + + return ret_value; +} + +/*----------------------------------------------------------------------------- + * gfx_msr_read + *----------------------------------------------------------------------------- + */ +DEV_STATUS +gfx_msr_read(unsigned int device, unsigned int msrRegister, Q_WORD * msrValue) +{ + DEV_STATUS ret_value = NOT_KNOWN; + +# if GFX_MSR_REDCLOUD + if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD) + ret_value = redcloud_msr_read(device, msrRegister, msrValue); +# endif + + return ret_value; +} + +/*----------------------------------------------------------------------------- + * gfx_msr_write + *----------------------------------------------------------------------------- + */ +DEV_STATUS +gfx_msr_write(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue) +{ + DEV_STATUS ret_value = NOT_KNOWN; + +# if GFX_MSR_REDCLOUD + if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD) + ret_value = redcloud_msr_write(device, msrRegister, msrValue); +# endif + + return ret_value; +} + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_regs.h new file mode 100644 index 000000000..7b11887be --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_regs.h @@ -0,0 +1,1358 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_regs.h,v 1.2 2003/02/05 18:38:43 alanh Exp $ */ +/* + * $Workfile: gfx_regs.h $ + * + * This header file contains the graphics register definitions. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/*----------------------------------*/ +/* FIRST GENERATION GRAPHICS UNIT */ +/*----------------------------------*/ + +#define GP_DST_XCOOR 0x8100 /* x destination origin */ +#define GP_DST_YCOOR 0x8102 /* y destination origin */ +#define GP_WIDTH 0x8104 /* pixel width */ +#define GP_HEIGHT 0x8106 /* pixel height */ +#define GP_SRC_XCOOR 0x8108 /* x source origin */ +#define GP_SRC_YCOOR 0x810A /* y source origin */ + +#define GP_VECTOR_LENGTH 0x8104 /* vector length */ +#define GP_INIT_ERROR 0x8106 /* vector initial error */ +#define GP_AXIAL_ERROR 0x8108 /* axial error increment */ +#define GP_DIAG_ERROR 0x810A /* diagonal error increment */ + +#define GP_SRC_COLOR_0 0x810C /* source color 0 */ +#define GP_SRC_COLOR_1 0x810E /* source color 1 */ +#define GP_PAT_COLOR_0 0x8110 /* pattern color 0 */ +#define GP_PAT_COLOR_1 0x8112 /* pattern color 1 */ +#define GP_PAT_COLOR_2 0x8114 /* pattern color 2 */ +#define GP_PAT_COLOR_3 0x8116 /* pattern color 3 */ +#define GP_PAT_DATA_0 0x8120 /* bits 31:0 of pattern */ +#define GP_PAT_DATA_1 0x8124 /* bits 63:32 of pattern */ +#define GP_PAT_DATA_2 0x8128 /* bits 95:64 of pattern */ +#define GP_PAT_DATA_3 0x812C /* bits 127:96 of pattern */ + +#define GP_VGA_WRITE 0x8140 /* VGA write path control */ +#define GP_VGA_READ 0x8144 /* VGA read path control */ + +#define GP_RASTER_MODE 0x8200 /* raster operation */ +#define GP_VECTOR_MODE 0x8204 /* vector mode register */ +#define GP_BLIT_MODE 0x8208 /* blit mode register */ +#define GP_BLIT_STATUS 0x820C /* blit status register */ + +#define GP_VGA_BASE 0x8210 /* VGA memory offset (x64K) */ +#define GP_VGA_LATCH 0x8214 /* VGA display latch */ + +/* "GP_VECTOR_MODE" BIT DEFINITIONS */ + +#define VM_X_MAJOR 0x0000 /* X major vector */ +#define VM_Y_MAJOR 0x0001 /* Y major vector */ +#define VM_MAJOR_INC 0x0002 /* positive major axis step */ +#define VM_MINOR_INC 0x0004 /* positive minor axis step */ +#define VM_READ_DST_FB 0x0008 /* read destination data */ + +/* "GP_RASTER_MODE" BIT DEFINITIONS */ + +#define RM_PAT_DISABLE 0x0000 /* pattern is disabled */ +#define RM_PAT_MONO 0x0100 /* 1BPP pattern expansion */ +#define RM_PAT_DITHER 0x0200 /* 2BPP pattern expansion */ +#define RM_PAT_COLOR 0x0300 /* 8BPP or 16BPP pattern */ +#define RM_PAT_MASK 0x0300 /* mask for pattern mode */ +#define RM_PAT_TRANSPARENT 0x0400 /* transparent 1BPP pattern */ +#define RM_SRC_TRANSPARENT 0x0800 /* transparent 1BPP source */ + +/* "GP_BLIT_STATUS" BIT DEFINITIONS */ + +#define BS_BLIT_BUSY 0x0001 /* blit engine is busy */ +#define BS_PIPELINE_BUSY 0x0002 /* graphics pipeline is busy */ +#define BS_BLIT_PENDING 0x0004 /* blit pending */ +#define BC_FLUSH 0x0080 /* flush pipeline requests */ +#define BC_8BPP 0x0000 /* 8BPP mode */ +#define BC_16BPP 0x0100 /* 16BPP mode */ +#define BC_FB_WIDTH_1024 0x0000 /* framebuffer width = 1024 */ +#define BC_FB_WIDTH_2048 0x0200 /* framebuffer width = 2048 */ +#define BC_FB_WIDTH_4096 0x0400 /* framebuffer width = 4096 */ + +/* "GP_BLIT_MODE" BIT DEFINITIONS */ + +#define BM_READ_SRC_NONE 0x0000 /* source foreground color */ +#define BM_READ_SRC_FB 0x0001 /* read source from FB */ +#define BM_READ_SRC_BB0 0x0002 /* read source from BB0 */ +#define BM_READ_SRC_BB1 0x0003 /* read source from BB1 */ +#define BM_READ_SRC_MASK 0x0003 /* read source mask */ + +#define BM_READ_DST_NONE 0x0000 /* no destination data */ +#define BM_READ_DST_BB0 0x0008 /* destination from BB0 */ +#define BM_READ_DST_BB1 0x000C /* destination from BB1 */ +#define BM_READ_DST_FB0 0x0010 /* dest from FB (store BB0) */ +#define BM_READ_DST_FB1 0x0014 /* dest from FB (store BB1) */ +#define BM_READ_DST_MASK 0x001C /* read destination mask */ + +#define BM_WRITE_FB 0x0000 /* write to framebuffer */ +#define BM_WRITE_MEM 0x0020 /* write to memory */ +#define BM_WRITE_MASK 0x0020 /* write mask */ + +#define BM_SOURCE_COLOR 0x0000 /* source is 8BPP or 16BPP */ +#define BM_SOURCE_EXPAND 0x0040 /* source is 1BPP */ +#define BM_SOURCE_TEXT 0x00C0 /* source is 1BPP text */ +#define BM_SOURCE_MASK 0x00C0 /* source mask */ + +#define BM_REVERSE_Y 0x0100 /* reverse Y direction */ + +/*---------------------------------------*/ +/* FIRST GENERATION DISPLAY CONTROLLER */ +/*---------------------------------------*/ + +#define DC_UNLOCK 0x8300 /* lock register */ +#define DC_GENERAL_CFG 0x8304 /* config registers... */ +#define DC_TIMING_CFG 0x8308 +#define DC_OUTPUT_CFG 0x830C + +#define DC_FB_ST_OFFSET 0x8310 /* framebuffer start offset */ +#define DC_CB_ST_OFFSET 0x8314 /* compression start offset */ +#define DC_CURS_ST_OFFSET 0x8318 /* cursor start offset */ +#define DC_ICON_ST_OFFSET 0x831C /* icon start offset */ +#define DC_VID_ST_OFFSET 0x8320 /* video start offset */ +#define DC_LINE_DELTA 0x8324 /* fb and cb skip counts */ +#define DC_BUF_SIZE 0x8328 /* fb and cb line size */ + +#define DC_H_TIMING_1 0x8330 /* horizontal timing... */ +#define DC_H_TIMING_2 0x8334 +#define DC_H_TIMING_3 0x8338 +#define DC_FP_H_TIMING 0x833C + +#define DC_V_TIMING_1 0x8340 /* vertical timing... */ +#define DC_V_TIMING_2 0x8344 +#define DC_V_TIMING_3 0x8348 +#define DC_FP_V_TIMING 0x834C + +#define DC_CURSOR_X 0x8350 /* cursor x position */ +#define DC_ICON_X 0x8354 /* HACK - 1.3 definition */ +#define DC_V_LINE_CNT 0x8354 /* vertical line counter */ +#define DC_CURSOR_Y 0x8358 /* cursor y position */ +#define DC_ICON_Y 0x835C /* HACK - 1.3 definition */ +#define DC_SS_LINE_CMP 0x835C /* line compare value */ +#define DC_CURSOR_COLOR 0x8360 /* cursor colors */ +#define DC_ICON_COLOR 0x8364 /* icon colors */ +#define DC_BORDER_COLOR 0x8368 /* border color */ +#define DC_PAL_ADDRESS 0x8370 /* palette address */ +#define DC_PAL_DATA 0x8374 /* palette data */ +#define DC_DFIFO_DIAG 0x8378 /* display FIFO diagnostic */ +#define DC_CFIFO_DIAG 0x837C /* compression FIF0 diagnostic */ + +/* PALETTE LOCATIONS */ + +#define PAL_CURSOR_COLOR_0 0x100 +#define PAL_CURSOR_COLOR_1 0x101 +#define PAL_ICON_COLOR_0 0x102 +#define PAL_ICON_COLOR_1 0x103 +#define PAL_OVERSCAN_COLOR 0x104 + +/* UNLOCK VALUE */ + +#define DC_UNLOCK_VALUE 0x00004758 /* used to unlock DC regs */ + +/* "DC_GENERAL_CFG" BIT DEFINITIONS */ + +#define DC_GCFG_DFLE 0x00000001 /* display FIFO load enable */ +#define DC_GCFG_CURE 0x00000002 /* cursor enable */ +#define DC_GCFG_VCLK_DIV 0x00000004 /* vid clock divisor */ +#define DC_GCFG_PLNO 0x00000004 /* planar offset LSB */ +#define DC_GCFG_PPC 0x00000008 /* pixel pan compatibility */ +#define DC_GCFG_CMPE 0x00000010 /* compression enable */ +#define DC_GCFG_DECE 0x00000020 /* decompression enable */ +#define DC_GCFG_DCLK_MASK 0x000000C0 /* dotclock multiplier */ +#define DC_GCFG_DCLK_POS 6 /* dotclock multiplier */ +#define DC_GCFG_DFHPSL_MASK 0x00000F00 /* FIFO high-priority start */ +#define DC_GCFG_DFHPSL_POS 8 /* FIFO high-priority start */ +#define DC_GCFG_DFHPEL_MASK 0x0000F000 /* FIFO high-priority end */ +#define DC_GCFG_DFHPEL_POS 12 /* FIFO high-priority end */ +#define DC_GCFG_CIM_MASK 0x00030000 /* compressor insert mode */ +#define DC_GCFG_CIM_POS 16 /* compressor insert mode */ +#define DC_GCFG_FDTY 0x00040000 /* frame dirty mode */ +#define DC_GCFG_RTPM 0x00080000 /* real-time perf. monitor */ +#define DC_GCFG_DAC_RS_MASK 0x00700000 /* DAC register selects */ +#define DC_GCFG_DAC_RS_POS 20 /* DAC register selects */ +#define DC_GCFG_CKWR 0x00800000 /* clock write */ +#define DC_GCFG_LDBL 0x01000000 /* line double */ +#define DC_GCFG_DIAG 0x02000000 /* FIFO diagnostic mode */ +#define DC_GCFG_CH4S 0x04000000 /* sparse refresh mode */ +#define DC_GCFG_SSLC 0x08000000 /* enable line compare */ +#define DC_GCFG_VIDE 0x10000000 /* video enable */ +#define DC_GCFG_DFCK 0x20000000 /* divide flat-panel clock - rev 2.3 down */ +#define DC_GCFG_VRDY 0x20000000 /* video port speed - rev 2.4 up */ +#define DC_GCFG_DPCK 0x40000000 /* divide pixel clock */ +#define DC_GCFG_DDCK 0x80000000 /* divide dot clock */ + +/* "DC_TIMING_CFG" BIT DEFINITIONS */ + +#define DC_TCFG_FPPE 0x00000001 /* flat-panel power enable */ +#define DC_TCFG_HSYE 0x00000002 /* horizontal sync enable */ +#define DC_TCFG_VSYE 0x00000004 /* vertical sync enable */ +#define DC_TCFG_BLKE 0x00000008 /* blank enable */ +#define DC_TCFG_DDCK 0x00000010 /* DDC clock */ +#define DC_TCFG_TGEN 0x00000020 /* timing generator enable */ +#define DC_TCFG_VIEN 0x00000040 /* vertical interrupt enable */ +#define DC_TCFG_BLNK 0x00000080 /* blink enable */ +#define DC_TCFG_CHSP 0x00000100 /* horizontal sync polarity */ +#define DC_TCFG_CVSP 0x00000200 /* vertical sync polarity */ +#define DC_TCFG_FHSP 0x00000400 /* panel horz sync polarity */ +#define DC_TCFG_FVSP 0x00000800 /* panel vert sync polarity */ +#define DC_TCFG_FCEN 0x00001000 /* flat-panel centering */ +#define DC_TCFG_CDCE 0x00002000 /* HACK - 1.3 definition */ +#define DC_TCFG_PLNR 0x00002000 /* planar mode enable */ +#define DC_TCFG_INTL 0x00004000 /* interlace scan */ +#define DC_TCFG_PXDB 0x00008000 /* pixel double */ +#define DC_TCFG_BKRT 0x00010000 /* blink rate */ +#define DC_TCFG_PSD_MASK 0x000E0000 /* power sequence delay */ +#define DC_TCFG_PSD_POS 17 /* power sequence delay */ +#define DC_TCFG_DDCI 0x08000000 /* DDC input (RO) */ +#define DC_TCFG_SENS 0x10000000 /* monitor sense (RO) */ +#define DC_TCFG_DNA 0x20000000 /* display not active (RO) */ +#define DC_TCFG_VNA 0x40000000 /* vertical not active (RO) */ +#define DC_TCFG_VINT 0x80000000 /* vertical interrupt (RO) */ + +/* "DC_OUTPUT_CFG" BIT DEFINITIONS */ + +#define DC_OCFG_8BPP 0x00000001 /* 8/16 bpp select */ +#define DC_OCFG_555 0x00000002 /* 16 bpp format */ +#define DC_OCFG_PCKE 0x00000004 /* PCLK enable */ +#define DC_OCFG_FRME 0x00000008 /* frame rate mod enable */ +#define DC_OCFG_DITE 0x00000010 /* dither enable */ +#define DC_OCFG_2PXE 0x00000020 /* 2 pixel enable */ +#define DC_OCFG_2XCK 0x00000040 /* 2 x pixel clock */ +#define DC_OCFG_2IND 0x00000080 /* 2 index enable */ +#define DC_OCFG_34ADD 0x00000100 /* 3- or 4-bit add */ +#define DC_OCFG_FRMS 0x00000200 /* frame rate mod select */ +#define DC_OCFG_CKSL 0x00000400 /* clock select */ +#define DC_OCFG_PRMP 0x00000800 /* palette re-map */ +#define DC_OCFG_PDEL 0x00001000 /* panel data enable low */ +#define DC_OCFG_PDEH 0x00002000 /* panel data enable high */ +#define DC_OCFG_CFRW 0x00004000 /* comp line buffer r/w sel */ +#define DC_OCFG_DIAG 0x00008000 /* comp line buffer diag */ + +#define MC_MEM_CNTRL1 0x00008400 +#define MC_DR_ADD 0x00008418 +#define MC_DR_ACC 0x0000841C + +/* MC_MEM_CNTRL1 BIT DEFINITIONS */ + +#define MC_XBUSARB 0x00000008 /* 0 = GP priority < CPU priority */ + /* 1 = GP priority = CPU priority */ + /* GXm databook V2.0 is wrong ! */ +/*----------*/ +/* CS5530 */ +/*----------*/ + +/* CS5530 REGISTER DEFINITIONS */ + +#define CS5530_VIDEO_CONFIG 0x0000 +#define CS5530_DISPLAY_CONFIG 0x0004 +#define CS5530_VIDEO_X_POS 0x0008 +#define CS5530_VIDEO_Y_POS 0x000C +#define CS5530_VIDEO_SCALE 0x0010 +#define CS5530_VIDEO_COLOR_KEY 0x0014 +#define CS5530_VIDEO_COLOR_MASK 0x0018 +#define CS5530_PALETTE_ADDRESS 0x001C +#define CS5530_PALETTE_DATA 0x0020 +#define CS5530_DOT_CLK_CONFIG 0x0024 +#define CS5530_CRCSIG_TFT_TV 0x0028 + +/* "CS5530_VIDEO_CONFIG" BIT DEFINITIONS */ + +#define CS5530_VCFG_VID_EN 0x00000001 +#define CS5530_VCFG_VID_REG_UPDATE 0x00000002 +#define CS5530_VCFG_VID_INP_FORMAT 0x0000000C +#define CS5530_VCFG_8_BIT_4_2_0 0x00000004 +#define CS5530_VCFG_16_BIT_4_2_0 0x00000008 +#define CS5530_VCFG_GV_SEL 0x00000010 +#define CS5530_VCFG_CSC_BYPASS 0x00000020 +#define CS5530_VCFG_X_FILTER_EN 0x00000040 +#define CS5530_VCFG_Y_FILTER_EN 0x00000080 +#define CS5530_VCFG_LINE_SIZE_LOWER_MASK 0x0000FF00 +#define CS5530_VCFG_INIT_READ_MASK 0x01FF0000 +#define CS5530_VCFG_EARLY_VID_RDY 0x02000000 +#define CS5530_VCFG_LINE_SIZE_UPPER 0x08000000 +#define CS5530_VCFG_4_2_0_MODE 0x10000000 +#define CS5530_VCFG_16_BIT_EN 0x20000000 +#define CS5530_VCFG_HIGH_SPD_INT 0x40000000 + +/* "CS5530_DISPLAY_CONFIG" BIT DEFINITIONS */ + +#define CS5530_DCFG_DIS_EN 0x00000001 +#define CS5530_DCFG_HSYNC_EN 0x00000002 +#define CS5530_DCFG_VSYNC_EN 0x00000004 +#define CS5530_DCFG_DAC_BL_EN 0x00000008 +#define CS5530_DCFG_DAC_PWDNX 0x00000020 +#define CS5530_DCFG_FP_PWR_EN 0x00000040 +#define CS5530_DCFG_FP_DATA_EN 0x00000080 +#define CS5530_DCFG_CRT_HSYNC_POL 0x00000100 +#define CS5530_DCFG_CRT_VSYNC_POL 0x00000200 +#define CS5530_DCFG_FP_HSYNC_POL 0x00000400 +#define CS5530_DCFG_FP_VSYNC_POL 0x00000800 +#define CS5530_DCFG_XGA_FP 0x00001000 +#define CS5530_DCFG_FP_DITH_EN 0x00002000 +#define CS5530_DCFG_CRT_SYNC_SKW_MASK 0x0001C000 +#define CS5530_DCFG_CRT_SYNC_SKW_INIT 0x00010000 +#define CS5530_DCFG_PWR_SEQ_DLY_MASK 0x000E0000 +#define CS5530_DCFG_PWR_SEQ_DLY_INIT 0x00080000 +#define CS5530_DCFG_VG_CK 0x00100000 +#define CS5530_DCFG_GV_PAL_BYP 0x00200000 +#define CS5530_DCFG_DDC_SCL 0x00400000 +#define CS5530_DCFG_DDC_SDA 0x00800000 +#define CS5530_DCFG_DDC_OE 0x01000000 +#define CS5530_DCFG_16_BIT_EN 0x02000000 + +/*----------*/ +/* SC1200 */ +/*----------*/ + +/* SC1200 VIDEO REGISTER DEFINITIONS */ + +#define SC1200_VIDEO_CONFIG 0x000 +#define SC1200_DISPLAY_CONFIG 0x004 +#define SC1200_VIDEO_X_POS 0x008 +#define SC1200_VIDEO_Y_POS 0x00C +#define SC1200_VIDEO_UPSCALE 0x010 +#define SC1200_VIDEO_COLOR_KEY 0x014 +#define SC1200_VIDEO_COLOR_MASK 0x018 +#define SC1200_PALETTE_ADDRESS 0x01C +#define SC1200_PALETTE_DATA 0x020 +#define SC1200_VID_MISC 0x028 +#define SC1200_VID_CLOCK_SELECT 0x02C +#define SC1200_VIDEO_DOWNSCALER_CONTROL 0x03C +#define SC1200_VIDEO_DOWNSCALER_COEFFICIENTS 0x40 +#define SC1200_VID_CRC 0x044 +#define SC1200_DEVICE_ID 0x048 +#define SC1200_VID_ALPHA_CONTROL 0x04C +#define SC1200_CURSOR_COLOR_KEY 0x050 +#define SC1200_CURSOR_COLOR_MASK 0x054 +#define SC1200_CURSOR_COLOR_1 0x058 +#define SC1200_CURSOR_COLOR_2 0x05C +#define SC1200_ALPHA_XPOS_1 0x060 +#define SC1200_ALPHA_YPOS_1 0x064 +#define SC1200_ALPHA_COLOR_1 0x068 +#define SC1200_ALPHA_CONTROL_1 0x06C +#define SC1200_ALPHA_XPOS_2 0x070 +#define SC1200_ALPHA_YPOS_2 0x074 +#define SC1200_ALPHA_COLOR_2 0x078 +#define SC1200_ALPHA_CONTROL_2 0x07C +#define SC1200_ALPHA_XPOS_3 0x080 +#define SC1200_ALPHA_YPOS_3 0x084 +#define SC1200_ALPHA_COLOR_3 0x088 +#define SC1200_ALPHA_CONTROL_3 0x08C +#define SC1200_VIDEO_REQUEST 0x090 +#define SC1200_ALPHA_WATCH 0x094 +#define SC1200_VIDEO_DISPLAY_MODE 0x400 +#define SC1200_VIDEO_ODD_VBI_LINE_ENABLE 0x40C +#define SC1200_VIDEO_EVEN_VBI_LINE_ENABLE 0x410 +#define SC1200_VIDEO_VBI_HORIZ_CONTROL 0x414 +#define SC1200_VIDEO_ODD_VBI_TOTAL_COUNT 0x418 +#define SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT 0x41C +#define SC1200_GENLOCK 0x420 +#define SC1200_GENLOCK_DELAY 0x424 +#define SC1200_TVOUT_HORZ_TIM 0x800 +#define SC1200_TVOUT_HORZ_SYNC 0x804 +#define SC1200_TVOUT_VERT_SYNC 0x808 +#define SC1200_TVOUT_LINE_END 0x80C +#define SC1200_TVOUT_VERT_DOWNSCALE 0x810 /* REV. A & B */ +#define SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE 0x810 /* REV. C */ +#define SC1200_TVOUT_HORZ_SCALING 0x814 +#define SC1200_TVOUT_DEBUG 0x818 +#define SC1200_TVENC_TIM_CTRL_1 0xC00 +#define SC1200_TVENC_TIM_CTRL_2 0xC04 +#define SC1200_TVENC_TIM_CTRL_3 0xC08 +#define SC1200_TVENC_SUB_FREQ 0xC0C +#define SC1200_TVENC_DISP_POS 0xC10 +#define SC1200_TVENC_DISP_SIZE 0xC14 +#define SC1200_TVENC_CC_DATA 0xC18 +#define SC1200_TVENC_EDS_DATA 0xC1C +#define SC1200_TVENC_CGMS_DATA 0xC20 +#define SC1200_TVENC_WSS_DATA 0xC24 +#define SC1200_TVENC_CC_CONTROL 0xC28 +#define SC1200_TVENC_DAC_CONTROL 0xC2C +#define SC1200_TVENC_MV_CONTROL 0xC30 + +/* "SC1200_VIDEO_CONFIG" BIT DEFINITIONS */ + +#define SC1200_VCFG_VID_EN 0x00000001 +#define SC1200_VCFG_VID_INP_FORMAT 0x0000000C +#define SC1200_VCFG_UYVY_FORMAT 0x00000000 +#define SC1200_VCFG_Y2YU_FORMAT 0x00000004 +#define SC1200_VCFG_YUYV_FORMAT 0x00000008 +#define SC1200_VCFG_YVYU_FORMAT 0x0000000C +#define SC1200_VCFG_X_FILTER_EN 0x00000040 +#define SC1200_VCFG_Y_FILTER_EN 0x00000080 +#define SC1200_VCFG_LINE_SIZE_LOWER_MASK 0x0000FF00 +#define SC1200_VCFG_INIT_READ_MASK 0x01FF0000 +#define SC1200_VCFG_LINE_SIZE_UPPER 0x08000000 +#define SC1200_VCFG_4_2_0_MODE 0x10000000 + +/* "SC1200_DISPLAY_CONFIG" BIT DEFINITIONS */ + +#define SC1200_DCFG_DIS_EN 0x00000001 +#define SC1200_DCFG_HSYNC_EN 0x00000002 +#define SC1200_DCFG_VSYNC_EN 0x00000004 +#define SC1200_DCFG_DAC_BL_EN 0x00000008 +#define SC1200_DCFG_FP_PWR_EN 0x00000040 +#define SC1200_DCFG_FP_DATA_EN 0x00000080 +#define SC1200_DCFG_CRT_HSYNC_POL 0x00000100 +#define SC1200_DCFG_CRT_VSYNC_POL 0x00000200 +#define SC1200_DCFG_CRT_SYNC_SKW_MASK 0x0001C000 +#define SC1200_DCFG_CRT_SYNC_SKW_INIT 0x00010000 +#define SC1200_DCFG_PWR_SEQ_DLY_MASK 0x000E0000 +#define SC1200_DCFG_PWR_SEQ_DLY_INIT 0x00080000 +#define SC1200_DCFG_VG_CK 0x00100000 +#define SC1200_DCFG_GV_PAL_BYP 0x00200000 +#define SC1200_DCFG_DDC_SCL 0x00400000 +#define SC1200_DCFG_DDC_SDA 0x00800000 +#define SC1200_DCFG_DDC_OE 0x01000000 + +/* "SC1200_VID_MISC" BIT DEFINITIONS */ + +#define SC1200_GAMMA_BYPASS_BOTH 0x00000001 +#define SC1200_DAC_POWER_DOWN 0x00000400 +#define SC1200_ANALOG_POWER_DOWN 0x00000800 +#define SC1200_PLL_POWER_NORMAL 0x00001000 + +/* "SC1200_VIDEO_DOWNSCALER_CONTROL" BIT DEFINITIONS */ + +#define SC1200_VIDEO_DOWNSCALE_ENABLE 0x00000001 +#define SC1200_VIDEO_DOWNSCALE_FACTOR_POS 1 +#define SC1200_VIDEO_DOWNSCALE_FACTOR_MASK 0x0000001E +#define SC1200_VIDEO_DOWNSCALE_TYPE_A 0x00000000 +#define SC1200_VIDEO_DOWNSCALE_TYPE_B 0x00000040 +#define SC1200_VIDEO_DOWNSCALE_TYPE_MASK 0x00000040 + +/* "SC1200_VIDEO_DOWNSCALER_COEFFICIENTS" BIT DEFINITIONS */ + +#define SC1200_VIDEO_DOWNSCALER_COEF1_POS 0 +#define SC1200_VIDEO_DOWNSCALER_COEF2_POS 8 +#define SC1200_VIDEO_DOWNSCALER_COEF3_POS 16 +#define SC1200_VIDEO_DOWNSCALER_COEF4_POS 24 +#define SC1200_VIDEO_DOWNSCALER_COEF_MASK 0xF + +/* VIDEO DE-INTERLACING AND ALPHA CONTROL (REGISTER 0x4C) */ + +#define SC1200_VERTICAL_SCALER_SHIFT_MASK 0x00000007 +#define SC1200_VERTICAL_SCALER_SHIFT_INIT 0x00000004 +#define SC1200_VERTICAL_SCALER_SHIFT_EN 0x00000010 +#define SC1200_TOP_LINE_IN_ODD 0x00000040 +#define SC1200_NO_CK_OUTSIDE_ALPHA 0x00000100 +#define SC1200_VIDEO_IS_INTERLACED 0x00000200 +#define SC1200_CSC_VIDEO_YUV_TO_RGB 0x00000400 +#define SC1200_CSC_GFX_RGB_TO_YUV 0x00000800 +#define SC1200_VIDEO_INPUT_IS_RGB 0x00002000 +#define SC1200_VIDEO_LINE_OFFSET_ODD 0x00001000 +#define SC1200_ALPHA1_PRIORITY_POS 16 +#define SC1200_ALPHA1_PRIORITY_MASK 0x00030000 +#define SC1200_ALPHA2_PRIORITY_POS 18 +#define SC1200_ALPHA2_PRIORITY_MASK 0x000C0000 +#define SC1200_ALPHA3_PRIORITY_POS 20 +#define SC1200_ALPHA3_PRIORITY_MASK 0x00300000 + +/* VIDEO CURSOR COLOR KEY DEFINITIONS (REGISTER 0x50) */ + +#define SC1200_CURSOR_COLOR_KEY_OFFSET_POS 24 +#define SC1200_CURSOR_COLOR_BITS 23 +#define SC1200_COLOR_MASK 0x00FFFFFF /* 24 significant bits */ + +/* ALPHA COLOR BIT DEFINITION (REGISTERS 0x68, 0x78, AND 0x88) */ + +#define SC1200_ALPHA_COLOR_ENABLE 0x01000000 + +/* ALPHA CONTROL BIT DEFINITIONS (REGISTERS 0x6C, 0x7C, AND 0x8C) */ + +#define SC1200_ACTRL_WIN_ENABLE 0x00010000 +#define SC1200_ACTRL_LOAD_ALPHA 0x00020000 + +/* VIDEO REQUEST DEFINITIONS (REGISTER 0x90) */ + +#define SC1200_VIDEO_Y_REQUEST_POS 0 +#define SC1200_VIDEO_X_REQUEST_POS 16 +#define SC1200_VIDEO_REQUEST_MASK 0x00000FFF + +/* VIDEO DISPLAY MODE (REGISTER 0x400) */ + +#define SC1200_VIDEO_SOURCE_MASK 0x00000003 +#define SC1200_VIDEO_SOURCE_GX1 0x00000000 +#define SC1200_VIDEO_SOURCE_DVIP 0x00000002 +#define SC1200_VBI_SOURCE_MASK 0x00000004 +#define SC1200_VBI_SOURCE_DVIP 0x00000000 +#define SC1200_VBI_SOURCE_GX1 0x00000004 + +/* ODD/EVEN VBI LINE ENABLE (REGISTERS 0x40C, 0x410) */ + +#define SC1200_VIDEO_VBI_LINE_ENABLE_MASK 0x00FFFFFC +#define SC1200_VIDEO_ALL_ACTIVE_IS_VBI 0x01000000 +#define SC1200_VIDEO_VBI_LINE_OFFSET_POS 25 +#define SC1200_VIDEO_VBI_LINE_OFFSET_MASK 0x3E000000 + +/* ODD/EVEN VBI TOTAL COUNT (REGISTERS 0x418, 0x41C) */ + +#define SC1200_VIDEO_VBI_TOTAL_COUNT_MASK 0x000FFFFF + +/* GENLOCK BIT DEFINITIONS */ + +#define SC1200_GENLOCK_SINGLE_ENABLE 0x00000001 +#define SC1200_GENLOCK_FIELD_SYNC_ENABLE 0x00000001 +#define SC1200_GENLOCK_CONTINUOUS_ENABLE 0x00000002 +#define SC1200_GENLOCK_GX_VSYNC_FALLING_EDGE 0x00000004 +#define SC1200_GENLOCK_VIP_VSYNC_FALLING_EDGE 0x00000008 +#define SC1200_GENLOCK_TIMEOUT_ENABLE 0x00000010 +#define SC1200_GENLOCK_TVENC_RESET_EVEN_FIELD 0x00000020 +#define SC1200_GENLOCK_TVENC_RESET_BEFORE_DELAY 0x00000040 +#define SC1200_GENLOCK_TVENC_RESET_ENABLE 0x00000080 +#define SC1200_GENLOCK_SYNC_TO_TVENC 0x00000100 +#define SC1200_GENLOCK_DELAY_MASK 0x001FFFFF + +/* TVOUT HORIZONTAL PRE ENCODER SCALE BIT DEFINITIONS */ + +#define SC1200_TVOUT_YC_DELAY_MASK 0x00C00000 +#define SC1200_TVOUT_YC_DELAY_NONE 0x00000000 +#define SC1200_TVOUT_Y_DELAY_ONE_PIXEL 0x00400000 +#define SC1200_TVOUT_C_DELAY_ONE_PIXEL 0x00800000 +#define SC1200_TVOUT_C_DELAY_TWO_PIXELS 0x00C00000 + +/* TVOUT HORIZONTAL SCALING/CONTROL BIT DEFINITIONS */ + +#define SC1200_TVOUT_FLICKER_FILTER_MASK 0x60000000 +#define SC1200_TVOUT_FLICKER_FILTER_FOURTH_HALF_FOURTH 0x00000000 +#define SC1200_TVOUT_FLICKER_FILTER_HALF_ONE_HALF 0x20000000 +#define SC1200_TVOUT_FLICKER_FILTER_DISABLED 0x40000000 +#define SC1200_TVENC_EXTERNAL_RESET_INTERVAL_MASK 0x0F000000 +#define SC1200_TVENC_EXTERNAL_RESET_EVERY_ODD_FIELD 0x00000000 +#define SC1200_TVENC_EXTERNAL_RESET_EVERY_EVEN_FIELD 0x02000000 +#define SC1200_TVENC_EXTERNAL_RESET_NEXT_ODD_FIELD 0x05000000 +#define SC1200_TVENC_EXTERNAL_RESET_NEXT_EVEN_FIELD 0x07000000 +#define SC1200_TVENC_EXTERNAL_RESET_EVERY_FIELD 0x0E000000 +#define SC1200_TVENC_EXTERNAL_RESET_EVERY_X_ODD_FIELDS 0x08000000 +#define SC1200_TVENC_EXTERNAL_RESET_EVERY_X_EVEN_FIELDS 0x0A000000 + +/* TVOUT DEBUG BIT DEFINITIONS */ + +#define SC1200_TVOUT_FIELD_STATUS_EVEN 0x00000040 +#define SC1200_TVOUT_FIELD_STATUS_TV 0x00000080 +#define SC1200_TVOUT_CRT_VSYNC_STATUS_TRAILING 0x00000100 +#define SC1200_TVOUT_FIELD_STATUS_INVERT 0x00000200 +#define SC1200_TVOUT_CONVERTER_INTERPOLATION 0x00000400 + +/* TVENC TIMING/CONTROL 1 BIT DEFINITIONS (REGISTER 0xC00) */ + +#define SC1200_TVENC_VPHASE_MASK 0x001FF800 +#define SC1200_TVENC_VPHASE_POS 11 +#define SC1200_TVENC_SUB_CARRIER_RESET_MASK 0x30000000 +#define SC1200_TVENC_SUB_CARRIER_RESET_NEVER 0x00000000 +#define SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_LINES 0x10000000 +#define SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_FRAMES 0x20000000 +#define SC1200_TVENC_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES 0x30000000 +#define SC1200_TVENC_VIDEO_TIMING_ENABLE 0x80000000 + +/* TVENC TIMING/CONTROL 2 BIT DEFINITIONS (REGISTER 0xC04) */ + +#define SC1200_TVENC_OUTPUT_YCBCR 0x40000000 +#define SC1200_TVENC_CFS_MASK 0x00030000 +#define SC1200_TVENC_CFS_BYPASS 0x00000000 +#define SC1200_TVENC_CFS_CVBS 0x00020000 +#define SC1200_TVENC_CFS_SVIDEO 0x00030000 + +/* TVENC TIMING/CONTROL 3 BIT DEFINITIONS (REGISTER 0xC08) */ + +#define SC1200_TVENC_CS 0x00000001 +#define SC1200_TVENC_SYNCMODE_MASK 0x00000006 +#define SC1200_TVENC_SYNC_ON_GREEN 0x00000002 +#define SC1200_TVENC_SYNC_ON_CVBS 0x00000004 +#define SC1200_TVENC_CM 0x00000008 + +/* TVENC DAC CONTROL BIT DEFINITIONS (REGISTER 0xC2C) */ +#define SC1200_TVENC_TRIM_MASK 0x00000007 +#define SC1200_TVENC_POWER_DOWN 0x00000020 + +/* TVENC MV CONTROL BIT DEFINITIONS (REGISTER 0xC30) */ +#define SC1200_TVENC_MV_ENABLE 0xBE + +/* SC1200 VIP REGISTER DEFINITIONS */ + +#define SC1200_VIP_CONFIG 0x00000000 +#define SC1200_VIP_CONTROL 0x00000004 +#define SC1200_VIP_STATUS 0x00000008 +#define SC1200_VIP_CURRENT_LINE 0x00000010 +#define SC1200_VIP_LINE_TARGET 0x00000014 +#define SC1200_ODD_DIRECT_VBI_LINE_ENABLE 0x00000018 +#define SC1200_EVEN_DIRECT_VBI_LINE_ENABLE 0x0000001C +#define SC1200_VIP_ODD_BASE 0x00000020 +#define SC1200_VIP_EVEN_BASE 0x00000024 +#define SC1200_VIP_PITCH 0x00000028 +#define SC1200_VBI_ODD_BASE 0x00000040 +#define SC1200_VBI_EVEN_BASE 0x00000044 +#define SC1200_VBI_PITCH 0x00000048 + +/* "SC1200_VIP_CONFIG" BIT DEFINITIONS */ + +#define SC1200_VIP_MODE_MASK 0x00000003 +#define SC1200_VIP_MODE_C 0x00000002 +#define SC1200_VBI_ANCILLARY_TO_MEMORY 0x000C0000 +#define SC1200_VBI_TASK_A_TO_MEMORY 0x00140000 +#define SC1200_VBI_TASK_B_TO_MEMORY 0x00240000 +#define SC1200_VIP_BUS_REQUEST_THRESHOLD 0x00400000 + +/* "SC1200_VIP_CONTROL" BIT DEFINITIONS */ + +#define SC1200_CAPTURE_RUN_MODE_MASK 0x00000003 +#define SC1200_CAPTURE_RUN_MODE_STOP_LINE 0x00000000 +#define SC1200_CAPTURE_RUN_MODE_STOP_FIELD 0x00000001 +#define SC1200_CAPTURE_RUN_MODE_START 0x00000003 +#define SC1200_VIP_DATA_CAPTURE_EN 0x00000100 +#define SC1200_VIP_VBI_CAPTURE_EN 0x00000200 +#define SC1200_VIP_VBI_FIELD_INTERRUPT_EN 0x00010000 + +/* "SC1200_VIP_STATUS" BIT DEFINITIONS */ + +#define SC1200_VIP_CURRENT_FIELD_ODD 0x01000000 +#define SC1200_VIP_BASE_NOT_UPDATED 0x00200000 +#define SC1200_VIP_FIFO_OVERFLOW 0x00100000 +#define SC1200_VIP_CLEAR_LINE_INT 0x00020000 +#define SC1200_VIP_CLEAR_FIELD_INT 0x00010000 +#define SC1200_VBI_DATA_CAPTURE_ACTIVE 0x00000200 +#define SC1200_VIDEO_DATA_CAPTURE_ACTIVE 0x00000100 + +/* "SC1200_VIP_CURRENT_LINE" BIT DEFINITIONS */ + +#define SC1200_VIP_CURRENT_LINE_MASK 0x000003FF + +/* "SC1200_VIP_LINE_TARGET" BIT DEFINITIONS */ + +#define SC1200_VIP_LAST_LINE_MASK 0x03FF0000 + +/* "SC1200_VIP_PITCH" BIT DEFINITION */ + +#define SC1200_VIP_PITCH_MASK 0x0000FFFC + +/* "SC1200_VBI_PITCH" BIT DEFINITION */ + +#define SC1200_VBI_PITCH_MASK 0x0000FFFC + +/* SC1200 DIRECT VBI LINE ENABLE BIT DEFINITION */ + +#define SC1200_DIRECT_VBI_LINE_ENABLE_MASK 0x00FFFFFF + +/* SC1200 CONFIGURATION BLOCK */ + +#define SC1200_CB_BASE_ADDR 0x9000 +#define SC1200_CB_WDTO 0x0000 +#define SC1200_CB_WDCNFG 0x0002 +#define SC1200_CB_WDSTS 0x0004 +#define SC1200_CB_TMVALUE 0x0008 +#define SC1200_CB_TMCNFG 0x000D +#define SC1200_CB_PMR 0x0030 +#define SC1200_CB_MCR 0x0034 +#define SC1200_CB_INTSEL 0x0038 +#define SC1200_CB_PID 0x003C +#define SC1200_CB_REV 0x003D + +/* SC1200 HIGH RESOLUTION TIMER CONFIGURATION REGISTER BITS */ + +#define SC1200_TMCLKSEL_27MHZ 0x2 + +/*---------------------------------*/ +/* PHILIPS SAA7114 VIDEO DECODER */ +/*---------------------------------*/ + +#define SAA7114_CHIPADDR 0x42 + +/* VIDEO DECODER REGISTER DEFINITIONS */ + +#define SAA7114_ANALOG_INPUT_CTRL1 0x02 +#define SAA7114_LUMINANCE_CONTROL 0x09 +#define SAA7114_BRIGHTNESS 0x0A +#define SAA7114_CONTRAST 0x0B +#define SAA7114_SATURATION 0x0C +#define SAA7114_HUE 0x0D +#define SAA7114_STATUS 0x1F +#define SAA7114_IPORT_CONTROL 0x86 + +/* TASK A REGISTER DEFINITIONS */ + +#define SAA7114_TASK_A_HORZ_OUTPUT_LO 0x9C +#define SAA7114_TASK_A_HORZ_OUTPUT_HI 0x9D +#define SAA7114_TASK_A_HSCALE_LUMA_LO 0xA8 +#define SAA7114_TASK_A_HSCALE_LUMA_HI 0xA9 +#define SAA7114_TASK_A_HSCALE_CHROMA_LO 0xAC +#define SAA7114_TASK_A_HSCALE_CHROMA_HI 0xAD + +/* TASK B REGISTER DEFINITIONS */ + +#define SAA7114_HORZ_OFFSET_LO 0xC4 +#define SAA7114_HORZ_OFFSET_HI 0xC5 +#define SAA7114_HORZ_INPUT_LO 0xC6 +#define SAA7114_HORZ_INPUT_HI 0xC7 +#define SAA7114_VERT_OFFSET_LO 0xC8 +#define SAA7114_VERT_OFFSET_HI 0xC9 +#define SAA7114_VERT_INPUT_LO 0xCA +#define SAA7114_VERT_INPUT_HI 0xCB +#define SAA7114_HORZ_OUTPUT_LO 0xCC +#define SAA7114_HORZ_OUTPUT_HI 0xCD +#define SAA7114_VERT_OUTPUT_LO 0xCE +#define SAA7114_VERT_OUTPUT_HI 0xCF +#define SAA7114_HORZ_PRESCALER 0xD0 +#define SAA7114_HORZ_ACL 0xD1 +#define SAA7114_HORZ_FIR_PREFILTER 0xD2 +#define SAA7114_FILTER_CONTRAST 0xD5 +#define SAA7114_FILTER_SATURATION 0xD6 +#define SAA7114_HSCALE_LUMA_LO 0xD8 +#define SAA7114_HSCALE_LUMA_HI 0xD9 +#define SAA7114_HSCALE_CHROMA_LO 0xDC +#define SAA7114_HSCALE_CHROMA_HI 0xDD +#define SAA7114_VSCALE_LUMA_LO 0xE0 +#define SAA7114_VSCALE_LUMA_HI 0xE1 +#define SAA7114_VSCALE_CHROMA_LO 0xE2 +#define SAA7114_VSCALE_CHROMA_HI 0xE3 +#define SAA7114_VSCALE_CONTROL 0xE4 +#define SAA7114_VSCALE_CHROMA_OFFS0 0xE8 +#define SAA7114_VSCALE_CHROMA_OFFS1 0xE9 +#define SAA7114_VSCALE_CHROMA_OFFS2 0xEA +#define SAA7114_VSCALE_CHROMA_OFFS3 0xEB +#define SAA7114_VSCALE_LUMINA_OFFS0 0xEC +#define SAA7114_VSCALE_LUMINA_OFFS1 0xED +#define SAA7114_VSCALE_LUMINA_OFFS2 0xEE +#define SAA7114_VSCALE_LUMINA_OFFS3 0xEF + +/* Still need to determine PHO value (common phase offset) */ +#define SAA7114_VSCALE_PHO 0x00 + +/*----------------------------------------------*/ +/* SECOND GENERATION GRAPHICS UNIT (REDCLOUD) */ +/*----------------------------------------------*/ + +#define MGP_DST_OFFSET 0x0000 /* dst address */ +#define MGP_SRC_OFFSET 0x0004 /* src address */ +#define MGP_VEC_ERR 0x0004 /* vector diag/axial errors */ +#define MGP_STRIDE 0x0008 /* src and dst strides */ +#define MGP_WID_HEIGHT 0x000C /* width and height of BLT */ +#define MGP_VEC_LEN 0x000C /* vector length/init error */ +#define MGP_SRC_COLOR_FG 0x0010 /* src mono data fgcolor */ +#define MGP_SRC_COLOR_BG 0x0014 /* src mono data bkcolor */ +#define MGP_PAT_COLOR_0 0x0018 /* pattern color 0 */ +#define MGP_PAT_COLOR_1 0x001C /* pattern color 1 */ +#define MGP_PAT_COLOR_2 0x0020 /* pattern color 2 */ +#define MGP_PAT_COLOR_3 0x0024 /* pattern color 3 */ +#define MGP_PAT_COLOR_4 0x0028 /* pattern color 4 */ +#define MGP_PAT_COLOR_5 0x002C /* pattern color 5 */ +#define MGP_PAT_DATA_0 0x0030 /* pattern data 0 */ +#define MGP_PAT_DATA_1 0x0034 /* pattern data 1 */ +#define MGP_RASTER_MODE 0x0038 /* raster operation */ +#define MGP_VECTOR_MODE 0x003C /* render vector */ +#define MGP_BLT_MODE 0x0040 /* render BLT */ +#define MGP_BLT_STATUS 0x0044 /* BLT status register */ +#define MGP_RESET 0x0044 /* reset register (write) */ +#define MGP_HST_SOURCE 0x0048 /* host src data (bitmap) */ +#define MGP_BASE_OFFSET 0x004C /* base render offset */ + +/* MGP_RASTER_MODE DEFINITIONS */ + +#define MGP_RM_BPPFMT_332 0x00000000 /* 8 BPP, 3:3:2 */ +#define MGP_RM_BPPFMT_4444 0x40000000 /* 16 BPP, 4:4:4:4 */ +#define MGP_RM_BPPFMT_1555 0x50000000 /* 16 BPP, 1:5:5:5 */ +#define MGP_RM_BPPFMT_565 0x60000000 /* 16 BPP, 5:6:5 */ +#define MGP_RM_BPPFMT_8888 0x80000000 /* 32 BPP, 8:8:8:8 */ +#define MGP_RM_ALPHA_EN_MASK 0x00C00000 /* Alpha enable */ +#define MGP_RM_ALPHA_TO_RGB 0x00400000 /* Alpha applies to RGB */ +#define MGP_RM_ALPHA_TO_ALPHA 0x00800000 /* Alpha applies to alpha */ +#define MGP_RM_ALPHA_OP_MASK 0x00300000 /* Alpha operation */ +#define MGP_RM_ALPHA_TIMES_A 0x00000000 /* Alpha * A */ +#define MGP_RM_BETA_TIMES_B 0x00100000 /* (1-alpha) * B */ +#define MGP_RM_A_PLUS_BETA_B 0x00200000 /* A + (1-alpha) * B */ +#define MGP_RM_ALPHA_A_PLUS_BETA_B 0x00300000 /* alpha * A + (1 - alpha)B */ +#define MGP_RM_ALPHA_SELECT 0x000E0000 /* Alpha Select */ +#define MGP_RM_SELECT_ALPHA_A 0x00000000 /* Alpha from channel A */ +#define MGP_RM_SELECT_ALPHA_B 0x00020000 /* Alpha from channel B */ +#define MGP_RM_SELECT_ALPHA_R 0x00040000 /* Registered alpha */ +#define MGP_RM_SELECT_ALPHA_1 0x00060000 /* Constant 1 */ +#define MGP_RM_SELECT_ALPHA_CHAN_A 0x00080000 /* RGB Values from A */ +#define MGP_RM_SELECT_ALPHA_CHAN_B 0x000A0000 /* RGB Values from B */ +#define MGP_RM_DEST_FROM_CHAN_A 0x00010000 /* Alpha channel select */ +#define MGP_RM_PAT_FLAGS 0x00000700 /* pattern related bits */ +#define MGP_RM_PAT_MONO 0x00000100 /* monochrome pattern */ +#define MGP_RM_PAT_COLOR 0x00000200 /* color pattern */ +#define MGP_RM_PAT_TRANS 0x00000400 /* pattern transparency */ +#define MGP_RM_SRC_TRANS 0x00000800 /* source transparency */ + +/* MGP_VECTOR_MODE DEFINITIONS */ + +#define MGP_VM_DST_REQ 0x00000008 /* dst data required */ +#define MGP_VM_THROTTLE 0x00000010 /* sync to VBLANK */ + +/* MGP_BLT_MODE DEFINITIONS */ + +#define MGP_BM_SRC_FB 0x00000001 /* src = frame buffer */ +#define MGP_BM_SRC_HOST 0x00000002 /* src = host register */ +#define MGP_BM_DST_REQ 0x00000004 /* dst data required */ +#define MGP_BM_SRC_MONO 0x00000040 /* monochrome source data */ +#define MGP_BM_SRC_BP_MONO 0x00000080 /* Byte-packed monochrome */ +#define MGP_BM_NEG_YDIR 0x00000100 /* negative Y direction */ +#define MGP_BM_NEG_XDIR 0x00000200 /* negative X direction */ +#define MGP_BM_THROTTLE 0x00000400 /* sync to VBLANK */ + +/* MGP_BLT_STATUS DEFINITIONS */ + +#define MGP_BS_BLT_BUSY 0x00000001 /* GP is not idle */ +#define MGP_BS_BLT_PENDING 0x00000004 /* second BLT is pending */ +#define MGP_BS_HALF_EMPTY 0x00000008 /* src FIFO half empty */ + +/* ALPHA BLENDING MODES */ + +#define ALPHA_MODE_BLEND 0x00000000 + +/*---------------------------------------------------*/ +/* SECOND GENERATION DISPLAY CONTROLLER (REDCLOUD) */ +/*---------------------------------------------------*/ + +#define MDC_UNLOCK 0x00000000 /* Unlock register */ +#define MDC_GENERAL_CFG 0x00000004 /* Config registers */ +#define MDC_DISPLAY_CFG 0x00000008 +#define MDC_GFX_SCL 0x0000000C /* Graphics scaling */ + +#define MDC_FB_ST_OFFSET 0x00000010 /* Frame buffer start offset */ +#define MDC_CB_ST_OFFSET 0x00000014 /* Compression start offset */ +#define MDC_CURS_ST_OFFSET 0x00000018 /* Cursor buffer start offset */ +#define MDC_ICON_ST_OFFSET 0x0000001C /* Icon buffer start offset */ +#define MDC_VID_Y_ST_OFFSET 0x00000020 /* Video Y Buffer start offset */ +#define MDC_VID_U_ST_OFFSET 0x00000024 /* Video U Buffer start offset */ +#define MDC_VID_V_ST_OFFSET 0x00000028 /* Video V Buffer start offset */ +#define MDC_LINE_SIZE 0x00000030 /* Video, CB, and FB line sizes */ +#define MDC_GFX_PITCH 0x00000034 /* FB and DB skip counts */ +#define MDC_VID_YUV_PITCH 0x00000038 /* Y, U and V buffer skip counts */ + +#define MDC_H_ACTIVE_TIMING 0x00000040 /* Horizontal timings */ +#define MDC_H_BLANK_TIMING 0x00000044 +#define MDC_H_SYNC_TIMING 0x00000048 +#define MDC_V_ACTIVE_TIMING 0x00000050 /* Vertical Timings */ +#define MDC_V_BLANK_TIMING 0x00000054 +#define MDC_V_SYNC_TIMING 0x00000058 + +#define MDC_CURSOR_X 0x00000060 /* Cursor X position */ +#define MDC_CURSOR_Y 0x00000064 /* Cursor Y Position */ +#define MDC_ICON_X 0x00000068 /* Icon X Position */ +#define MDC_LINE_CNT_STATUS 0x0000006C /* Icon Y Position */ + +#define MDC_PAL_ADDRESS 0x00000070 /* Palette Address */ +#define MDC_PAL_DATA 0x00000074 /* Palette Data */ +#define MDC_DFIFO_DIAG 0x00000078 /* Display FIFO diagnostic */ +#define MDC_CFIFO_DIAG 0x0000007C /* Compression FIFO diagnostic */ + +#define MDC_VID_DS_DELTA 0x00000080 /* Vertical Downscaling fraction */ + +#define MDC_PHY_MEM_OFFSET 0x00000084 /* VG Base Address Register */ +#define MDC_DV_CTL 0x00000088 /* Dirty-Valid Control Register */ +#define MDC_DV_ACC 0x0000008C /* Dirty-Valid RAM Access */ + +/* UNLOCK VALUE */ + +#define MDC_UNLOCK_VALUE 0x00004758 /* used to unlock DC regs */ + +/* VG MBUS DEVICE SMI MSR FIELDS */ + +#define MDC_VG_BL_MASK 0x00000001 +#define MDC_MISC_MASK 0x00000002 +#define MDC_ISR0_MASK 0x00000004 +#define MDC_VGA_BL_MASK 0x00000008 +#define MDC_CRTCIO_MSK 0x00000010 +#define MDC_VG_BLANK_SMI 0x00000001 +#define MDC_MISC_SMI 0x00000002 +#define MDC_ISR0_SMI 0x00000004 +#define MDC_VGA_BLANK_SMI 0x00000008 +#define MDC_CRTCIO_SMI 0x00000010 + +/* MDC_GENERAL_CFG BIT FIELDS */ + +#define MDC_GCFG_DBUG 0x80000000 +#define MDC_GCFG_DBSL 0x40000000 +#define MDC_GCFG_CFRW 0x20000000 +#define MDC_GCFG_DIAG 0x10000000 +#define MDC_GCFG_GXRFS4 0x08000000 +#define MDC_GCFG_SGFR 0x04000000 +#define MDC_GCFG_SGRE 0x02000000 +#define MDC_GCFG_SIGE 0x01000000 +#define MDC_GCFG_YUVM 0x00100000 +#define MDC_GCFG_VDSE 0x00080000 +#define MDC_GCFG_VGAFT 0x00040000 +#define MDC_GCFG_FDTY 0x00020000 +#define MDC_GCFG_STFM 0x00010000 +#define MDC_GCFG_DFHPEL_MASK 0x0000F000 +#define MDC_GCFG_DFHPSL_MASK 0x00000F00 +#define MDC_GCFG_VGAE 0x00000080 +#define MDC_GCFG_DECE 0x00000040 +#define MDC_GCFG_CMPE 0x00000020 +#define MDC_GCFG_VIDE 0x00000008 +#define MDC_GCFG_ICNE 0x00000004 +#define MDC_GCFG_CURE 0x00000002 +#define MDC_GCFG_DFLE 0x00000001 + +/* MDC_DISPLAY_CFG BIT FIELDS */ + +#define MDC_DCFG_A20M 0x80000000 +#define MDC_DCFG_A18M 0x40000000 +#define MDC_DCFG_VISL 0x08000000 +#define MDC_DCFG_FRLK 0x04000000 +#define MDC_DCFG_PALB 0x02000000 +#define MDC_DCFG_PIX_PAN_MASK 0x00F00000 +#define MDC_DCFG_DCEN 0x00080000 +#define MDC_DCFG_16BPP_MODE_MASK 0x00000C00 +#define MDC_DCFG_16BPP 0x00000000 +#define MDC_DCFG_15BPP 0x00000400 +#define MDC_DCFG_12BPP 0x00000800 +#define MDC_DCFG_DISP_MODE_MASK 0x00000300 +#define MDC_DCFG_DISP_MODE_8BPP 0x00000000 +#define MDC_DCFG_DISP_MODE_16BPP 0x00000100 +#define MDC_DCFG_DISP_MODE_24BPP 0x00000200 +#define MDC_DCFG_SCLE 0x00000080 +#define MDC_DCFG_TRUP 0x00000040 +#define MDC_DCFG_VIEN 0x00000020 +#define MDC_DCFG_VDEN 0x00000010 +#define MDC_DCFG_GDEN 0x00000008 +#define MDC_DCFG_VCKE 0x00000004 +#define MDC_DCFG_PCKE 0x00000002 +#define MDC_DCFG_TGEN 0x00000001 + +/* MDC_LINE_CNT BIT FIELDS */ + +#define MDC_LNCNT_DNA 0x80000000 +#define MDC_LNCNT_VNA 0x40000000 +#define MDC_LNCNT_VSA 0x20000000 +#define MDC_LNCNT_VINT 0x10000000 +#define MDC_LNCNT_FLIP 0x08000000 +#define MDC_LNCNT_V_LINE_CNT 0x07FF0000 +#define MDC_LNCNT_VFLIP 0x00008000 +#define MDC_LNCNT_SIGC 0x00004000 +#define MDC_LNCNT_SS_LINE_CMP 0x000007FF + +/* MDC_FB_ST_OFFSET BIT FIELDS */ + +#define MDC_FB_ST_OFFSET_MASK 0x0FFFFFFF + +/* MDC_CB_ST_OFFSET BIT FIELDS */ + +#define MDC_CB_ST_OFFSET_MASK 0x0FFFFFFF + +/* MDC_CURS_ST_OFFSET BIT FIELDS */ + +#define MDC_CURS_ST_OFFSET_MASK 0x0FFFFFFF + +/* MDC_ICON_ST_OFFSET BIT FIELDS */ + +#define MDC_ICON_ST_OFFSET_MASK 0x0FFFFFFF + +/* MDC_VID_Y_ST_OFFSET BIT FIELDS */ + +#define MDC_VID_Y_ST_OFFSET_MASK 0x0FFFFFFF + +/* MDC_VID_U_ST_OFFSET BIT FIELDS */ + +#define MDC_VID_U_ST_OFFSET_MASK 0x0FFFFFFF + +/* MDC_VID_V_ST_OFFSET BIT FIELDS */ + +#define MDC_VID_V_ST_OFFSET_MASK 0x0FFFFFFF + +/* MDC_LINE_SIZE BIT FIELDS */ + +#define MDC_LINE_SIZE_VLS_MASK 0xFF000000 +#define MDC_LINE_SIZE_CBLS_MASK 0x007F0000 +#define MDC_LINE_SIZE_FBLS_MASK 0x000007FF + +/* MDC_GFX_PITCH BIT FIELDS */ + +#define MDC_GFX_PITCH_CBP_MASK 0xFFFF0000 +#define MDC_GFX_PITCH_FBP_MASK 0x0000FFFF + +/* MDC_VID_YUV_PITCH BIT FIELDS */ + +#define MDC_YUV_PITCH_UVP_MASK 0xFFFF0000 +#define MDC_YUV_PITCH_YBP_MASK 0x0000FFFF + +/* MDC_H_ACTIVE_TIMING BIT FIELDS */ + +#define MDC_HAT_HT_MASK 0x0FF80000 +#define MDC_HAT_HA_MASK 0x00000FF8 + +/* MDC_H_BLANK_TIMING BIT FIELDS */ + +#define MDC_HBT_HBE_MASK 0x0FF80000 +#define MDC_HBT_HBS_MASK 0x00000FF8 + +/* MDC_H_SYNC_TIMING BIT FIELDS */ + +#define MDC_HST_HSE_MASK 0x0FF80000 +#define MDC_HST_HSS_MASK 0x00000FF8 + +/* MDC_V_ACTIVE_TIMING BIT FIELDS */ + +#define MDC_VAT_VT_MASK 0x07FF0000 +#define MDC_VAT_VA_MASK 0x000007FF + +/* MDC_V_BLANK_TIMING BIT FIELDS */ + +#define MDC_VBT_VBE_MASK 0x07FF0000 +#define MDC_VBT_VBS_MASK 0x000007FF + +/* MDC_V_SYNC_TIMING BIT FIELDS */ + +#define MDC_VST_VSE_MASK 0x07FF0000 +#define MDC_VST_VSS_MASK 0x000007FF + +/* MDC_DV_CTL BIT DEFINITIONS */ + +#define MDC_DV_LINE_SIZE_MASK 0x00000C00 +#define MDC_DV_LINE_SIZE_1024 0x00000000 +#define MDC_DV_LINE_SIZE_2048 0x00000400 +#define MDC_DV_LINE_SIZE_4096 0x00000800 +#define MDC_DV_LINE_SIZE_8192 0x00000C00 + +/* VGA DEFINITIONS */ + +#define MDC_SEQUENCER_INDEX 0x03C4 +#define MDC_SEQUENCER_DATA 0x03C5 +#define MDC_SEQUENCER_RESET 0x00 +#define MDC_SEQUENCER_CLK_MODE 0x01 + +#define MDC_RESET_VGA_DISP_ENABLE 0x03 +#define MDC_CLK_MODE_SCREEN_OFF 0x20 + +/*---------------------------------------------------*/ +/* REDCLOUD DISPLAY FILTER */ +/*---------------------------------------------------*/ + +/* RCDF VIDEO REGISTER DEFINITIONS */ + +#define RCDF_VIDEO_CONFIG 0x000 +#define RCDF_DISPLAY_CONFIG 0x008 +#define RCDF_VIDEO_X_POS 0x010 +#define RCDF_VIDEO_Y_POS 0x018 +#define RCDF_VIDEO_SCALE 0x020 +#define RCDF_VIDEO_COLOR_KEY 0x028 +#define RCDF_VIDEO_COLOR_MASK 0x030 +#define RCDF_PALETTE_ADDRESS 0x038 +#define RCDF_PALETTE_DATA 0x040 +#define RCDF_VID_MISC 0x050 +#define RCDF_VID_CLOCK_SELECT 0x058 +#define RCDF_VIDEO_DOWNSCALER_CONTROL 0x078 +#define RCDF_VIDEO_DOWNSCALER_COEFFICIENTS 0x080 +#define RCDF_VID_CRC 0x088 +#define RCDF_VID_CRC32 0x090 +#define RCDF_VID_ALPHA_CONTROL 0x098 +#define RCDF_CURSOR_COLOR_KEY 0x0A0 +#define RCDF_CURSOR_COLOR_MASK 0x0A8 +#define RCDF_CURSOR_COLOR_1 0x0B0 +#define RCDF_CURSOR_COLOR_2 0x0B8 +#define RCDF_ALPHA_XPOS_1 0x0C0 +#define RCDF_ALPHA_YPOS_1 0x0C8 +#define RCDF_ALPHA_COLOR_1 0x0D0 +#define RCDF_ALPHA_CONTROL_1 0x0D8 +#define RCDF_ALPHA_XPOS_2 0x0E0 +#define RCDF_ALPHA_YPOS_2 0x0E8 +#define RCDF_ALPHA_COLOR_2 0x0F0 +#define RCDF_ALPHA_CONTROL_2 0x0F8 +#define RCDF_ALPHA_XPOS_3 0x100 +#define RCDF_ALPHA_YPOS_3 0x108 +#define RCDF_ALPHA_COLOR_3 0x110 +#define RCDF_ALPHA_CONTROL_3 0x118 +#define RCDF_VIDEO_REQUEST 0x120 +#define RCDF_ALPHA_WATCH 0x128 +#define RCDF_VIDEO_TEST_MODE 0x210 +#define RCDF_POWER_MANAGEMENT 0x410 + +/* DISPLAY FILTER POWER MANAGEMENT DEFINITIONS */ + +#define RCDF_PM_PANEL_POWER_ON 0x01000000 + +/* DISPLAY FILTER MSRS */ + +#define RCDF_MBD_MSR_DIAG_DF 0x2010 +#define RCDF_DIAG_32BIT_CRC 0x80000000 + +/* "RCDF_VIDEO_CONFIG" BIT DEFINITIONS */ + +#define RCDF_VCFG_VID_EN 0x00000001 +#define RCDF_VCFG_VID_INP_FORMAT 0x0000000C +#define RCDF_VCFG_X_FILTER_EN 0x00000040 +#define RCDF_VCFG_Y_FILTER_EN 0x00000080 +#define RCDF_VCFG_LINE_SIZE_LOWER_MASK 0x0000FF00 +#define RCDF_VCFG_INIT_READ_MASK 0x01FF0000 +#define RCDF_VCFG_LINE_SIZE_UPPER 0x08000000 +#define RCDF_VCFG_4_2_0_MODE 0x10000000 +#define RCDF_VCFG_UYVY_FORMAT 0x00000000 +#define RCDF_VCFG_Y2YU_FORMAT 0x00000004 +#define RCDF_VCFG_YUYV_FORMAT 0x00000008 +#define RCDF_VCFG_YVYU_FORMAT 0x0000000C + +/* "RCDF_DISPLAY_CONFIG" BIT DEFINITIONS */ + +#define RCDF_DCFG_DIS_EN 0x00000001 +#define RCDF_DCFG_HSYNC_EN 0x00000002 +#define RCDF_DCFG_VSYNC_EN 0x00000004 +#define RCDF_DCFG_DAC_BL_EN 0x00000008 +#define RCDF_DCFG_FP_PWR_EN 0x00000040 +#define RCDF_DCFG_FP_DATA_EN 0x00000080 +#define RCDF_DCFG_CRT_HSYNC_POL 0x00000100 +#define RCDF_DCFG_CRT_VSYNC_POL 0x00000200 +#define RCDF_DCFG_CRT_SYNC_SKW_MASK 0x0001C000 +#define RCDF_DCFG_CRT_SYNC_SKW_INIT 0x00010000 +#define RCDF_DCFG_PWR_SEQ_DLY_MASK 0x000E0000 +#define RCDF_DCFG_PWR_SEQ_DLY_INIT 0x00080000 +#define RCDF_DCFG_VG_CK 0x00100000 +#define RCDF_DCFG_GV_PAL_BYP 0x00200000 +#define RCDF_DAC_VREF 0x04000000 +#define RCDF_FP_ON_STATUS 0x08000000 + +/* "RCDF_VID_MISC" BIT DEFINITIONS */ + +#define RCDF_GAMMA_BYPASS_BOTH 0x00000001 +#define RCDF_DAC_POWER_DOWN 0x00000400 +#define RCDF_ANALOG_POWER_DOWN 0x00000800 + +/* "RCDF_VIDEO_DOWNSCALER_CONTROL" BIT DEFINITIONS */ + +#define RCDF_VIDEO_DOWNSCALE_ENABLE 0x00000001 +#define RCDF_VIDEO_DOWNSCALE_FACTOR_POS 1 +#define RCDF_VIDEO_DOWNSCALE_FACTOR_MASK 0x0000001E +#define RCDF_VIDEO_DOWNSCALE_TYPE_A 0x00000000 +#define RCDF_VIDEO_DOWNSCALE_TYPE_B 0x00000040 +#define RCDF_VIDEO_DOWNSCALE_TYPE_MASK 0x00000040 + +/* "RCDF_VIDEO_DOWNSCALER_COEFFICIENTS" BIT DEFINITIONS */ + +#define RCDF_VIDEO_DOWNSCALER_COEF1_POS 0 +#define RCDF_VIDEO_DOWNSCALER_COEF2_POS 8 +#define RCDF_VIDEO_DOWNSCALER_COEF3_POS 16 +#define RCDF_VIDEO_DOWNSCALER_COEF4_POS 24 +#define RCDF_VIDEO_DOWNSCALER_COEF_MASK 0xF + +/* VIDEO DE-INTERLACING AND ALPHA CONTROL */ + +#define RCDF_NO_CK_OUTSIDE_ALPHA 0x00000100 +#define RCDF_CSC_VIDEO_YUV_TO_RGB 0x00000400 +#define RCDF_VIDEO_INPUT_IS_RGB 0x00002000 +#define RCDF_ALPHA1_PRIORITY_POS 16 +#define RCDF_ALPHA1_PRIORITY_MASK 0x00030000 +#define RCDF_ALPHA2_PRIORITY_POS 18 +#define RCDF_ALPHA2_PRIORITY_MASK 0x000C0000 +#define RCDF_ALPHA3_PRIORITY_POS 20 +#define RCDF_ALPHA3_PRIORITY_MASK 0x00300000 + +/* VIDEO CURSOR COLOR KEY DEFINITIONS */ + +#define RCDF_CURSOR_COLOR_KEY_ENABLE 0x20000000 +#define RCDF_CURSOR_COLOR_KEY_OFFSET_POS 24 +#define RCDF_CURSOR_COLOR_BITS 23 +#define RCDF_COLOR_MASK 0x00FFFFFF /* 24 significant bits */ + +/* ALPHA COLOR BIT DEFINITION (REGISTERS 0x68, 0x78, AND 0x88) */ + +#define RCDF_ALPHA_COLOR_ENABLE 0x01000000 + +/* ALPHA CONTROL BIT DEFINITIONS (REGISTERS 0x6C, 0x7C, AND 0x8C) */ + +#define RCDF_ACTRL_WIN_ENABLE 0x00010000 +#define RCDF_ACTRL_LOAD_ALPHA 0x00020000 + +/* VIDEO REQUEST DEFINITIONS (REGISTER 0x90) */ + +#define RCDF_VIDEO_Y_REQUEST_POS 0 +#define RCDF_VIDEO_X_REQUEST_POS 16 +#define RCDF_VIDEO_REQUEST_MASK 0x000007FF + +/* GEODELINK DEVICE MSR REGISTER SUMMARY */ + +#define MBD_MSR_CAP 0x2000 /* Device Capabilities */ +#define MBD_MSR_CONFIG 0x2001 /* Device Master Configuration Register */ +#define MBD_MSR_SMI 0x2002 /* MBus Device SMI Register */ +#define MBD_MSR_ERROR 0x2003 /* MBus Device Error */ +#define MBD_MSR_PM 0x2004 /* MBus Device Power Management Register */ +#define MBD_MSR_DIAG 0x2005 /* Mbus Device Diagnostic Register */ + +/* DISPLAY FILTER MBD_MSR_DIAG DEFINITIONS */ + +#define RCDF_MBD_DIAG_SEL0 0x00007FFF /* Lower 32-bits of Diag Bus Select */ +#define RCDF_MBD_DIAG_EN0 0x00008000 /* Enable for lower 32-bits of diag bus */ +#define RCDF_MBD_DIAG_SEL1 0x7FFF0000 /* Upper 32-bits of Diag Bus Select */ +#define RCDF_MBD_DIAG_EN1 0x80000000 /* Enable for upper 32-bits of diag bus */ + +/* DISPLAY FILTER MBD_MSR_CONFIG DEFINITIONS */ + +#define RCDF_CONFIG_FMT_MASK 0x00000038 /* Output Format */ +#define RCDF_CONFIG_FMT_CRT 0x00000000 +#define RCDF_CONFIG_FMT_FP 0x00000008 + +/* MCP MSR DEFINITIONS */ + +#define MCP_CLKOFF 0x0010 +#define MCP_CLKACTIVE 0x0011 +#define MCP_CLKDISABLE 0x0012 +#define MCP_CLK4ACK 0x0013 +#define MCP_SYS_RSTPLL 0x0014 +#define MCP_DOTPLL 0x0015 +#define MCP_DBGCLKCTL 0x0016 +#define MCP_RC_REVID 0x0017 +#define MCP_SETM0CTL 0x0040 +#define MCP_SETN0CTL 0x0048 +#define MCP_CMPVAL0 0x0050 +#define MCP_CMPMASK0 0x0051 +#define MCP_REGA 0x0058 +#define MCP_REGB 0x0059 +#define MCP_REGAMASK 0x005A +#define MCP_REGAVAL 0x005B +#define MCP_REGBMASK 0x005C +#define MCP_REGBVAL 0x005D +#define MCP_FIFOCTL 0x005E +#define MCP_DIAGCTL 0x005F +#define MCP_H0CTL 0x0060 +#define MCP_XSTATE 0x0066 +#define MCP_YSTATE 0x0067 +#define MCP_ACTION0 0x0068 + +/* MCP_SYS_RSTPLL DEFINITIONS */ + +#define MCP_DOTPOSTDIV3 0x00000008 +#define MCP_DOTPREMULT2 0x00000004 +#define MCP_DOTPREDIV2 0x00000002 + +/* MCP MBD_MSR_DIAG DEFINITIONS */ + +#define MCP_MBD_DIAG_SEL0 0x00000007 +#define MCP_MBD_DIAG_EN0 0x00008000 +#define MCP_MBD_DIAG_SEL1 0x00070000 +#define MCP_MBD_DIAG_EN1 0x80000000 + +/* MCP_DOTPLL DEFINITIONS */ + +#define MCP_DOTPLL_P 0x00000003 +#define MCP_DOTPLL_N 0x000001FC +#define MCP_DOTPLL_M 0x00001E00 +#define MCP_DOTPLL_LOCK 0x02000000 +#define MCP_DOTPLL_BYPASS 0x00008000 + +/* END OF FILE */ + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_rndr.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_rndr.c new file mode 100644 index 000000000..5b6b8811b --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_rndr.c @@ -0,0 +1,786 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_rndr.c,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: gfx_rndr.c $ + * + * This file contains routines to program the 2D acceleration hardware: + * + * gfx_set_bpp + * gfx_set_solid_pattern + * gfx_set_mono_pattern + * gfx_set_color_pattern + * gfx_load_color_pattern_line + * gfx_set_solid_source + * gfx_set_mono_source + * gfx_set_raster_operation + * gfx_pattern_fill + * gfx_color_pattern_fill + * gfx_screen_to_screen_blt + * gfx_screen_to_screen_xblt + * gfx_color_bitmap_to_screen_blt + * gfx_color_bitmap_to_screen_xblt + * gfx_mono_bitmap_to_screen_blt + * gfx_bresenham_line + * gfx_wait_until_idle + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* STATIC VARIABLES */ + +unsigned short GFXbpp = 16; +unsigned short GFXbb0Base = 0x400; +unsigned short GFXbb1Base = 0x930; +unsigned short GFXbufferWidthPixels = 400; + +unsigned short GFXpatternFlags = 0; +unsigned short GFXsourceFlags = 0; +unsigned long GFXsavedColor = 0; +unsigned short GFXsavedRop = 0; +unsigned short GFXusesDstData = 0; + +/* INCLUDE SUPPORT FOR FIRST GENERATION, IF SPECIFIED. */ + +#if GFX_2DACCEL_GU1 +#include "rndr_gu1.c" +#endif + +/* INCLUDE SUPPORT FOR SECOND GENERATION, IF SPECIFIED. */ + +#if GFX_2DACCEL_GU2 +#include "rndr_gu2.c" +#endif + +void gfx_reset_pitch(unsigned short pitch); + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call either first or second generation routines. */ + +#if GFX_2DACCEL_DYNAMIC + +/*--------------------------------------------------------------------------- + * gfx_reset_pitch (PRIVATE ROUTINE - NOT PART OF API) + *--------------------------------------------------------------------------- + */ +void +gfx_reset_pitch(unsigned short pitch) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_reset_pitch(pitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_bpp + *--------------------------------------------------------------------------- + */ +void +gfx_set_bpp(unsigned short bpp) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_set_bpp(bpp); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_set_bpp(bpp); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_solid_source + *--------------------------------------------------------------------------- + */ +void +gfx_set_solid_source(unsigned long color) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_set_solid_source(color); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_set_solid_source(color); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_mono_source + *--------------------------------------------------------------------------- + */ +void +gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned short transparent) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_set_mono_source(bgcolor, fgcolor, transparent); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_set_mono_source(bgcolor, fgcolor, transparent); +# endif +} + +void +gfx_set_pattern_flags(unsigned short flags) +{ + GFXpatternFlags |= flags; +} + +/*--------------------------------------------------------------------------- + * gfx_set_solid_pattern + *--------------------------------------------------------------------------- + */ +void +gfx_set_solid_pattern(unsigned long color) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_set_solid_pattern(color); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_set_solid_pattern(color); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_mono_pattern + *--------------------------------------------------------------------------- + */ +void +gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparent) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_set_mono_pattern(bgcolor, fgcolor, data0, data1, transparent); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_set_mono_pattern(bgcolor, fgcolor, data0, data1, transparent); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_color_pattern + *--------------------------------------------------------------------------- + */ +void +gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned long data2, unsigned long data3, + unsigned char transparent) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_set_color_pattern(bgcolor, fgcolor, data0, data1, data2, data3, + transparent); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_set_color_pattern(bgcolor, fgcolor, data0, data1, data2, data3, + transparent); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_load_color_pattern_line + *--------------------------------------------------------------------------- + */ +void +gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_load_color_pattern_line(y, pattern_8x8); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_load_color_pattern_line(y, pattern_8x8); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_raster_operation + *--------------------------------------------------------------------------- + */ +void +gfx_set_raster_operation(unsigned char rop) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_set_raster_operation(rop); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_set_raster_operation(rop); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_pattern_fill + *--------------------------------------------------------------------------- + */ +void +gfx_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_pattern_fill(x, y, width, height); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_pattern_fill(x, y, width, height); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_color_pattern_fill + *--------------------------------------------------------------------------- + */ +void +gfx_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long *pattern) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_color_pattern_fill(x, y, width, height, pattern); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_color_pattern_fill(x, y, width, height, pattern); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_screen_to_screen_blt + *--------------------------------------------------------------------------- + */ +void +gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_screen_to_screen_xblt + *--------------------------------------------------------------------------- + */ +void +gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_screen_to_screen_xblt(srcx, srcy, dstx, dsty, width, height, color); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_screen_to_screen_xblt(srcx, srcy, dstx, dsty, width, height, color); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_color_bitmap_to_screen_blt + *--------------------------------------------------------------------------- + */ +void +gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height, + data, pitch); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height, + data, pitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_color_bitmap_to_screen_xblt + *--------------------------------------------------------------------------- + */ +void +gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch, + unsigned long color) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_color_bitmap_to_screen_xblt(srcx, srcy, dstx, dsty, width, height, + data, pitch, color); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_color_bitmap_to_screen_xblt(srcx, srcy, dstx, dsty, width, height, + data, pitch, color); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_mono_bitmap_to_screen_blt + *--------------------------------------------------------------------------- + */ +void +gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, short pitch) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_mono_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height, + data, pitch); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_mono_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height, + data, pitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_text_blt + *--------------------------------------------------------------------------- + */ +void +gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, + unsigned short height, unsigned char *data) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_text_blt(dstx, dsty, width, height, data); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_text_blt(dstx, dsty, width, height, data); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_bresenham_line + *--------------------------------------------------------------------------- + */ +void +gfx_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_bresenham_line(x, y, length, initerr, axialerr, diagerr, flags); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_bresenham_line(x, y, length, initerr, axialerr, diagerr, flags); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_wait_until_idle + *--------------------------------------------------------------------------- + */ +void +gfx_wait_until_idle(void) +{ +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + gu1_wait_until_idle(); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu2_wait_until_idle(); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_test_blt_pending + *--------------------------------------------------------------------------- + */ +int +gfx_test_blt_pending(void) +{ + int retval = 0; + +# if GFX_2DACCEL_GU1 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1) + retval = gu1_test_blt_pending(); +# endif +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + retval = gu2_test_blt_pending(); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * NEW ROUTINES FOR REDCLOUD + *--------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------- + * gfx2_set_source_stride + *--------------------------------------------------------------------------- + */ +void +gfx2_set_source_stride(unsigned short stride) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_set_source_stride(stride); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_set_destination_stride + *--------------------------------------------------------------------------- + */ +void +gfx2_set_destination_stride(unsigned short stride) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_set_destination_stride(stride); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_set_pattern_origin + *--------------------------------------------------------------------------- + */ +void +gfx2_set_pattern_origin(int x, int y) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_set_pattern_origin(x, y); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_set_source_transparency + *--------------------------------------------------------------------------- + */ +void +gfx2_set_source_transparency(unsigned long color, unsigned long mask) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_set_source_transparency(color, mask); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_set_alpha_mode + *--------------------------------------------------------------------------- + */ +void +gfx2_set_alpha_mode(int mode) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_set_alpha_mode(mode); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_set_alpha_value + *--------------------------------------------------------------------------- + */ +void +gfx2_set_alpha_value(unsigned char value) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_set_alpha_value(value); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_pattern_fill + *--------------------------------------------------------------------------- + */ +void +gfx2_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_pattern_fill(dstoffset, width, height); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_color_pattern_fill + *--------------------------------------------------------------------------- + */ +void +gfx2_color_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned long *pattern) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_color_pattern_fill(dstoffset, width, height, pattern); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_screen_to_screen_blt + *--------------------------------------------------------------------------- + */ +void +gfx2_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset, + unsigned short width, unsigned short height, + int flags) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_screen_to_screen_blt(srcoffset, dstoffset, width, height, flags); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_mono_expand_blt + *--------------------------------------------------------------------------- + */ +void +gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx, + unsigned short srcy, unsigned long dstoffset, + unsigned short width, unsigned short height, + int byte_packed) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_mono_expand_blt(srcbase, srcx, srcy, dstoffset, width, height, + byte_packed); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_color_bitmap_to_screen_blt + *--------------------------------------------------------------------------- + */ +void +gfx2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data, + short pitch) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_color_bitmap_to_screen_blt(srcx, srcy, dstoffset, width, height, + data, pitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_text_blt + *--------------------------------------------------------------------------- + */ +void +gfx2_text_blt(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_text_blt(dstoffset, width, height, data); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_mono_bitmap_to_screen_blt + *--------------------------------------------------------------------------- + */ +void +gfx2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data, + short pitch) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_mono_bitmap_to_screen_blt(srcx, srcy, dstoffset, width, height, + data, pitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_bresenham_line + *--------------------------------------------------------------------------- + */ +void +gfx2_bresenham_line(unsigned long dstoffset, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_bresenham_line(dstoffset, length, initerr, axialerr, diagerr, + flags); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx2_sync_to_vblank + *--------------------------------------------------------------------------- + */ +void +gfx2_sync_to_vblank(void) +{ +# if GFX_2DACCEL_GU2 + if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2) + gu22_sync_to_vblank(); +# endif +} + +#endif /* GFX_2DACCEL_DYNAMIC */ + +/* END OF FILE */ + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_rtns.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_rtns.h new file mode 100644 index 000000000..aefd6c04a --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_rtns.h @@ -0,0 +1,738 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_rtns.h,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: gfx_rtns.h $ + * + * This header file defines the Durango routines and variables used + * to access the memory mapped regions. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef _gfx_rtns_h +#define _gfx_rtns_h + +/* INCLUDE DURANGO DEFINITIONS */ +/* These definitions are placed in another file to allow their inclusion */ +/* in a user application. Such applications generally work through driver */ +/* shell routines that simply pass their parameters to Durango routines. */ +/* An external file provides an easy way to provide the definitions for these */ +/* parameters without the applications gaining any Durango visisbility. */ + +#include "gfx_type.h" + +/* COMPILER OPTION FOR C++ PROGRAMS */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* DURANGO MEMORY POINTERS */ + + extern unsigned char *gfx_virt_regptr; + extern unsigned char *gfx_virt_fbptr; + extern unsigned char *gfx_virt_vidptr; + extern unsigned char *gfx_virt_vipptr; + extern unsigned char *gfx_virt_spptr; + extern unsigned char *gfx_virt_gpptr; + + extern unsigned char *gfx_phys_regptr; + extern unsigned char *gfx_phys_fbptr; + extern unsigned char *gfx_phys_vidptr; + extern unsigned char *gfx_phys_vipptr; + extern unsigned char *gfx_phys_spptr; + extern unsigned char *gfx_phys_gpptr; + +/* DURANGO VARIBLES FOR RUNTIME SELECTION AND POSSIBLE VALUES */ + + extern int gfx_display_type; +#define GFX_DISPLAY_TYPE_GU1 0x0001 +#define GFX_DISPLAY_TYPE_GU2 0x0002 + + extern int gfx_init_type; +#define GFX_INIT_TYPE_GU1 0x0001 +#define GFX_INIT_TYPE_GU2 0x0002 + + extern int gfx_msr_type; +#define GFX_MSR_TYPE_REDCLOUD 0x0001 + + extern int gfx_2daccel_type; +#define GFX_2DACCEL_TYPE_GU1 0x0001 +#define GFX_2DACCEL_TYPE_GU2 0x0002 + + extern int gfx_video_type; +#define GFX_VIDEO_TYPE_CS5530 0x0001 +#define GFX_VIDEO_TYPE_SC1200 0x0002 +#define GFX_VIDEO_TYPE_REDCLOUD 0x0004 + + extern int gfx_vip_type; +#define GFX_VIP_TYPE_SC1200 0x0001 + + extern int gfx_decoder_type; +#define GFX_DECODER_TYPE_SAA7114 0x0001 + + extern int gfx_tv_type; +#define GFX_TV_TYPE_SC1200 0x0001 +#define GFX_TV_TYPE_FS451 0x0002 + + extern int gfx_i2c_type; +#define GFX_I2C_TYPE_ACCESS 0x0001 +#define GFX_I2C_TYPE_GPIO 0x0002 + +/* GLOBAL CPU INFORMATION */ + + extern unsigned long gfx_cpu_version; + extern unsigned long gfx_cpu_frequency; + extern unsigned long gfx_vid_version; + extern ChipType gfx_chip_revision; + +/* ROUTINES IN GFX_INIT.C */ + + unsigned long gfx_pci_config_read(unsigned long address); + void gfx_pci_config_write(unsigned long address, unsigned long data); + unsigned long gfx_get_core_freq(void); + unsigned long gfx_detect_cpu(void); + unsigned long gfx_detect_video(void); + unsigned long gfx_get_cpu_register_base(void); + unsigned long gfx_get_graphics_register_base(void); + unsigned long gfx_get_frame_buffer_base(void); + unsigned long gfx_get_frame_buffer_size(void); + unsigned long gfx_get_vid_register_base(void); + unsigned long gfx_get_vip_register_base(void); + +/* ROUTINES IN GFX_MSR.C */ + + int gfx_msr_init(void); + DEV_STATUS gfx_id_msr_device(MSR * pDev, unsigned long address); + DEV_STATUS gfx_get_msr_dev_address(unsigned int device, + unsigned long *address); + DEV_STATUS gfx_get_glink_id_at_address(unsigned int *device, + unsigned long address); + DEV_STATUS gfx_msr_read(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue); + DEV_STATUS gfx_msr_write(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue); + +/* ROUTINES IN GFX_DISP.C */ + + int gfx_set_display_bpp(unsigned short bpp); + int gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz); + int gfx_set_display_mode(int xres, int yres, int bpp, int hz); + int gfx_set_display_timings(unsigned short bpp, unsigned short flags, + unsigned short hactive, + unsigned short hblank_start, + unsigned short hsync_start, + unsigned short hsync_end, + unsigned short hblank_end, + unsigned short htotal, unsigned short vactive, + unsigned short vblank_start, + unsigned short vsync_start, + unsigned short vsync_end, + unsigned short vblank_end, + unsigned short vtotal, + unsigned long frequency); + int gfx_set_vtotal(unsigned short vtotal); + void gfx_set_display_pitch(unsigned short pitch); + void gfx_set_display_offset(unsigned long offset); + int gfx_set_display_palette_entry(unsigned long index, + unsigned long palette); + int gfx_set_display_palette(unsigned long *palette); + void gfx_video_shutdown(void); + void gfx_set_clock_frequency(unsigned long frequency); + int gfx_set_crt_enable(int enable); + void gfx_set_cursor_enable(int enable); + void gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor); + void gfx_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, + unsigned short yhotspot); + void gfx_set_cursor_shape32(unsigned long memoffset, + unsigned long *andmask, + unsigned long *xormask); + void gfx_set_cursor_shape64(unsigned long memoffset, + unsigned long *andmask, + unsigned long *xormask); + void gfx_set_icon_enable(int enable); + void gfx_set_icon_colors(unsigned long color0, unsigned long color1, + unsigned long color2); + void gfx_set_icon_position(unsigned long memoffset, unsigned short xpos); + void gfx_set_icon_shape64(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask, unsigned int lines); + + int gfx_set_compression_enable(int enable); + int gfx_set_compression_offset(unsigned long offset); + int gfx_set_compression_pitch(unsigned short pitch); + int gfx_set_compression_size(unsigned short size); + void gfx_set_display_priority_high(int enable); + int gfx_test_timing_active(void); + int gfx_test_vertical_active(void); + int gfx_wait_vertical_blank(void); + void gfx_delay_milliseconds(unsigned long milliseconds); + void gfx_delay_microseconds(unsigned long microseconds); + void gfx_enable_panning(int x, int y); + int gfx_set_fixed_timings(int panelResX, int panelResY, + unsigned short width, unsigned short height, + unsigned short bpp); + int gfx_set_panel_present(int panelResX, int panelResY, + unsigned short width, unsigned short height, + unsigned short bpp); + void gfx_reset_timing_lock(void); + +/* "READ" ROUTINES IN GFX_DISP.C */ + + int gfx_get_display_details(unsigned int mode, int *xres, int *yres, + int *hz); + unsigned short gfx_get_display_pitch(void); + int gfx_get_vsa2_softvga_enable(void); + int gfx_get_sync_polarities(void); + unsigned long gfx_get_clock_frequency(void); + unsigned long gfx_get_max_supported_pixel_clock(void); + int gfx_mode_frequency_supported(int xres, int yres, int bpp, + unsigned long frequency); + int gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, + int *hz, unsigned long frequency); + int gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, + unsigned long frequency); + int gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, + int *frequency); + int gfx_get_display_mode_count(void); + int gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz); + unsigned long gfx_get_frame_buffer_line_size(void); + unsigned short gfx_get_hactive(void); + unsigned short gfx_get_hblank_start(void); + unsigned short gfx_get_hsync_start(void); + unsigned short gfx_get_hsync_end(void); + unsigned short gfx_get_hblank_end(void); + unsigned short gfx_get_htotal(void); + unsigned short gfx_get_vactive(void); + unsigned short gfx_get_vline(void); + unsigned short gfx_get_vblank_start(void); + unsigned short gfx_get_vsync_start(void); + unsigned short gfx_get_vsync_end(void); + unsigned short gfx_get_vblank_end(void); + unsigned short gfx_get_vtotal(void); + unsigned short gfx_get_display_bpp(void); + unsigned long gfx_get_display_offset(void); + int gfx_get_display_palette_entry(unsigned long index, + unsigned long *palette); + void gfx_get_display_palette(unsigned long *palette); + unsigned long gfx_get_cursor_enable(void); + unsigned long gfx_get_cursor_offset(void); + unsigned long gfx_get_cursor_position(void); + unsigned long gfx_get_cursor_clip(void); + unsigned long gfx_get_cursor_color(int color); + unsigned long gfx_get_icon_enable(void); + unsigned long gfx_get_icon_offset(void); + unsigned long gfx_get_icon_position(void); + unsigned long gfx_get_icon_color(int color); + int gfx_get_compression_enable(void); + unsigned long gfx_get_compression_offset(void); + unsigned short gfx_get_compression_pitch(void); + unsigned short gfx_get_compression_size(void); + int gfx_get_display_priority_high(void); + int gfx_get_valid_bit(int line); + +/* ROUTINES IN GFX_RNDR.C */ + + void gfx_set_bpp(unsigned short bpp); + void gfx_set_solid_pattern(unsigned long color); + void gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparency); + void gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned long data2, unsigned long data3, + unsigned char transparency); + void gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8); + void gfx_set_solid_source(unsigned long color); + void gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned short transparent); + void gfx_set_pattern_flags(unsigned short flags); + void gfx_set_raster_operation(unsigned char rop); + void gfx_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height); + void gfx_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long *pattern); + void gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height); + void gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color); + void gfx_color_bitmap_to_screen_blt(unsigned short srcx, + unsigned short srcy, + unsigned short dstx, + unsigned short dsty, + unsigned short width, + unsigned short height, + unsigned char *data, long pitch); + void gfx_color_bitmap_to_screen_xblt(unsigned short srcx, + unsigned short srcy, + unsigned short dstx, + unsigned short dsty, + unsigned short width, + unsigned short height, + unsigned char *data, long pitch, + unsigned long color); + void gfx_mono_bitmap_to_screen_blt(unsigned short srcx, + unsigned short srcy, + unsigned short dstx, + unsigned short dsty, + unsigned short width, + unsigned short height, + unsigned char *data, short pitch); + void gfx_text_blt(unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data); + void gfx_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags); + void gfx_wait_until_idle(void); + int gfx_test_blt_pending(void); + +/* SECOND GENERATION RENDERING ROUTINES */ + + void gfx2_set_source_stride(unsigned short stride); + void gfx2_set_destination_stride(unsigned short stride); + void gfx2_set_pattern_origin(int x, int y); + void gfx2_set_source_transparency(unsigned long color, unsigned long mask); + void gfx2_set_alpha_mode(int mode); + void gfx2_set_alpha_value(unsigned char value); + void gfx2_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height); + void gfx2_color_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height, + unsigned long *pattern); + void gfx2_screen_to_screen_blt(unsigned long srcoffset, + unsigned long dstoffset, + unsigned short width, unsigned short height, + int flags); + void gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx, + unsigned short srcy, unsigned long dstoffset, + unsigned short width, unsigned short height, + int byte_packed); + void gfx2_color_bitmap_to_screen_blt(unsigned short srcx, + unsigned short srcy, + unsigned long dstoffset, + unsigned short width, + unsigned short height, + unsigned char *data, short pitch); + void gfx2_mono_bitmap_to_screen_blt(unsigned short srcx, + unsigned short srcy, + unsigned long dstoffset, + unsigned short width, + unsigned short height, + unsigned char *data, short pitch); + void gfx2_text_blt(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data); + void gfx2_bresenham_line(unsigned long dstoffset, unsigned short length, + unsigned short initerr, unsigned short axialerr, + unsigned short diagerr, unsigned short flags); + void gfx2_sync_to_vblank(void); + +/* ROUTINES IN GFX_VID.C */ + + int gfx_set_video_enable(int enable); + int gfx_set_video_format(unsigned long format); + int gfx_set_video_size(unsigned short width, unsigned short height); + int gfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch); + int gfx_set_video_offset(unsigned long offset); + int gfx_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset, + unsigned long voffset); + int gfx_set_video_window(short x, short y, unsigned short w, + unsigned short h); + int gfx_set_video_left_crop(unsigned short x); + int gfx_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); + int gfx_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); + int gfx_set_video_vertical_downscale(unsigned short srch, + unsigned short dsth); + void gfx_set_video_vertical_downscale_enable(int enable); + int gfx_set_video_downscale_config(unsigned short type, unsigned short m); + int gfx_set_video_color_key(unsigned long key, unsigned long mask, + int bluescreen); + int gfx_set_video_filter(int xfilter, int yfilter); + int gfx_set_video_palette(unsigned long *palette); + int gfx_set_video_palette_entry(unsigned long index, unsigned long color); + int gfx_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4); + int gfx_set_video_downscale_enable(int enable); + int gfx_set_video_source(VideoSourceType source); + int gfx_set_vbi_source(VbiSourceType source); + int gfx_set_vbi_lines(unsigned long even, unsigned long odd); + int gfx_set_vbi_total(unsigned long even, unsigned long odd); + int gfx_set_video_interlaced(int enable); + int gfx_set_color_space_YUV(int enable); + int gfx_set_vertical_scaler_offset(char offset); + int gfx_set_top_line_in_odd(int enable); + int gfx_set_genlock_delay(unsigned long delay); + int gfx_set_genlock_enable(int flags); + int gfx_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, + unsigned long color1, unsigned long color2); + int gfx_set_video_cursor_enable(int enable); + int gfx_set_video_request(short x, short y); + + int gfx_select_alpha_region(int region); + int gfx_set_alpha_enable(int enable); + int gfx_set_alpha_window(short x, short y, + unsigned short width, unsigned short height); + int gfx_set_alpha_value(unsigned char alpha, char delta); + int gfx_set_alpha_priority(int priority); + int gfx_set_alpha_color(unsigned long color); + int gfx_set_alpha_color_enable(int enable); + int gfx_set_no_ck_outside_alpha(int enable); + int gfx_disable_softvga(void); + int gfx_enable_softvga(void); + int gfx_set_macrovision_enable(int enable); + +/* READ ROUTINES IN GFX_VID.C */ + + int gfx_get_video_enable(void); + int gfx_get_video_format(void); + unsigned long gfx_get_video_src_size(void); + unsigned long gfx_get_video_line_size(void); + unsigned long gfx_get_video_xclip(void); + unsigned long gfx_get_video_offset(void); + void gfx_get_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset); + void gfx_get_video_yuv_pitch(unsigned long *ypitch, + unsigned long *uvpitch); + unsigned long gfx_get_video_upscale(void); + unsigned long gfx_get_video_scale(void); + unsigned long gfx_get_video_downscale_delta(void); + int gfx_get_video_vertical_downscale_enable(void); + int gfx_get_video_downscale_config(unsigned short *type, + unsigned short *m); + void gfx_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4); + void gfx_get_video_downscale_enable(int *enable); + unsigned long gfx_get_video_dst_size(void); + unsigned long gfx_get_video_position(void); + unsigned long gfx_get_video_color_key(void); + unsigned long gfx_get_video_color_key_mask(void); + int gfx_get_video_palette_entry(unsigned long index, + unsigned long *palette); + int gfx_get_video_color_key_src(void); + int gfx_get_video_filter(void); + int gfx_get_video_request(short *x, short *y); + int gfx_get_video_source(VideoSourceType * source); + int gfx_get_vbi_source(VbiSourceType * source); + unsigned long gfx_get_vbi_lines(int odd); + unsigned long gfx_get_vbi_total(int odd); + int gfx_get_video_interlaced(void); + int gfx_get_color_space_YUV(void); + int gfx_get_vertical_scaler_offset(char *offset); + unsigned long gfx_get_genlock_delay(void); + int gfx_get_genlock_enable(void); + int gfx_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, + unsigned long *color1, unsigned short *color2); + unsigned long gfx_read_crc(void); + unsigned long gfx_read_crc32(void); + unsigned long gfx_read_window_crc(int source, unsigned short x, + unsigned short y, unsigned short width, + unsigned short height, int crc32); + int gfx_get_macrovision_enable(void); + + void gfx_get_alpha_enable(int *enable); + void gfx_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height); + void gfx_get_alpha_value(unsigned char *alpha, char *delta); + void gfx_get_alpha_priority(int *priority); + void gfx_get_alpha_color(unsigned long *color); + +/* ROUTINES IN GFX_VIP.C */ + + int gfx_set_vip_enable(int enable); + int gfx_set_vip_capture_run_mode(int mode); + int gfx_set_vip_base(unsigned long even, unsigned long odd); + int gfx_set_vip_pitch(unsigned long pitch); + int gfx_set_vip_mode(int mode); + int gfx_set_vbi_enable(int enable); + int gfx_set_vbi_mode(int mode); + int gfx_set_vbi_base(unsigned long even, unsigned long odd); + int gfx_set_vbi_pitch(unsigned long pitch); + int gfx_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines); + int gfx_set_vbi_interrupt(int enable); + int gfx_set_vip_bus_request_threshold_high(int enable); + int gfx_set_vip_last_line(int last_line); + int gfx_test_vip_odd_field(void); + int gfx_test_vip_bases_updated(void); + int gfx_test_vip_fifo_overflow(void); + int gfx_get_vip_line(void); + +/* READ ROUTINES IN GFX_VIP.C */ + + int gfx_get_vip_enable(void); + unsigned long gfx_get_vip_base(int odd); + unsigned long gfx_get_vip_pitch(void); + int gfx_get_vip_mode(void); + int gfx_get_vbi_enable(void); + int gfx_get_vbi_mode(void); + unsigned long gfx_get_vbi_base(int odd); + unsigned long gfx_get_vbi_pitch(void); + unsigned long gfx_get_vbi_direct(int odd); + int gfx_get_vbi_interrupt(void); + int gfx_get_vip_bus_request_threshold_high(void); + +/* ROUTINES IN GFX_DCDR.C */ + + int gfx_set_decoder_defaults(void); + int gfx_set_decoder_analog_input(unsigned char input); + int gfx_set_decoder_brightness(unsigned char brightness); + int gfx_set_decoder_contrast(unsigned char contrast); + int gfx_set_decoder_hue(char hue); + int gfx_set_decoder_saturation(unsigned char saturation); + int gfx_set_decoder_input_offset(unsigned short x, unsigned short y); + int gfx_set_decoder_input_size(unsigned short width, + unsigned short height); + int gfx_set_decoder_output_size(unsigned short width, + unsigned short height); + int gfx_set_decoder_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); + int gfx_set_decoder_vbi_format(int start, int end, int format); + int gfx_set_decoder_vbi_enable(int enable); + int gfx_set_decoder_vbi_upscale(void); + int gfx_set_decoder_TV_standard(TVStandardType TVStandard); + int gfx_set_decoder_luminance_filter(unsigned char lufi); + int gfx_decoder_software_reset(void); + int gfx_decoder_detect_macrovision(void); + int gfx_decoder_detect_video(void); + +/* READ ROUTINES IN GFX_DCDR.C */ + + unsigned char gfx_get_decoder_brightness(void); + unsigned char gfx_get_decoder_contrast(void); + char gfx_get_decoder_hue(void); + unsigned char gfx_get_decoder_saturation(void); + unsigned long gfx_get_decoder_input_offset(void); + unsigned long gfx_get_decoder_input_size(void); + unsigned long gfx_get_decoder_output_size(void); + int gfx_get_decoder_vbi_format(int line); + +/* ROUTINES IN GFX_I2C.C */ + + int gfx_i2c_reset(unsigned char busnum, short adr, char freq); + int gfx_i2c_write(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, + unsigned char *data); + int gfx_i2c_read(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, + unsigned char *data); + int gfx_i2c_select_gpio(int clock, int data); + int gfx_i2c_init(void); + void gfx_i2c_cleanup(void); + +/* ROUTINES IN GFX_TV.C */ + + int gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution); + int gfx_set_tv_output(int output); + int gfx_set_tv_enable(int enable); + int gfx_set_tv_flicker_filter(int ff); + int gfx_set_tv_sub_carrier_reset(int screset); + int gfx_set_tv_vphase(int vphase); + int gfx_set_tv_YC_delay(int delay); + int gfx_set_tvenc_reset_interval(int interval); + int gfx_set_tv_cc_enable(int enable); + int gfx_set_tv_cc_data(unsigned char data1, unsigned char data2); + int gfx_set_tv_display(int width, int height); + int gfx_test_tvout_odd_field(void); + int gfx_test_tvenc_odd_field(void); + int gfx_set_tv_field_status_invert(int enable); + int gfx_get_tv_vphase(void); + int gfx_get_tv_enable(unsigned int *p_on); + int gfx_get_tv_output(void); + int gfx_get_tv_mode_count(TVStandardType format); + int gfx_get_tv_display_mode(int *width, int *height, int *bpp, int *hz); + int gfx_get_tv_display_mode_frequency(unsigned short width, + unsigned short height, + TVStandardType format, + int *frequency); + int gfx_is_tv_display_mode_supported(unsigned short width, + unsigned short height, + TVStandardType format); + + int gfx_get_tv_standard(unsigned long *p_standard); + int gfx_get_available_tv_standards(unsigned long *p_standards); + int gfx_set_tv_standard(unsigned long standard); + int gfx_get_tv_vga_mode(unsigned long *p_vga_mode); + int gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes); + int gfx_set_tv_vga_mode(unsigned long vga_mode); + int gfx_get_tvout_mode(unsigned long *p_tvout_mode); + int gfx_set_tvout_mode(unsigned long tvout_mode); + int gfx_get_sharpness(int *p_sharpness); + int gfx_set_sharpness(int sharpness); + int gfx_get_flicker_filter(int *p_flicker); + int gfx_set_flicker_filter(int flicker); + int gfx_get_overscan(int *p_x, int *p_y); + int gfx_set_overscan(int x, int y); + int gfx_get_position(int *p_x, int *p_y); + int gfx_set_position(int x, int y); + int gfx_get_color(int *p_color); + int gfx_set_color(int color); + int gfx_get_brightness(int *p_brightness); + int gfx_set_brightness(int brightness); + int gfx_get_contrast(int *p_contrast); + int gfx_set_contrast(int constrast); + int gfx_get_yc_filter(unsigned int *p_yc_filter); + int gfx_set_yc_filter(unsigned int yc_filter); + int gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits); + int gfx_set_aps_trigger_bits(unsigned int trigger_bits); + +/* ROUTINES IN GFX_VGA.C */ + + int gfx_get_softvga_active(void); + int gfx_vga_test_pci(void); + unsigned char gfx_vga_get_pci_command(void); + int gfx_vga_set_pci_command(unsigned char command); + int gfx_vga_seq_reset(int reset); + int gfx_vga_set_graphics_bits(void); + int gfx_vga_mode(gfx_vga_struct * vga, int xres, int yres, int bpp, + int hz); + int gfx_vga_pitch(gfx_vga_struct * vga, unsigned short pitch); + int gfx_vga_save(gfx_vga_struct * vga, int flags); + int gfx_vga_restore(gfx_vga_struct * vga, int flags); + int gfx_vga_mode_switch(int active); + void gfx_vga_clear_extended(void); + +/* CLOSE BRACKET FOR C++ COMPLILATION */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_gfx_rtns_h */ + +/* END OF FILE */ + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_tv.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_tv.c new file mode 100644 index 000000000..6cb825d91 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_tv.c @@ -0,0 +1,940 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_tv.c,v 1.1 2002/12/10 15:12:25 alanh Exp $ */ +/* + * $Workfile: gfx_tv.c $ + * + * This file contains routines to program TVOUT and TV encoder. + * + * Routines: + * + * gfx_set_tv_format + * gfx_set_tv_output + * gfx_set_tv_enable + * gfx_set_tv_flicker_filter + * gfx_set_tv_sub_carrier_reset + * gfx_set_tv_vphase + * gfx_set_tv_YC_delay + * gfx_set_tvenc_reset_interval + * gfx_set_tv_cc_enable + * gfx_set_tv_cc_data + * gfx_test_tvout_odd_field + * gfx_test_tvenc_odd_field + * gfx_set_tv_field_status_invert + * gfx_get_tv_vphase + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* TV TIMINGS */ + +DISPLAYMODE TVTimings[] = { + +/* NTSC resolution */ + + {0x3 | /* negative syncs */ + GFX_MODE_TV_NTSC, /* NTSC format */ + 640, 640, 656, 744, 792, 792, /* horizontal timings */ + 480, 480, 490, 492, 517, 525, /* vertical timings */ + 0x0018EC4D, /* freq = 24.923052 MHz */ + } + , + +/* PAL resolution */ + + {0x3 | /* negative syncs */ + GFX_MODE_TV_PAL, /* PAL format */ + 768, 768, 800, 848, 864, 864, /* horizontal timings */ + 576, 576, 586, 588, 625, 625, /* vertical timings */ + 0x001B0000, /* freq = 27.00 MHz */ + } + , + +/* NTSC resolution non-square pixels */ + + {0x3 | /* negative syncs */ + GFX_MODE_TV_NTSC, /* NTSC format */ + 720, 720, 736, 752, 792, 792, /* horizontal timings */ + 480, 480, 490, 492, 517, 525, /* vertical timings */ + 0x0018EC4D, /* freq = 24.923052 MHz */ + } + , + +/* PAL resolution non-square pixels */ + + {0x3 | /* negative syncs */ + GFX_MODE_TV_PAL, /* PAL format */ + 720, 720, 752, 816, 864, 864, /* horizontal timings */ + 576, 576, 586, 588, 625, 625, /* vertical timings */ + 0x001B0000, /* freq = 27.00 MHz */ + } +}; + +#define NUM_TV_MODES sizeof(TVTimings)/sizeof(DISPLAYMODE) + +/* INCLUDE SUPPORT FOR SC1200 TV ENCODER, IF SPECIFIED */ + +#if GFX_TV_SC1200 +#include "tv_1200.c" +#endif + +/* INCLUDE SUPPORT FOR FS450 TV ENCODER, IF SPECIFIED */ + +#if GFX_TV_FS451 +#include "tv_fs450.c" +#endif + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call either SC1200 or FS450 TV encoder routines. */ + +#if GFX_TV_DYNAMIC + +/*----------------------------------------------------------------------------- + * gfx_set_tv_format + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_format(format, resolution); +#endif +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_tv_format(format, resolution); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_output + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_output(int output) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_output(output); +#endif +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_tv_output(output); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_enable + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_enable(int enable) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_enable(enable); +#endif +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_tv_enable(enable); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_flicker_filter + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_flicker_filter(int ff) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_flicker_filter(ff); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_sub_carrier_reset + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_sub_carrier_reset(int screset) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_sub_carrier_reset(screset); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_vphase + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_vphase(int vphase) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_vphase(vphase); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_YC_delay + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_YC_delay(int delay) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_YC_delay(delay); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tvenc_reset_interval + *----------------------------------------------------------------------------- + */ +int +gfx_set_tvenc_reset_interval(int interval) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tvenc_reset_interval(interval); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_enable + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_cc_enable(int enable) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_cc_enable(enable); +#endif + return (retval); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_data + * + * This routine writes the two specified characters to the CC data register + * of the TV encoder. + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_cc_data(unsigned char data1, unsigned char data2) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_cc_data(data1, data2); +#endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_set_tv_display + * + * Set the timings in the display controller to support a TV resolution. + *--------------------------------------------------------------------------- + */ +int +gfx_set_tv_display(int width, int height) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + status = sc1200_set_tv_display(width, height); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_test_tvout_odd_field + *--------------------------------------------------------------------------- + */ +int +gfx_test_tvout_odd_field(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + status = sc1200_test_tvout_odd_field(); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_test_tvenc_odd_field + *--------------------------------------------------------------------------- + */ +int +gfx_test_tvenc_odd_field(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + status = sc1200_test_tvenc_odd_field(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_field_status_invert + *----------------------------------------------------------------------------- + */ +int +gfx_set_tv_field_status_invert(int enable) +{ + int retval = GFX_STATUS_UNSUPPORTED; + +#if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_set_tv_field_status_invert(enable); +#endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_vphase + *--------------------------------------------------------------------------- + */ +int +gfx_get_tv_vphase(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + status = sc1200_get_tv_vphase(); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_enable + *--------------------------------------------------------------------------- + */ +int +gfx_get_tv_enable(unsigned int *p_on) +{ + int retval = -1; + +# if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_tv_enable(p_on); +# endif +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_get_tv_enable(p_on); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_output + *--------------------------------------------------------------------------- + */ +int +gfx_get_tv_output() +{ + int retval = -1; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_get_tv_output(); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_mode_count + *--------------------------------------------------------------------------- + */ +int +gfx_get_tv_mode_count(TVStandardType format) +{ + int retval = -1; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_get_tv_mode_count(format); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_display_mode + *--------------------------------------------------------------------------- + */ +int +gfx_get_tv_display_mode(int *width, int *height, int *bpp, int *hz) +{ + int retval = -1; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_get_tv_display_mode(width, height, bpp, hz); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_display_mode_frequency + *--------------------------------------------------------------------------- + */ +int +gfx_get_tv_display_mode_frequency(unsigned short width, unsigned short height, + TVStandardType format, int *frequency) +{ + int retval = -1; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = + sc1200_get_tv_display_mode_frequency(width, height, format, + frequency); +# endif + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_is_tv_display_mode_supported + *--------------------------------------------------------------------------- + */ +int +gfx_is_tv_display_mode_supported(unsigned short width, unsigned short height, + TVStandardType format) +{ + int retval = -1; + +# if GFX_TV_SC1200 + if (gfx_tv_type & GFX_TV_TYPE_SC1200) + retval = sc1200_is_tv_display_mode_supported(width, height, format); +# endif + return (retval); +} + +/*------------------------------------------ + * The following functions were added to support + * the FS450 and will eventually be removed. There + * is no equivalent support in the SC1200. + *----------------------------------------------*/ + +/* +// ========================================================================== +// +// TV standard +*/ + +int +gfx_get_tv_standard(unsigned long *p_standard) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_tv_standard(p_standard); +#endif + return (retval); +} + +int +gfx_get_available_tv_standards(unsigned long *p_standards) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_available_tv_standards(p_standards); +#endif + return (retval); +} + +int +gfx_set_tv_standard(unsigned long standard) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_tv_standard(standard); +#endif + return (retval); +} + +/* +// ========================================================================== +// +// vga mode as known by the driver +*/ + +int +gfx_get_tv_vga_mode(unsigned long *p_vga_mode) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_tv_vga_mode(p_vga_mode); +#endif + return (retval); +} + +int +gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_available_tv_vga_modes(p_vga_modes); +#endif + return (retval); +} + +int +gfx_set_tv_vga_mode(unsigned long vga_mode) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_tv_vga_mode(vga_mode); +#endif + return (retval); +} + +/* +// ========================================================================== +// +// tvout mode +*/ + +int +gfx_get_tvout_mode(unsigned long *p_tvout_mode) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_tvout_mode(p_tvout_mode); +#endif + return (retval); +} + +int +gfx_set_tvout_mode(unsigned long tvout_mode) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_tvout_mode(tvout_mode); +#endif + return (retval); +} + +/* +// ========================================================================== +// +// Sharpness +*/ +int +gfx_get_sharpness(int *p_sharpness) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_sharpness(p_sharpness); +#endif + return (retval); +} + +int +gfx_set_sharpness(int sharpness) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_sharpness(sharpness); +#endif + return (retval); +} + +/* +// ========================================================================== +// +// flicker filter control. +*/ + +int +gfx_get_flicker_filter(int *p_flicker) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_flicker_filter(p_flicker); +#endif + return (retval); +} + +int +gfx_set_flicker_filter(int flicker) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_flicker_filter(flicker); +#endif + return (retval); +} + +/* +// ========================================================================== +// +// Overscan and Position +*/ + +int +gfx_get_overscan(int *p_x, int *p_y) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_overscan(p_x, p_y); +#endif + return (retval); + +} + +int +gfx_set_overscan(int x, int y) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_overscan(x, y); +#endif + return (retval); +} + +int +gfx_get_position(int *p_x, int *p_y) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_position(p_x, p_y); +#endif + return (retval); +} + +int +gfx_set_position(int x, int y) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_position(x, y); +#endif + return (retval); +} + +/* +// ========================================================================== +// +// Color, Brightness, and Contrast +*/ + +int +gfx_get_color(int *p_color) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_color(p_color); +#endif + return (retval); +} + +int +gfx_set_color(int color) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_color(color); +#endif + return (retval); +} + +int +gfx_get_brightness(int *p_brightness) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_brightness(p_brightness); +#endif + return (retval); +} + +int +gfx_set_brightness(int brightness) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_brightness(brightness); +#endif + return (retval); +} + +int +gfx_get_contrast(int *p_contrast) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_contrast(p_contrast); +#endif + return (retval); +} + +int +gfx_set_contrast(int contrast) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_contrast(contrast); +#endif + return (retval); +} + +/* +// ========================================================================== +// +// YC filters +*/ + +int +gfx_get_yc_filter(unsigned int *p_yc_filter) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_yc_filter(p_yc_filter); +#endif + return (retval); +} + +int +gfx_set_yc_filter(unsigned int yc_filter) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_yc_filter(yc_filter); +#endif + return (retval); +} + +int +gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_get_aps_trigger_bits(p_trigger_bits); +#endif + return (retval); +} + +int +gfx_set_aps_trigger_bits(unsigned int trigger_bits) +{ + int retval = -1; + +#if GFX_TV_FS451 + if (gfx_tv_type & GFX_TV_TYPE_FS451) + retval = fs450_set_aps_trigger_bits(trigger_bits); +#endif + return (retval); +} + +#endif /* GFX_TV_DYNAMIC */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_tv.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_tv.h new file mode 100644 index 000000000..430c8a5f9 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_tv.h @@ -0,0 +1,60 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_tv.h,v 1.1 2002/12/10 15:12:26 alanh Exp $ */ + +typedef struct tagTVDISPLAYMODE +{ + /* DISPLAY MODE FLAGS */ + /* Specify valid color depths and the refresh rate. */ + + unsigned short flags; + + /* TIMINGS */ + + unsigned short hactive; + unsigned short hblankstart; + unsigned short hsyncstart; + unsigned short hsyncend; + unsigned short hblankend; + unsigned short htotal; + + unsigned short vactive; + unsigned short vblankstart; + unsigned short vsyncstart; + unsigned short vsyncend; + unsigned short vblankend; + unsigned short vtotal; + + /* CLOCK FREQUENCY */ + + unsigned long frequency; + +} +TVDISPLAYMODE; + +TVDISPLAYMODE TVTimings[] = { + +/* NTSC resolution */ + { + 0x3, /* negative syncs */ + 0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0318, /* horizontal timings */ + 0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D, /* vertical timings */ + 0x0018EC4D, /* freq = 24.923052 MHz */ + }, + +/* PAL resolution */ + { + 0x3, /* positive syncs */ + 0x0300, 0x0300, 0x0320, 0x0350, 0x0360, 0x0360, /* horizontal timings */ + 0x0240, 0x0240, 0x024A, 0x024C, 0x0271, 0x0271, /* vertical timings */ + 0x001B0000, /* freq = 27.00 MHz */ + }, + +/* PAL resolution non-square pixels */ + { + 0x3, /* positive syncs */ + 0x02C0, 0x02C0, 0x02F0, 0x0330, 0x0360, 0x0360, /* horizontal timings */ + 0x0240, 0x0240, 0x024A, 0x024C, 0x0271, 0x0271, /* vertical timings */ + 0x001B0000, /* freq = 27.00 MHz */ + } +}; + +#define NUM_TV_MODES sizeof(TVTimings)/sizeof(TVDISPLAYMODE) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_type.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_type.h new file mode 100644 index 000000000..a50d5bd7c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_type.h @@ -0,0 +1,439 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_type.h,v 1.1 2002/12/10 15:12:26 alanh Exp $ */ +/* + * $Workfile: gfx_type.h $ + * + * This header file defines the pneumonics used when calling Durango routines. + * This file is automatically included by gfx_rtns.h + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef _gfx_type_h +#define _gfx_type_h + +/* MSR DEFINITIONS */ + +typedef enum DevStatus +{ FOUND, NOT_KNOWN, REQ_NOT_FOUND, REQ_NOT_INSTALLED } +DEV_STATUS; + +typedef struct msr +{ + DEV_STATUS Present; /* Node enumeration status */ + unsigned char Id; /* Device ID (from MSR specs) */ + unsigned long Address; /* Address - 32-bit MBus address at which 'Id' is found */ +} +MSR; + +typedef struct mValue +{ + unsigned long high; + unsigned long low; +} +Q_WORD; + +typedef struct mbusNode +{ + unsigned long address; + unsigned int deviceId; + unsigned int claimed; +} +MBUS_NODE; + +/* MSR ARRAY INDEXES */ +/* These are indexes into the array of MBus devices. These */ +/* should not be confused with the class codes at MSR register */ +/* 0x2000. */ + +#define RC_ID_MBIU0 0x00 +#define RC_ID_MBIU1 0x01 +#define RC_ID_MCP 0x02 +#define RC_ID_MPCI 0x03 +#define RC_ID_MC 0x04 +#define RC_ID_GP 0x05 +#define RC_ID_VG 0x06 +#define RC_ID_DF 0x07 +#define RC_ID_FG 0x08 +#define RC_ID_VA 0x09 +#define CP_ID_MBIU 0x0A +#define CP_ID_MPCI 0x0B +#define CP_ID_USB2 0x0C +#define CP_ID_ATAC 0x0D +#define CP_ID_MDD 0x0E +#define CP_ID_ACC 0x0F +#define CP_ID_USB1 0x10 +#define CP_ID_MCP 0x11 + +/* MBUS DEVICE CLASS CODES */ +/* These are the device ids for the known Redcloud MBus devices. */ + +#define RC_CC_MBIU 0x01 +#define RC_CC_MCP 0x02 +#define RC_CC_MPCI 0x05 +#define RC_CC_MC 0x20 +#define RC_CC_GP 0x3D +#define RC_CC_VG 0x3E +#define RC_CC_DF 0x3F +#define RC_CC_FG 0xF0 +#define RC_CC_VA 0x86 +#define CP_CC_MBIU 0x01 +#define CP_CC_MPCI 0x05 +#define CP_CC_USB2 0x42 +#define CP_CC_ATAC 0x47 +#define CP_CC_MDD 0xDF +#define CP_CC_ACC 0x33 +#define CP_CC_USB1 0x42 +#define CP_CC_MCP 0x02 + +/* VAIL AND MBIUS ARE AT KNOWN ADDRESSES */ +/* We can initialize the addresses of these devices in advance, */ +/* as their location should never change. */ + +#define RC_MB0_MBIU0 0x10000000 +#define RC_MB0_MBIU1 0x40000000 +#define CP_MB0_MBIU0 0x51010000 +#define RC_MB0_CPU 0x00000000 +#define FAKE_ADDRESS 0xFFFFFFFF + +/* MSR PORT DESCRIPTORS */ + +#define NOT_POPULATED 0 +#define NOT_INSTALLED 0xFFFE +#define REFLECTIVE 0xFFFF + +/* CRC DATA SOURCES */ + +#define CRC_SOURCE_GFX_DATA 0x00 +#define CRC_SOURCE_CRT_RGB 0x01 +#define CRC_SOURCE_FP_DATA 0x02 + +/* TV DEFINITIONS */ + +typedef enum TVStandardType +{ + TV_STANDARD_NTSC = 1, + TV_STANDARD_PAL +} +TVStandardType; + +typedef enum GfxOnTVType +{ + GFX_ON_TV_SQUARE_PIXELS = 1, + GFX_ON_TV_NO_SCALING +} +GfxOnTVType; + +#define CRT_DISABLE 0x00 +#define CRT_ENABLE 0x01 +#define CRT_STANDBY 0x02 +#define CRT_SUSPEND 0x03 + +#define TV_OUTPUT_COMPOSITE 0x01 +#define TV_OUTPUT_S_VIDEO 0x02 +#define TV_OUTPUT_YUV 0x03 +#define TV_OUTPUT_SCART 0x04 + +#define TV_FLICKER_FILTER_NONE 0x01 +#define TV_FLICKER_FILTER_NORMAL 0x02 +#define TV_FLICKER_FILTER_INTERLACED 0x03 + +#define TV_YC_DELAY_NONE 0x01 +#define TV_Y_DELAY_ONE_PIXEL 0x02 +#define TV_C_DELAY_ONE_PIXEL 0x03 +#define TV_C_DELAY_TWO_PIXELS 0x04 + +#define TV_SUB_CARRIER_RESET_NEVER 0x01 +#define TV_SUB_CARRIER_RESET_EVERY_TWO_LINES 0x02 +#define TV_SUB_CARRIER_RESET_EVERY_TWO_FRAMES 0x03 +#define TV_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES 0x04 + +#define TVENC_RESET_EVERY_ODD_FIELD 0x01 +#define TVENC_RESET_EVERY_EVEN_FIELD 0x02 +#define TVENC_RESET_NEXT_ODD_FIELD 0x03 +#define TVENC_RESET_NEXT_EVEN_FIELD 0x04 +#define TVENC_RESET_EVERY_FIELD 0x05 +#define TVENC_RESET_EVERY_X_ODD_FIELDS 0x06 +#define TVENC_RESET_EVERY_X_EVEN_FIELDS 0x07 + +/* VBI FORMATS */ + +#define VBI_FORMAT_VIDEO 0x1 +#define VBI_FORMAT_RAW 0x2 +#define VBI_FORMAT_CC 0x4 +#define VBI_FORMAT_NABTS 0x8 + +/* VIDEO DEFINITIONS */ + +#define VIDEO_FORMAT_UYVY 0x0 +#define VIDEO_FORMAT_Y2YU 0x1 +#define VIDEO_FORMAT_YUYV 0x2 +#define VIDEO_FORMAT_YVYU 0x3 +#define VIDEO_FORMAT_Y0Y1Y2Y3 0x4 +#define VIDEO_FORMAT_Y3Y2Y1Y0 0x5 +#define VIDEO_FORMAT_Y1Y0Y3Y2 0x6 +#define VIDEO_FORMAT_Y1Y2Y3Y0 0x7 +#define VIDEO_FORMAT_RGB 0x8 +#define VIDEO_FORMAT_P2M_P2L_P1M_P1L 0x9 +#define VIDEO_FORMAT_P1M_P1L_P2M_P2L 0xA +#define VIDEO_FORMAT_P1M_P2L_P2M_P1L 0xB + +#define VIDEO_DOWNSCALE_KEEP_1_OF 0x1 +#define VIDEO_DOWNSCALE_DROP_1_OF 0x2 + +typedef enum VideoSourceType +{/* The source from which the video processor shows full screen video */ + VIDEO_SOURCE_MEMORY = 1, + VIDEO_SOURCE_DVIP +} +VideoSourceType; + +typedef enum VbiSourceType +{/* The source from which the video processor takes VBI */ + VBI_SOURCE_MEMORY = 1, + VBI_SOURCE_DVIP +} +VbiSourceType; + +/* GENLOCK DEFINITIONS */ + +#define GENLOCK_SINGLE 0x001 +#define GENLOCK_FIELD_SYNC 0x001 +#define GENLOCK_CONTINUOUS 0x002 +#define GENLOCK_SYNCED_EDGE_FALLING 0x004 +#define GENLOCK_SYNCING_EDGE_FALLING 0x008 +#define GENLOCK_TIMEOUT 0x010 +#define GENLOCK_TVENC_RESET_EVEN_FIELD 0x020 +#define GENLOCK_TVENC_RESET_BEFORE_DELAY 0x040 +#define GENLOCK_TVENC_RESET 0x080 +#define GENLOCK_SYNC_TO_TVENC 0x100 + +/* VIP DEFINITIONS */ + +#define VIP_MODE_C 0x1 + +#define VIP_CAPTURE_STOP_LINE 0x1 +#define VIP_CAPTURE_STOP_FIELD 0x2 +#define VIP_CAPTURE_START_FIELD 0x4 + +#define VBI_ANCILLARY 0x1 +#define VBI_TASK_A 0x2 +#define VBI_TASK_B 0x4 + +/* VGA STRUCTURE */ + +#define GFX_STD_CRTC_REGS 25 +#define GFX_EXT_CRTC_REGS 16 + +#define GFX_VGA_FLAG_MISC_OUTPUT 0x00000001 +#define GFX_VGA_FLAG_STD_CRTC 0x00000002 +#define GFX_VGA_FLAG_EXT_CRTC 0x00000004 + +/* FS450 TV Standard flags */ + +#define GFX_TV_STANDARD_NTSC_M 0x0001 +#define GFX_TV_STANDARD_NTSC_M_J 0x0002 +#define GFX_TV_STANDARD_PAL_B 0x0004 +#define GFX_TV_STANDARD_PAL_D 0x0008 +#define GFX_TV_STANDARD_PAL_H 0x0010 +#define GFX_TV_STANDARD_PAL_I 0x0020 +#define GFX_TV_STANDARD_PAL_M 0x0040 +#define GFX_TV_STANDARD_PAL_N 0x0080 +#define GFX_TV_STANDARD_PAL_G 0x0100 + +/* FS450 VGA Mode flags */ + +#define GFX_VGA_MODE_UNKNOWN 0 +#define GFX_VGA_MODE_640X480 0x0001 +#define GFX_VGA_MODE_720X487 0x0002 +#define GFX_VGA_MODE_720X576 0x0004 +#define GFX_VGA_MODE_800X600 0x0008 +#define GFX_VGA_MODE_1024X768 0x0010 + +/* FS450 TVout mode flags */ + +#define GFX_TVOUT_MODE_CVBS 0x0001 +#define GFX_TVOUT_MODE_YC 0x0002 +#define GFX_TVOUT_MODE_RGB 0x0004 +#define GFX_TVOUT_MODE_CVBS_YC (GFX_TVOUT_MODE_CVBS | GFX_TVOUT_MODE_YC) + +/* FS450 Luma and Chroma Filters */ + +#define GFX_LUMA_FILTER 0x0001 +#define GFX_CHROMA_FILTER 0x0002 + +/* APS Trigger Bits */ + +#define GFX_APS_TRIGGER_OFF 0 +#define GFX_APS_TRIGGER_AGC_ONLY 1 +#define GFX_APS_TRIGGER_AGC_2_LINE 2 +#define GFX_APS_TRIGGER_AGC_4_LINE 3 + +typedef struct +{ + int xsize; + int ysize; + int hz; + int clock; + unsigned char miscOutput; + unsigned char stdCRTCregs[GFX_STD_CRTC_REGS]; + unsigned char extCRTCregs[GFX_EXT_CRTC_REGS]; +} +gfx_vga_struct; + +/* POSSIBLE STATUS VALUES */ + +#define GFX_STATUS_UNSUPPORTED (-3) +#define GFX_STATUS_BAD_PARAMETER (-2) +#define GFX_STATUS_ERROR (-1) +#define GFX_STATUS_OK 0 + +/* CPU AND VIDEO TYPES */ + +#define GFX_CPU_GXLV 1 +#define GFX_CPU_SC1200 2 +#define GFX_CPU_REDCLOUD 3 +#define GFX_CPU_PYRAMID 0x20801 + +#define GFX_VID_CS5530 1 +#define GFX_VID_SC1200 2 +#define GFX_VID_REDCLOUD 3 + +/* CHIP NAME AND REVISION */ + +typedef enum ChipType +{ + CHIP_NOT_DETECTED, + SC1200_REV_A, + SC1200_REV_B1_B2, + SC1200_REV_B3, + SC1200_REV_C1, + SC1200_REV_D1, + SC1200_REV_D1_1, + SC1200_REV_D2_MVD, /* Macrovision disabled */ + SC1200_REV_D2_MVE, /* Macrovision enabled */ + SC1200_FUTURE_REV +} +ChipType; + +#endif /* !_gfx_type_h */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vga.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vga.c new file mode 100644 index 000000000..a2c0dd648 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vga.c @@ -0,0 +1,146 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vga.c,v 1.1 2002/12/10 15:12:26 alanh Exp $ */ +/* + * $Workfile: gfx_vga.c $ + * + * This file contains routines to interface to the VGA registers. Some + * operating systems require mode sets be done through VGA, rather than + * directly using the "gfx_set_display_mode" routine. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* INCLUDE SUPPORT FOR FIRST GENERATION, IF SPECIFIED. */ + +#if GFX_VGA_GU1 +#include "vga_gu1.c" +#endif + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call either first or second generation routines. */ + +#if GFX_VGA_DYNAMIC + +#endif /* GFX_DISPLAY_DYNAMIC */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vid.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vid.c new file mode 100644 index 000000000..9ddde27ee --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vid.c @@ -0,0 +1,2127 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vid.c,v 1.1 2002/12/10 15:12:26 alanh Exp $ */ +/* + * $Workfile: gfx_vid.c $ + * + * This file contains routines to control the video overlay window. + * + * Video overlay routines: + * + * gfx_set_clock_frequency + * gfx_set_crt_enable + * gfx_set_video_enable + * gfx_set_video_format + * gfx_set_video_size + * gfx_set_video_offset + * gfx_set_video_yuv_offsets + * gfx_set_video_yuv_pitch + * gfx_set_video_scale + * gfx_set_video_upscale + * gfx_set_video_downscale_config + * gfx_set_video_downscale_coefficients + * gfx_set_video_downscale_enable + * gfx_set_video_vertical_downscale + * gfx_set_video_vertical_downscale_enable + * gfx_set_video_window + * gfx_set_video_left_crop + * gfx_set_video_color_key + * gfx_set_video_filter + * gfx_set_video_palette + * gfx_set_video_request + * gfx_set_video_source + * gfx_set_vbi_source + * gfx_set_vbi_lines + * gfx_set_vbi_total + * gfx_set_video_interlaced + * gfx_set_color_space_YUV + * gfx_set_vertical_scaler_offset + * gfx_set_top_line_in_odd + * gfx_set_genlock_delay + * gfx_set_genlock_enable + * gfx_set_video_cursor + * gfx_set_video_cursor_enable + * + * Alpha blending routines (SC1200 ONLY): + * + * gfx_select_alpha_region + * gfx_set_alpha_enable + * gfx_set_alpha_window + * gfx_set_alpha_value + * gfx_set_alpha_priority + * gfx_set_alpha_color + * gfx_set_alpha_color_enable + * gfx_set_no_ck_outside_alpha + * gfx_test_tvout_odd_field + * + * And the following routines if GFX_READ_ROUTINES is set: + * + * gfx_get_sync_polarities + * gfx_get_video_enable + * gfx_get_video_format + * gfx_get_video_src_size + * gfx_get_video_line_size + * gfx_get_video_xclip + * gfx_get_video_offset + * gfx_get_video_yuv_offsets + * gfx_get_video_yuv_pitch + * gfx_get_video_scale + * gfx_get_video_upscale + * gfx_get_video_downscale_config + * gfx_get_video_downscale_coefficients + * gfx_get_video_downscale_enable + * gfx_get_video_downscale_delta + * gfx_get_video_vertical_downscale_enable + * gfx_get_video_dst_size + * gfx_get_video_position + * gfx_get_video_color_key + * gfx_get_video_color_key_mask + * gfx_get_video_color_key_src + * gfx_get_video_filter + * gfx_get_video_request + * gfx_get_video_source + * gfx_get_vbi_source + * gfx_get_vbi_lines + * gfx_get_vbi_total + * gfx_get_video_interlaced + * gfx_get_color_space_YUV + * gfx_get_vertical_scaler_offset + * gfx_get_genlock_delay + * gfx_get_genlock_enable + * gfx_get_video_cursor + * gfx_get_clock_frequency + * gfx_read_crc + * + * Alpha blending read routines (SC1200 ONLY): + * + * gfx_get_alpha_enable + * gfx_get_alpha_size + * gfx_get_alpha_value + * gfx_get_alpha_priority + * gfx_get_alpha_color + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* STATIC VARIABLES FOR VIDEO OVERLAY CONTROL */ +/* These are saved to allow these routines to do clipping. */ + +unsigned long gfx_vid_offset = 0; /* copy from last gfx_set_video_offset */ +unsigned long gfx_vid_uoffset = 0; /* copy from last gfx_set_video_yuv_offsets */ +unsigned long gfx_vid_voffset = 0; /* copy from last gfx_set_video_yuv_offsets */ +unsigned long gfx_vid_srcw = 300; /* copy from last gfx_set_video_scale */ +unsigned long gfx_vid_srch = 300; /* copy from last gfx_set_video_scale */ +unsigned long gfx_vid_dstw = 300; /* copy from last gfx_set_video_scale */ +unsigned long gfx_vid_dsth = 300; /* copy from last gfx_set_video_scale */ +short gfx_vid_xpos = 0; /* copy from last gfx_set_video_window */ +short gfx_vid_ypos = 0; /* copy from last gfx_set_video_window */ +unsigned short gfx_vid_width = 0; /* copy from last gfx_set_video_window */ +unsigned short gfx_vid_height = 0; /* copy from last gfx_set_video_window */ + +int gfx_alpha_select = 0; /* currently selected alpha region */ + +int gfx_set_screen_enable(int enable); /* forward declaration */ + +/* INCLUDE SUPPORT FOR CS5530, IF SPECIFIED. */ + +#if GFX_VIDEO_CS5530 +#include "vid_5530.c" +#endif + +/* INCLUDE SUPPORT FOR SC1200, IF SPECIFIED. */ + +#if GFX_VIDEO_SC1200 +#include "vid_1200.c" +#endif + +/* INLUDE SUPPORT FOR REDCLOUD, IF SPECIFIED. */ + +#if GFX_VIDEO_REDCLOUD +#include "vid_rdcl.c" +#endif + +/*--------------------------------------------------------------------------- + * gfx_select_alpha_region + * + * This routine selects which alpha region should be used for future + * updates. The SC1200, for example, has 3 alpha windows available, + * so valid parameter values are 0..2. + *--------------------------------------------------------------------------- + */ +int +gfx_select_alpha_region(int region) +{ + if (region > 2) + return (GFX_STATUS_BAD_PARAMETER); + + gfx_alpha_select = region; + return (GFX_STATUS_OK); +} + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call either CS5530 or SC1200 routines. */ + +#if GFX_VIDEO_DYNAMIC + +/*--------------------------------------------------------------------------- + * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine is used to disable all components of video overlay before + * performing a mode switch. + *--------------------------------------------------------------------------- + */ +void +gfx_reset_video(void) +{ +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + cs5530_reset_video(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_reset_video(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_reset_video(); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine is used to configure the display output during a modeset + *--------------------------------------------------------------------------- + */ +int +gfx_set_display_control(int sync_polarities) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_display_control(sync_polarities); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_display_control(sync_polarities); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_display_control(sync_polarities); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_clock_frequency + *----------------------------------------------------------------------------- + */ +void +gfx_set_clock_frequency(unsigned long frequency) +{ +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + cs5530_set_clock_frequency(frequency); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_set_clock_frequency(frequency); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_set_clock_frequency(frequency); +# endif +} + +/*----------------------------------------------------------------------------- + * gfx_set_crt_enable + *----------------------------------------------------------------------------- + */ +int +gfx_set_crt_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_crt_enable(enable); +# endif +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_crt_enable(enable); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_crt_enable(enable); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_enable + *----------------------------------------------------------------------------- + */ +int +gfx_set_video_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_enable(enable); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_enable(enable); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_enable(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_screen_enable (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine enables or disables the graphics display logic of the video processor. + *--------------------------------------------------------------------------- + */ +int +gfx_set_screen_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_screen_enable(enable); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_format + *----------------------------------------------------------------------------- + */ +int +gfx_set_video_format(unsigned long format) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_format(format); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_format(format); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_format(format); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_size + *----------------------------------------------------------------------------- + */ +int +gfx_set_video_size(unsigned short width, unsigned short height) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_size(width, height); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_size(width, height); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_size(width, height); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_yuv_pitch + *----------------------------------------------------------------------------- + */ +int +gfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_yuv_pitch(ypitch, uvpitch); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_offset + *----------------------------------------------------------------------------- + */ +int +gfx_set_video_offset(unsigned long offset) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_offset(offset); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_offset(offset); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_offset(offset); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_yuv_offsets + *----------------------------------------------------------------------------- + */ +int +gfx_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset, + unsigned long voffset) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_yuv_offsets(yoffset, uoffset, voffset); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_scale + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_scale(srcw, srch, dstw, dsth); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_scale(srcw, srch, dstw, dsth); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_scale(srcw, srch, dstw, dsth); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_upscale + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_upscale(srcw, srch, dstw, dsth); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_vertical_downscale + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_vertical_downscale(unsigned short srch, unsigned short dsth) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_vertical_downscale(srch, dsth); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_vertical_downscale_enable + *--------------------------------------------------------------------------- + */ +void +gfx_set_video_vertical_downscale_enable(int enable) +{ +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_set_video_vertical_downscale_enable(enable); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_config + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_downscale_config(unsigned short type, unsigned short m) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_downscale_config(type, m); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_downscale_config(type, m); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_coefficients + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = + sc1200_set_video_downscale_coefficients(coef1, coef2, coef3, + coef4); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = + redcloud_set_video_downscale_coefficients(coef1, coef2, coef3, + coef4); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_enable + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_downscale_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_downscale_enable(enable); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_downscale_enable(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_window + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_window(x, y, w, h); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_window(x, y, w, h); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_window(x, y, w, h); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_left_crop + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_left_crop(unsigned short x) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_left_crop(x); +# endif +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_left_crop(x); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_left_crop(x); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_color_key + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_color_key(key, mask, graphics); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_color_key(key, mask, graphics); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_color_key(key, mask, graphics); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_filter + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_filter(int xfilter, int yfilter) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_filter(xfilter, yfilter); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_filter(xfilter, yfilter); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_filter(xfilter, yfilter); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_palette(unsigned long *palette) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_palette(palette); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_palette(palette); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_palette(palette); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette_entry + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_palette_entry(unsigned long index, unsigned long palette) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_set_video_palette_entry(index, palette); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_palette_entry(index, palette); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_palette_entry(index, palette); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_request + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_request(short x, short y) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_request(x, y); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_request(x, y); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_source + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_source(VideoSourceType source) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_source(source); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_source + *--------------------------------------------------------------------------- + */ +int +gfx_set_vbi_source(VbiSourceType source) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_vbi_source(source); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_lines + *--------------------------------------------------------------------------- + */ +int +gfx_set_vbi_lines(unsigned long even, unsigned long odd) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_vbi_lines(even, odd); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_total + *--------------------------------------------------------------------------- + */ +int +gfx_set_vbi_total(unsigned long even, unsigned long odd) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_vbi_total(even, odd); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_interlaced + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_interlaced(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_video_interlaced(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_color_space_YUV + *--------------------------------------------------------------------------- + */ +int +gfx_set_color_space_YUV(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_color_space_YUV(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vertical_scaler_offset + *--------------------------------------------------------------------------- + */ +int +gfx_set_vertical_scaler_offset(char offset) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_vertical_scaler_offset(offset); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_top_line_in_odd + *--------------------------------------------------------------------------- + */ +int +gfx_set_top_line_in_odd(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_top_line_in_odd(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_genlock_delay + *--------------------------------------------------------------------------- + */ +int +gfx_set_genlock_delay(unsigned long delay) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_genlock_delay(delay); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_genlock_enable + *--------------------------------------------------------------------------- + */ +int +gfx_set_genlock_enable(int flags) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_genlock_enable(flags); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_cursor + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, unsigned long color1, + unsigned long color2) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = + sc1200_set_video_cursor(key, mask, select_color2, color1, color2); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = + redcloud_set_video_cursor(key, mask, select_color2, color1, + color2); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_cursor_enable + *--------------------------------------------------------------------------- + */ +int +gfx_set_video_cursor_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_video_cursor_enable(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_enable + *--------------------------------------------------------------------------- + */ +int +gfx_set_alpha_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_alpha_enable(enable); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_alpha_enable(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_window + *--------------------------------------------------------------------------- + */ +int +gfx_set_alpha_window(short x, short y, + unsigned short width, unsigned short height) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_alpha_window(x, y, width, height); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_alpha_window(x, y, width, height); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_value + *--------------------------------------------------------------------------- + */ +int +gfx_set_alpha_value(unsigned char alpha, char delta) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_alpha_value(alpha, delta); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_alpha_value(alpha, delta); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_priority + *--------------------------------------------------------------------------- + */ +int +gfx_set_alpha_priority(int priority) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_alpha_priority(priority); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_alpha_priority(priority); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_color + *--------------------------------------------------------------------------- + */ +int +gfx_set_alpha_color(unsigned long color) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_alpha_color(color); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_alpha_color(color); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_color_enable + *--------------------------------------------------------------------------- + */ +int +gfx_set_alpha_color_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_alpha_color_enable(enable); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_alpha_color_enable(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_no_ck_outside_alpha + *--------------------------------------------------------------------------- + */ +int +gfx_set_no_ck_outside_alpha(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_no_ck_outside_alpha(enable); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_set_no_ck_outside_alpha(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_set_macrovision_enable + *--------------------------------------------------------------------------- + */ +int +gfx_set_macrovision_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_set_macrovision_enable(enable); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_disable_softvga + *--------------------------------------------------------------------------- + */ +int +gfx_disable_softvga(void) +{ + int status = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_disable_softvga(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_disable_softvga(); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_enable_softvga + *--------------------------------------------------------------------------- + */ +int +gfx_enable_softvga(void) +{ + int status = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_enable_softvga(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_enable_softvga(); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_get_clock_frequency + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_clock_frequency(void) +{ + unsigned long frequency = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + frequency = cs5530_get_clock_frequency(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + frequency = sc1200_get_clock_frequency(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + frequency = redcloud_get_clock_frequency(); +# endif + return (frequency); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*--------------------------------------------------------------------------- + * gfx_get_vsa2_softvga_enable + *--------------------------------------------------------------------------- + */ +int +gfx_get_vsa2_softvga_enable(void) +{ + int enable = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + enable = cs5530_get_vsa2_softvga_enable(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + enable = sc1200_get_vsa2_softvga_enable(); +# endif + return enable; + +} + +/*--------------------------------------------------------------------------- + * gfx_get_sync_polarities + *--------------------------------------------------------------------------- + */ +int +gfx_get_sync_polarities(void) +{ + int polarities = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + polarities = cs5530_get_sync_polarities(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + polarities = sc1200_get_sync_polarities(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + polarities = redcloud_get_sync_polarities(); +# endif + return (polarities); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_palette_entry + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_palette_entry(unsigned long index, unsigned long *palette) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + status = cs5530_get_video_palette_entry(index, palette); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_get_video_palette_entry(index, palette); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_get_video_palette_entry(index, palette); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_enable + *----------------------------------------------------------------------------- + */ +int +gfx_get_video_enable(void) +{ + int enable = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + enable = cs5530_get_video_enable(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + enable = sc1200_get_video_enable(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + enable = redcloud_get_video_enable(); +# endif + return (enable); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_format + *----------------------------------------------------------------------------- + */ +int +gfx_get_video_format(void) +{ + int format = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + format = cs5530_get_video_format(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + format = sc1200_get_video_format(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + format = redcloud_get_video_format(); +# endif + return (format); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_src_size + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_src_size(void) +{ + unsigned long size = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + size = cs5530_get_video_src_size(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + size = sc1200_get_video_src_size(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + size = redcloud_get_video_src_size(); +# endif + return (size); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_line_size + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_line_size(void) +{ + unsigned long size = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + size = cs5530_get_video_line_size(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + size = sc1200_get_video_line_size(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + size = redcloud_get_video_line_size(); +# endif + return (size); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_xclip + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_xclip(void) +{ + unsigned long size = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + size = cs5530_get_video_xclip(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + size = sc1200_get_video_xclip(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + size = redcloud_get_video_xclip(); +# endif + return (size); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_offset + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_offset(void) +{ + unsigned long offset = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + offset = cs5530_get_video_offset(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + offset = sc1200_get_video_offset(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + offset = redcloud_get_video_offset(); +# endif + return (offset); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_yuv_offsets + *----------------------------------------------------------------------------- + */ +void +gfx_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset, + unsigned long *voffset) +{ +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_video_yuv_offsets(yoffset, uoffset, voffset); +# endif +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_yuv_pitch + *----------------------------------------------------------------------------- + */ +void +gfx_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch) +{ +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_video_yuv_pitch(ypitch, uvpitch); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_upscale + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_upscale(void) +{ + unsigned long scale = 0; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + scale = sc1200_get_video_upscale(); +# endif + return (scale); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_scale + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_scale(void) +{ + unsigned long scale = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + scale = cs5530_get_video_scale(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + scale = sc1200_get_video_scale(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + scale = redcloud_get_video_scale(); +# endif + return (scale); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_delta + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_downscale_delta(void) +{ + unsigned long delta = 0; + +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + delta = redcloud_get_video_downscale_delta(); +# endif + return (delta); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_vertical_downscale_enable + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_vertical_downscale_enable(void) +{ + int enable = 0; + +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + enable = redcloud_get_video_vertical_downscale_enable(); +# endif + return (enable); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_config + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_downscale_config(unsigned short *type, unsigned short *m) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_get_video_downscale_config(type, m); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_get_video_downscale_config(type, m); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_coefficients + *--------------------------------------------------------------------------- + */ +void +gfx_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4) +{ +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_get_video_downscale_coefficients(coef1, coef2, coef3, coef4); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_video_downscale_coefficients(coef1, coef2, coef3, coef4); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_enable + *--------------------------------------------------------------------------- + */ +void +gfx_get_video_downscale_enable(int *enable) +{ +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_get_video_downscale_enable(enable); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_video_downscale_enable(enable); +# endif +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_dst_size + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_dst_size(void) +{ + unsigned long size = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + size = cs5530_get_video_dst_size(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + size = sc1200_get_video_dst_size(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + size = redcloud_get_video_dst_size(); +# endif + return (size); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_position + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_position(void) +{ + unsigned long position = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + position = cs5530_get_video_position(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + position = sc1200_get_video_position(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + position = redcloud_get_video_position(); +# endif + return (position); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_color_key(void) +{ + unsigned long key = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + key = cs5530_get_video_color_key(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + key = sc1200_get_video_color_key(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + key = redcloud_get_video_color_key(); +# endif + return (key); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_mask + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_video_color_key_mask(void) +{ + unsigned long mask = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + mask = cs5530_get_video_color_key_mask(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + mask = sc1200_get_video_color_key_mask(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + mask = redcloud_get_video_color_key_mask(); +# endif + return (mask); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_src + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_color_key_src(void) +{ + int src = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + src = cs5530_get_video_color_key_src(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + src = sc1200_get_video_color_key_src(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + src = redcloud_get_video_color_key_src(); +# endif + return (src); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_filter + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_filter(void) +{ + int filter = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + filter = cs5530_get_video_filter(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + filter = sc1200_get_video_filter(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + filter = redcloud_get_video_filter(); +# endif + return (filter); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_request + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_request(short *x, short *y) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_get_video_request(x, y); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + status = redcloud_get_video_request(x, y); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_source + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_source(VideoSourceType * source) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_get_video_source(source); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_source + *--------------------------------------------------------------------------- + */ +int +gfx_get_vbi_source(VbiSourceType * source) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_get_vbi_source(source); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_lines + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vbi_lines(int odd) +{ + unsigned long lines = (unsigned long)GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + lines = sc1200_get_vbi_lines(odd); +# endif + return (lines); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_total + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vbi_total(int odd) +{ + unsigned long total = (unsigned long)GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + total = sc1200_get_vbi_total(odd); +# endif + return (total); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_interlaced + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_interlaced(void) +{ + int interlaced = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + interlaced = sc1200_get_video_interlaced(); +# endif + return (interlaced); +} + +/*--------------------------------------------------------------------------- + * gfx_get_color_space_YUV + *--------------------------------------------------------------------------- + */ +int +gfx_get_color_space_YUV(void) +{ + int color_space = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + color_space = sc1200_get_color_space_YUV(); +# endif + return (color_space); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vertical_scaler_offset + *--------------------------------------------------------------------------- + */ +int +gfx_get_vertical_scaler_offset(char *offset) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + status = sc1200_get_vertical_scaler_offset(offset); +# endif + return (status); +} + +/*--------------------------------------------------------------------------- + * gfx_get_genlock_delay + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_get_genlock_delay(void) +{ + unsigned long delay = (unsigned long)GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + delay = sc1200_get_genlock_delay(); +# endif + return (delay); +} + +/*--------------------------------------------------------------------------- + * gfx_get_genlock_enable + *--------------------------------------------------------------------------- + */ +int +gfx_get_genlock_enable(void) +{ + int enable = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + enable = sc1200_get_genlock_enable(); +# endif + return (enable); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_cursor + *--------------------------------------------------------------------------- + */ +int +gfx_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, unsigned long *color1, + unsigned short *color2) +{ + int enable = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + enable = + sc1200_get_video_cursor(key, mask, select_color2, color1, color2); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + enable = + redcloud_get_video_cursor(key, mask, select_color2, color1, + color2); +# endif + return (enable); +} + +/*--------------------------------------------------------------------------- + * gfx_read_crc + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_read_crc(void) +{ + unsigned long crc = 0; + +# if GFX_VIDEO_CS5530 + if (gfx_video_type == GFX_VIDEO_TYPE_CS5530) + crc = cs5530_read_crc(); +# endif +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + crc = sc1200_read_crc(); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + crc = redcloud_read_crc(); +# endif + return (crc); +} + +/*--------------------------------------------------------------------------- + * gfx_read_crc32 + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_read_crc32(void) +{ + unsigned long crc = 0; + +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + crc = redcloud_read_crc32(); +# endif + return (crc); +} + +/*--------------------------------------------------------------------------- + * gfx_read_window_crc + *--------------------------------------------------------------------------- + */ +unsigned long +gfx_read_window_crc(int source, unsigned short x, unsigned short y, + unsigned short width, unsigned short height, int crc32) +{ + unsigned long crc = 0; + +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + crc = redcloud_read_window_crc(source, x, y, width, height, crc32); +# endif + return (crc); +} + +/*----------------------------------------------------------------------------- + * gfx_get_macrovision_enable + *----------------------------------------------------------------------------- + */ +int +gfx_get_macrovision_enable(void) +{ + int enable = 0; + +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + enable = sc1200_get_video_enable(); +# endif + return (enable); +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_enable + *--------------------------------------------------------------------------- + */ +void +gfx_get_alpha_enable(int *enable) +{ +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_get_alpha_enable(enable); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_alpha_enable(enable); +# endif + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_size + *--------------------------------------------------------------------------- + */ +void +gfx_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height) +{ +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_get_alpha_size(x, y, width, height); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_alpha_size(x, y, width, height); +# endif + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_value + *--------------------------------------------------------------------------- + */ +void +gfx_get_alpha_value(unsigned char *alpha, char *delta) +{ +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_get_alpha_value(alpha, delta); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_alpha_value(alpha, delta); +# endif + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_priority + *--------------------------------------------------------------------------- + */ +void +gfx_get_alpha_priority(int *priority) +{ +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_get_alpha_priority(priority); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_alpha_priority(priority); +# endif + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_color + *--------------------------------------------------------------------------- + */ +void +gfx_get_alpha_color(unsigned long *color) +{ +# if GFX_VIDEO_SC1200 + if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) + sc1200_get_alpha_color(color); +# endif +# if GFX_VIDEO_REDCLOUD + if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD) + redcloud_get_alpha_color(color); +# endif + return; +} + +#endif /* GFX_READ_ROUTINES */ + +#endif /* GFX_VIDEO_DYNAMIC */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vip.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vip.c new file mode 100644 index 000000000..1f506ae94 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vip.c @@ -0,0 +1,632 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/gfx_vip.c,v 1.1 2002/12/10 15:12:26 alanh Exp $ */ +/* + * $Workfile: gfx_vip.c $ + * + * This file contains routines to control the video input port (VIP). + * + * gfx_set_vip_enable + * gfx_set_vip_capture_run_mode + * gfx_set_vip_base + * gfx_set_vip_pitch + * gfx_set_vip_mode + * gfx_set_vbi_enable + * gfx_set_vbi_mode + * gfx_set_vbi_base + * gfx_set_vbi_pitch + * gfx_set_vbi_direct + * gfx_set_vbi_interrupt + * gfx_set_vip_bus_request_threshold_high + * gfx_set_vip_last_line + * gfx_test_vip_odd_field + * gfx_test_vip_bases_updated + * gfx_test_vip_fifo_overflow + * gfx_get_vip_line + * gfx_get_vip_base + * gfx_get_vbi_pitch + * + * And the following routines if GFX_READ_ROUTINES is set: + * + * gfx_get_vip_enable + * gfx_get_vip_pitch + * gfx_get_vip_mode + * gfx_get_vbi_enable + * gfx_get_vbi_mode + * gfx_get_vbi_base + * gfx_get_vbi_direct + * gfx_get_vbi_interrupt + * gfx_get_vip_bus_request_threshold_high + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* INCLUDE SUPPORT FOR SC1200, IF SPECIFIED. */ + +#if GFX_VIP_SC1200 +#include "vip_1200.c" +#endif + +/* WRAPPERS IF DYNAMIC SELECTION */ +/* Extra layer to call either CS5530 or SC1200 routines. */ + +#if GFX_VIP_DYNAMIC + +/*----------------------------------------------------------------------------- + * gfx_set_vip_enable + *----------------------------------------------------------------------------- + */ +int +gfx_set_vip_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vip_enable(enable); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_capture_run_mode + *----------------------------------------------------------------------------- + */ +int +gfx_set_vip_capture_run_mode(int mode) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vip_capture_run_mode(mode); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_base + *----------------------------------------------------------------------------- + */ +int +gfx_set_vip_base(unsigned long even, unsigned long odd) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vip_base(even, odd); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_pitch + *----------------------------------------------------------------------------- + */ +int +gfx_set_vip_pitch(unsigned long pitch) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vip_pitch(pitch); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_mode + *----------------------------------------------------------------------------- + */ +int +gfx_set_vip_mode(int mode) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vip_mode(mode); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_enable + *----------------------------------------------------------------------------- + */ +int +gfx_set_vbi_enable(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vbi_enable(enable); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_mode + *----------------------------------------------------------------------------- + */ +int +gfx_set_vbi_mode(int mode) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vbi_mode(mode); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_base + *----------------------------------------------------------------------------- + */ +int +gfx_set_vbi_base(unsigned long even, unsigned long odd) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vbi_base(even, odd); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_pitch + *----------------------------------------------------------------------------- + */ +int +gfx_set_vbi_pitch(unsigned long pitch) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vbi_pitch(pitch); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_direct + *----------------------------------------------------------------------------- + */ +int +gfx_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vbi_direct(even_lines, odd_lines); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_interrupt + *----------------------------------------------------------------------------- + */ +int +gfx_set_vbi_interrupt(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vbi_interrupt(enable); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_bus_request_threshold_high + *----------------------------------------------------------------------------- + */ +int +gfx_set_vip_bus_request_threshold_high(int enable) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vip_bus_request_threshold_high(enable); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_last_line + *----------------------------------------------------------------------------- + */ +int +gfx_set_vip_last_line(int last_line) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_set_vip_last_line(last_line); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_test_vip_odd_field + *----------------------------------------------------------------------------- + */ +int +gfx_test_vip_odd_field(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_test_vip_odd_field(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_test_vip_bases_updated + *----------------------------------------------------------------------------- + */ +int +gfx_test_vip_bases_updated(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_test_vip_bases_updated(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_test_vip_fifo_overflow + *----------------------------------------------------------------------------- + */ +int +gfx_test_vip_fifo_overflow(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_test_vip_fifo_overflow(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_line + *----------------------------------------------------------------------------- + */ +int +gfx_get_vip_line(void) +{ + int status = GFX_STATUS_UNSUPPORTED; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + status = sc1200_get_vip_line(); +# endif + return (status); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_base + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vip_base(int odd) +{ + unsigned long base = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + base = sc1200_get_vip_base(odd); +# endif + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_pitch + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vbi_pitch(void) +{ + unsigned long pitch = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + pitch = sc1200_get_vbi_pitch(); +# endif + return (pitch); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*----------------------------------------------------------------------------- + * gfx_get_vip_enable + *----------------------------------------------------------------------------- + */ +int +gfx_get_vip_enable(void) +{ + int enable = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + enable = sc1200_get_vip_enable(); +# endif + return (enable); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_pitch + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vip_pitch(void) +{ + unsigned long pitch = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + pitch = sc1200_get_vip_pitch(); +# endif + return (pitch); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_mode + *----------------------------------------------------------------------------- + */ +int +gfx_get_vip_mode(void) +{ + int mode = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + mode = sc1200_get_vip_mode(); +# endif + return (mode); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_enable + *----------------------------------------------------------------------------- + */ +int +gfx_get_vbi_enable(void) +{ + int enable = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + enable = sc1200_get_vbi_enable(); +# endif + return (enable); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_mode + *----------------------------------------------------------------------------- + */ +int +gfx_get_vbi_mode(void) +{ + int mode = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + mode = sc1200_get_vbi_mode(); +# endif + return (mode); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_base + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vbi_base(int odd) +{ + unsigned long base = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + base = sc1200_get_vbi_base(odd); +# endif + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_direct + *----------------------------------------------------------------------------- + */ +unsigned long +gfx_get_vbi_direct(int odd) +{ + unsigned long vbi_direct_lines = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + vbi_direct_lines = sc1200_get_vbi_direct(odd); +# endif + return (vbi_direct_lines); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_interrupt + *----------------------------------------------------------------------------- + */ +int +gfx_get_vbi_interrupt(void) +{ + int enable = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + enable = sc1200_get_vbi_interrupt(); +# endif + return (enable); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_bus_request_threshold_high + *----------------------------------------------------------------------------- + */ +int +gfx_get_vip_bus_request_threshold_high(void) +{ + int enable = 0; + +# if GFX_VIP_SC1200 + if (gfx_vip_type == GFX_VIP_TYPE_SC1200) + enable = sc1200_get_vip_bus_request_threshold_high(); +# endif + return (enable); +} + +#endif /* GFX_READ_ROUTINES */ + +#endif /* GFX_VIP_DYNAMIC */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/history.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/history.h new file mode 100644 index 000000000..36f7fb98e --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/history.h @@ -0,0 +1,145 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/history.h,v 1.2 2003/02/05 18:38:43 alanh Exp $ */ +/* + * $Workfile: history.h $ + * + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + + +/* Version is in the format of MMmmpp + * where in MM is the Major version, mm is the minor version + * and pp is the patch number (0 - 99) +*/ + +#define DURANGO_VERSION 24902 + +#if 0 + +This file contains specific revision info SINCE THE LAST RELEASE. It is not meant to +be a comprehensive record of all additions. + +#endif +/* END OF FILE */ + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/i2c_acc.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/i2c_acc.c new file mode 100644 index 000000000..ff205ebda --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/i2c_acc.c @@ -0,0 +1,990 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/i2c_acc.c,v 1.1 2002/12/10 15:12:26 alanh Exp $ */ +/* + * $Workfile: i2c_acc.c $ + * + * This file contains routines to write to and read from the I2C bus using + * the ACCESS.bus hardware in the SC1200. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* SUPER IO DEFINITIONS */ + +#define INDEX_1 0x15C /* base address 1 selected */ +#define DATA_1 0x15D +#define INDEX_2 0x2E /* base address 2 selected */ +#define DATA_2 0x2F +#define PCI_INDEX 0xCF8 /* PCI configuration space INDEX */ +#define PCI_DATA 0xCFC /* PCI configuration space DATA */ +#define BASE_ADR_MSB_REG 0x60 /* base address MSB register */ +#define BASE_ADR_LSB_REG 0x61 /* base address LSB register */ + +#define SIO_BASE_ADR_15C_15D 0x6000000 +#define SIO_BASE_ADR_2E_2F 0x4000000 + +/* SUPER IO GLOBALS */ + +unsigned short index_reg, data_reg; + +/* ACCESS BUS DEFINITIONS */ + +#define ACC_I2C_TIMEOUT 1000000 /* Number of reads before timing out */ +#define ACB1_BASE 0x810 /* ACCESS.bus base addresses */ +#define ACB2_BASE 0x820 +#define ACBSDA 0 /* ACB serial data */ +#define ACBST 1 /* ACB status */ +#define ACBCST 2 /* ACB control status */ +#define ACBCTL1 3 /* ACB control 1 */ +#define ACBADDR 4 /* ACB own address */ +#define ACBCTL2 5 /* ACB control 2 */ +#define LDN 0x7 /* Logical Device Numbers */ +#define ACB1_LDN 0x5 +#define ACB2_LDN 0x6 + +/* INITIAL ACCESS.bus BASE ADDRESS VALUES */ + +unsigned short base_address_array[3] = { 0, ACB1_BASE, ACB2_BASE }; +char Freq = 0x71; + +/* LOCAL ACCESS.bus FUNCTION DECLARATIONS */ + +void acc_i2c_start(unsigned char busnum); +void acc_i2c_stop(unsigned char busnum); +void acc_i2c_abort_data(unsigned char busnum); +void acc_i2c_bus_recovery(unsigned char busnum); +void acc_i2c_stall_after_start(unsigned char busnum, int state); +void acc_i2c_send_address(unsigned char busnum, unsigned char cData); +int acc_i2c_ack(unsigned char busnum, int fPut, int negAck); +void acc_i2c_stop_clock(unsigned char busnum); +void acc_i2c_activate_clock(unsigned char busnum); +void acc_i2c_write_byte(unsigned char busnum, unsigned char cData); +unsigned char acc_i2c_read_byte(unsigned char busnum, int last_byte); +void acc_i2c_reset_bus(unsigned char busnum); +int acc_i2c_request_master(unsigned char busnum); +void acc_i2c_config(unsigned char busnum, short adr, char freq); +char acc_i2c_set_freq(unsigned char busnum, char freq); +unsigned short acc_i2c_set_base_address(unsigned char busnum, short adr); + +/* LOCAL HELPER ROUTINES */ + +void OsPciReadDWord(int bus, int dev, int func, int address, + unsigned long *data); +int sio_set_index_data_reg(void); +void sio_write_reg(unsigned char reg, unsigned char data); +unsigned char sio_read_reg(unsigned char reg); + +int acc_i2c_reset(unsigned char busnum, short adr, char freq); +int acc_i2c_write(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, + unsigned char *data); +int acc_i2c_read(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, + unsigned char *data); +int acc_i2c_select_gpio(int clock, int data); +int acc_i2c_init(void); +void acc_i2c_cleanup(void); + +/*--------------------------------------------------------------------------- + * OsPciReadDWord + * + * This routine reads one double word from the PCI configuration header + * defined by 'bus', 'dev', 'func' and 'address' to the double word + * pointed to by 'data'. + * + * Returns : None. + *--------------------------------------------------------------------------- + */ +void +OsPciReadDWord(int bus, int dev, int func, int address, unsigned long *data) +{ + /* + * The address of a double word in the Configuration Header is built in + * the following way : + * {10000000,bus[23:16],device[15:11],function[10:8],address[7:2],00} + */ + long addr = (0x80000000 | + ((bus & 0xff) << 16) | + ((dev & 0x1f) << 11) | + ((func & 0x7) << 8) | (address & 0xff)); + OUTD(PCI_INDEX, addr); + *data = IND(PCI_DATA); +} + +/*--------------------------------------------------------------------------- + * sio_set_index_data_reg + * + * This routine checks which index and data registers to use + * in order to access the Super I/O registers + * + * Returns : 1 - OK + * 0 - Super I/O disabled or configuration access disabled + * + *--------------------------------------------------------------------------- + */ +int +sio_set_index_data_reg(void) +{ + unsigned long xbus_expention_bar, io_control_reg1; + + OsPciReadDWord(0, 0x12, 5, 0x10, &xbus_expention_bar); + xbus_expention_bar = xbus_expention_bar & 0xfffffffe; + io_control_reg1 = IND((unsigned short)xbus_expention_bar); + + if ((io_control_reg1) & (SIO_BASE_ADR_15C_15D)) { + index_reg = INDEX_1; + data_reg = DATA_1; + return (1); + } + + if ((io_control_reg1) & (SIO_BASE_ADR_2E_2F)) { + index_reg = INDEX_2; + data_reg = DATA_2; + return (1); + } + + return (0); +} + +/*--------------------------------------------------------------------------- + * sio_write_reg + * + * This routine writes 'data' to 'reg' Super I/O register + * + * Returns : None + *--------------------------------------------------------------------------- + */ +void +sio_write_reg(unsigned char reg, unsigned char data) +{ + OUTB(index_reg, reg); + OUTB(data_reg, data); +} + +/*--------------------------------------------------------------------------- + * sio_read_reg + * + * This routine reads data from 'reg' Super I/O register + * + * Returns : The data read from the requested register + *--------------------------------------------------------------------------- + */ +unsigned char +sio_read_reg(unsigned char reg) +{ + OUTB(index_reg, reg); + return INB(data_reg); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_reset + * + * This routine resets the I2C bus as follows : + * · Sets the base address of the ACCESS.bus + * · Sets the frequency of the ACCESS.bus + * · Resets the ACCESS.bus + * + * If 'adr' is -1 the address is read from the hardware. + * If 'freq' is -1 the frequency is set to 56 clock cycles. + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +int +acc_i2c_reset(unsigned char busnum, short adr, char freq) +#else +int +gfx_i2c_reset(unsigned char busnum, short adr, char freq) +#endif +{ + if ((busnum != 1) && (busnum != 2)) + return GFX_STATUS_BAD_PARAMETER; + acc_i2c_config(busnum, adr, freq); + if (base_address_array[busnum] == 0) + return GFX_STATUS_ERROR; + acc_i2c_reset_bus(busnum); + return GFX_STATUS_OK; +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_select_gpio + * + * This routine selects which GPIO pins to use. + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +int +acc_i2c_select_gpio(int clock, int data) +#else +int +gfx_i2c_select_gpio(int clock, int data) +#endif +{ + /* THIS ROUTINE DOES NOT APPLY TO THE ACCESS.bus IMPLEMENTATION. */ + + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_write + * + * This routine writes data to the specified I2C address. + * busnum - ACCESS.bus number (1 or 2). + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +int +acc_i2c_write(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, unsigned char *data) +#else +int +gfx_i2c_write(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, unsigned char *data) +#endif +{ + int loop = 0; + + if ((busnum != 1) && (busnum != 2)) + return GFX_STATUS_BAD_PARAMETER; + + /* REQUEST MASTER */ + + if (!acc_i2c_request_master(busnum)) + return (GFX_STATUS_ERROR); + + /* WRITE ADDRESS COMMAND */ + + acc_i2c_ack(busnum, 1, 0); + acc_i2c_stall_after_start(busnum, 1); + acc_i2c_send_address(busnum, (unsigned char)(chipadr & 0xFE)); + acc_i2c_stall_after_start(busnum, 0); + if (!acc_i2c_ack(busnum, 0, 0)) + return (GFX_STATUS_ERROR); + + /* WRITE COMMAND */ + + acc_i2c_write_byte(busnum, subadr); + if (!acc_i2c_ack(busnum, 0, 0)) + return (GFX_STATUS_ERROR); + + /* WRITE DATA */ + + for (loop = 0; loop < bytes; loop++) { + acc_i2c_write_byte(busnum, *data); + if (loop < (bytes - 1)) + data += sizeof(unsigned char); + if (!acc_i2c_ack(busnum, 0, 0)) + return (GFX_STATUS_ERROR); + } + data -= (bytes - 1); + acc_i2c_stop(busnum); + + return GFX_STATUS_OK; +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_read + * + * This routine reads data from the specified I2C address. + * busnum - ACCESS.bus number (1 or 2). + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +int +acc_i2c_read(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, unsigned char *data) +#else +int +gfx_i2c_read(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, unsigned char *data) +#endif +{ + unsigned char bytesRead; + + if ((busnum != 1) && (busnum != 2)) + return GFX_STATUS_BAD_PARAMETER; + + if (bytes == 0) + return GFX_STATUS_OK; + + /* REQUEST MASTER */ + + if (!acc_i2c_request_master(busnum)) + return (GFX_STATUS_ERROR); + + /* WRITE ADDRESS COMMAND */ + + acc_i2c_ack(busnum, 1, 0); + acc_i2c_stall_after_start(busnum, 1); + acc_i2c_send_address(busnum, (unsigned char)(chipadr & 0xFE)); + acc_i2c_stall_after_start(busnum, 0); + if (!acc_i2c_ack(busnum, 0, 0)) + return (GFX_STATUS_ERROR); + + /* WRITE COMMAND */ + + acc_i2c_write_byte(busnum, subadr); + if (!acc_i2c_ack(busnum, 0, 0)) + return (GFX_STATUS_ERROR); + + /* START THE READ */ + + acc_i2c_start(busnum); + + /* WRITE ADDRESS COMMAND */ + + acc_i2c_ack(busnum, 1, 1); + acc_i2c_stall_after_start(busnum, 1); + acc_i2c_send_address(busnum, (unsigned char)(chipadr | 0x01)); + + /* IF LAST BYTE */ + + if (bytes == 1) + acc_i2c_ack(busnum, 1, 1); + else + acc_i2c_ack(busnum, 1, 0); + + acc_i2c_stall_after_start(busnum, 0); + + if (!acc_i2c_ack(busnum, 0, 0)) + return (GFX_STATUS_ERROR); + + /* READ COMMAND */ + + for (bytesRead = 0; bytesRead < bytes; bytesRead += 1) { + if (bytesRead < (bytes - 2)) { + data[bytesRead] = acc_i2c_read_byte(busnum, 0); + acc_i2c_ack(busnum, 1, 0); + } else if (bytesRead == (bytes - 2)) { /* TWO BYTES LEFT */ + acc_i2c_ack(busnum, 1, 1); + data[bytesRead] = acc_i2c_read_byte(busnum, 0); + acc_i2c_ack(busnum, 1, 1); + } else { /* LAST BYTE */ + + data[bytesRead] = acc_i2c_read_byte(busnum, 1); + acc_i2c_stop(busnum); + } + + /* WHILE NOT LAST BYTE */ + + if ((!(bytesRead == (bytes - 1))) && (!acc_i2c_ack(busnum, 0, 0))) + return (bytesRead); + } + + return GFX_STATUS_OK; +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_init + * + * This routine initializes the use of the ACCESS.BUS. + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +int +acc_i2c_init(void) +#else +int +gfx_i2c_init(void) +#endif +{ + /* ### ADD ### THIS ROUTINE IS NOT YET IMPLEMENTED FOR ACCESS.bus */ + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_cleanup + * + * This routine ends the use of the ACCESS.BUS. + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +void +acc_i2c_cleanup(void) +#else +void +gfx_i2c_cleanup(void) +#endif +{ + /* ### ADD ### THIS ROUTINE IS NOT YET IMPLEMENTED FOR ACCESS.bus */ +} + +/*--------------------------------------------------------*/ +/* LOCAL ROUTINES SPECIFIC TO ACCESS.bus IMPLEMENTATION */ +/*--------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * acc_i2c_reset_bus + * + * This routine resets the I2C bus. + *--------------------------------------------------------------------------- + */ +void +acc_i2c_reset_bus(unsigned char busnum) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + + /* Disable the ACCESS.bus device and */ + /* Configure the SCL frequency */ + OUTB((unsigned short)(bus_base_address + ACBCTL2), + (unsigned char)(Freq & 0xFE)); + + /* Configure no interrupt mode (polling) and */ + /* Disable global call address */ + OUTB((unsigned short)(bus_base_address + ACBCTL1), 0x0); + + /* Disable slave address */ + OUTB((unsigned short)(bus_base_address + ACBADDR), 0x0); + + /* Enable the ACCESS.bus device */ + reg = INB((unsigned short)(bus_base_address + ACBCTL2)); + reg |= 0x01; + OUTB((unsigned short)(bus_base_address + ACBCTL2), reg); + + /* Issue STOP event */ + + acc_i2c_stop(busnum); + + /* Clear NEGACK, STASTR and BER bits */ + OUTB((unsigned short)(bus_base_address + ACBST), 0x38); + + /* Clear BB (BUS BUSY) bit */ + reg = INB((unsigned short)(bus_base_address + ACBCST)); + reg |= 0x02; + OUTB((unsigned short)(bus_base_address + ACBCST), reg); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_start + * + * This routine starts a transfer on the I2C bus. + *--------------------------------------------------------------------------- + */ +void +acc_i2c_start(unsigned char busnum) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + + reg = INB((unsigned short)(bus_base_address + ACBCTL1)); + reg |= 0x01; + OUTB((unsigned short)(bus_base_address + ACBCTL1), reg); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_stop + * + * This routine stops a transfer on the I2C bus. + *--------------------------------------------------------------------------- + */ +void +acc_i2c_stop(unsigned char busnum) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + + reg = INB((unsigned short)(bus_base_address + ACBCTL1)); + reg |= 0x02; + OUTB((unsigned short)(bus_base_address + ACBCTL1), reg); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_abort_data + *--------------------------------------------------------------------------- + */ +void +acc_i2c_abort_data(unsigned char busnum) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + + acc_i2c_stop(busnum); + reg = INB((unsigned short)(bus_base_address + ACBCTL1)); + reg |= 0x10; + OUTB((unsigned short)(bus_base_address + ACBCTL1), reg); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_bus_recovery + *--------------------------------------------------------------------------- + */ +void +acc_i2c_bus_recovery(unsigned char busnum) +{ + acc_i2c_abort_data(busnum); + acc_i2c_reset_bus(busnum); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_stall_after_start + *--------------------------------------------------------------------------- + */ +void +acc_i2c_stall_after_start(unsigned char busnum, int state) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + + reg = INB((unsigned short)(bus_base_address + ACBCTL1)); + if (state) + reg |= 0x80; + else + reg &= 0x7F; + OUTB((unsigned short)(bus_base_address + ACBCTL1), reg); + + if (!state) { + reg = INB((unsigned short)(bus_base_address + ACBST)); + reg |= 0x08; + OUTB((unsigned short)(bus_base_address + ACBST), reg); + } +} + +/*--------------------------------------------------------------------------- + * acc_i2c_send_address + *--------------------------------------------------------------------------- + */ +void +acc_i2c_send_address(unsigned char busnum, unsigned char cData) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + unsigned long timeout = 0; + + /* WRITE THE DATA */ + + OUTB((unsigned short)(bus_base_address + ACBSDA), cData); + while (1) { + reg = INB((unsigned short)(bus_base_address + ACBST)); + if ((reg & 0x38) != 0) /* check STASTR, BER and NEGACK */ + break; + if (timeout++ == ACC_I2C_TIMEOUT) { + acc_i2c_bus_recovery(busnum); + return; + } + } + + /* CHECK FOR BUS ERROR */ + + if (reg & 0x20) { + acc_i2c_bus_recovery(busnum); + return; + } + + /* CHECK NEGATIVE ACKNOWLEDGE */ + + if (reg & 0x10) { + acc_i2c_abort_data(busnum); + return; + } + +} + +/*--------------------------------------------------------------------------- + * acc_i2c_ack + * + * This routine looks for acknowledge on the I2C bus. + *--------------------------------------------------------------------------- + */ +int +acc_i2c_ack(unsigned char busnum, int fPut, int negAck) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + unsigned long timeout = 0; + + if (fPut) { /* read operation */ + if (!negAck) { + /* Push Ack onto I2C bus */ + reg = INB((unsigned short)(bus_base_address + ACBCTL1)); + reg &= 0xE7; + OUTB((unsigned short)(bus_base_address + ACBCTL1), reg); + } else { + /* Push negAck onto I2C bus */ + reg = INB((unsigned short)(bus_base_address + ACBCTL1)); + reg |= 0x10; + OUTB((unsigned short)(bus_base_address + ACBCTL1), reg); + } + } else { /* write operation */ + /* Receive Ack from I2C bus */ + while (1) { + reg = INB((unsigned short)(bus_base_address + ACBST)); + if ((reg & 0x70) != 0) /* check SDAST, BER and NEGACK */ + break; + if (timeout++ == ACC_I2C_TIMEOUT) { + acc_i2c_bus_recovery(busnum); + return (0); + } + } + + /* CHECK FOR BUS ERROR */ + + if (reg & 0x20) { + acc_i2c_bus_recovery(busnum); + return (0); + } + + /* CHECK NEGATIVE ACKNOWLEDGE */ + + if (reg & 0x10) { + acc_i2c_abort_data(busnum); + return (0); + } + } + return (1); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_stop_clock + * + * This routine stops the ACCESS.bus clock. + *--------------------------------------------------------------------------- + */ +void +acc_i2c_stop_clock(unsigned char busnum) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + + reg = INB((unsigned short)(bus_base_address + ACBCTL2)); + reg &= ~0x01; + OUTB((unsigned short)(bus_base_address + ACBCTL2), reg); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_activate_clock + * + * This routine activates the ACCESS.bus clock. + *--------------------------------------------------------------------------- + */ +void +acc_i2c_activate_clock(unsigned char busnum) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + + reg = INB((unsigned short)(bus_base_address + ACBCTL2)); + reg |= 0x01; + OUTB((unsigned short)(bus_base_address + ACBCTL2), reg); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_write_byte + * + * This routine writes a byte to the I2C bus + *--------------------------------------------------------------------------- + */ +void +acc_i2c_write_byte(unsigned char busnum, unsigned char cData) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + unsigned long timeout = 0; + + while (1) { + reg = INB((unsigned short)(bus_base_address + ACBST)); + if (reg & 0x70) + break; + if (timeout++ == ACC_I2C_TIMEOUT) { + acc_i2c_bus_recovery(busnum); + return; + } + } + + /* CHECK FOR BUS ERROR */ + + if (reg & 0x20) { + acc_i2c_bus_recovery(busnum); + return; + } + + /* CHECK NEGATIVE ACKNOWLEDGE */ + + if (reg & 0x10) { + acc_i2c_abort_data(busnum); + return; + } + + /* WRITE THE DATA */ + + OUTB((unsigned short)(bus_base_address + ACBSDA), cData); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_read_byte + * + * This routine reads a byte from the I2C bus + *--------------------------------------------------------------------------- + */ +unsigned char +acc_i2c_read_byte(unsigned char busnum, int last_byte) +{ + unsigned char cData, reg; + unsigned short bus_base_address = base_address_array[busnum]; + unsigned long timeout = 0; + + while (1) { + reg = INB((unsigned short)(bus_base_address + ACBST)); + if (reg & 0x60) + break; + if (timeout++ == ACC_I2C_TIMEOUT) { + acc_i2c_bus_recovery(busnum); + return (0xEF); + } + } + + /* CHECK FOR BUS ERROR */ + + if (reg & 0x20) { + acc_i2c_bus_recovery(busnum); + return (0xEE); + } + + /* READ DATA */ + if (last_byte) + acc_i2c_stop_clock(busnum); + cData = INB((unsigned short)(bus_base_address + ACBSDA)); + if (last_byte) + acc_i2c_activate_clock(busnum); + + return (cData); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_request_master + *--------------------------------------------------------------------------- + */ +int +acc_i2c_request_master(unsigned char busnum) +{ + unsigned char reg; + unsigned short bus_base_address = base_address_array[busnum]; + unsigned long timeout = 0; + + acc_i2c_start(busnum); + while (1) { + reg = INB((unsigned short)(bus_base_address + ACBST)); + if (reg & 0x60) + break; + if (timeout++ == ACC_I2C_TIMEOUT) { + acc_i2c_bus_recovery(busnum); + return (0); + } + } + + /* CHECK FOR BUS ERROR */ + + if (reg & 0x20) { + acc_i2c_abort_data(busnum); + return (0); + } + + /* CHECK NEGATIVE ACKNOWLEDGE */ + + if (reg & 0x10) { + acc_i2c_abort_data(busnum); + return (0); + } + return (1); +} + +/*--------------------------------------------------------*/ +/* LOCAL ROUTINES SPECIFIC TO ACCESS.bus INITIALIZATION */ +/*--------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * acc_i2c_config + * + * This routine configures the I2C bus + *---------------------------------------------------------------------------- + */ +void +acc_i2c_config(unsigned char busnum, short adr, char freq) +{ + base_address_array[busnum] = acc_i2c_set_base_address(busnum, adr); + Freq = acc_i2c_set_freq(busnum, freq); +} + +/*---------------------------------------------------------------------------- + * acc_i2c_set_freq + * + * This routine sets the frequency of the I2C bus + *---------------------------------------------------------------------------- + */ +char +acc_i2c_set_freq(unsigned char busnum, char freq) +{ + unsigned short bus_base_address = base_address_array[busnum]; + + OUTB((unsigned short)(bus_base_address + ACBCTL2), 0x0); + + if (freq == -1) + freq = 0x71; + else { + freq = freq << 1; + freq |= 0x01; + } + + OUTB((unsigned short)(bus_base_address + ACBCTL2), freq); + return (freq); +} + +/*--------------------------------------------------------------------------- + * acc_i2c_set_base_address + * + * This routine sets the base address of the I2C bus + *--------------------------------------------------------------------------- + */ +unsigned short +acc_i2c_set_base_address(unsigned char busnum, short adr) +{ + unsigned short ab_base_addr; + + /* Get Super I/O Index and Data registers */ + if (!sio_set_index_data_reg()) + return (0); + + /* Configure LDN to current ACB */ + if (busnum == 1) + sio_write_reg(LDN, ACB1_LDN); + if (busnum == 2) + sio_write_reg(LDN, ACB2_LDN); + + if (adr == -1) { + /* Get ACCESS.bus base address */ + ab_base_addr = sio_read_reg(BASE_ADR_MSB_REG); + ab_base_addr = ab_base_addr << 8; + ab_base_addr |= sio_read_reg(BASE_ADR_LSB_REG); + if (ab_base_addr != 0) + return ab_base_addr; + else + adr = (busnum == 1 ? ACB1_BASE : ACB2_BASE); + } + + /* Set ACCESS.bus base address */ + sio_write_reg(BASE_ADR_LSB_REG, (unsigned char)(adr & 0xFF)); + sio_write_reg(BASE_ADR_MSB_REG, (unsigned char)(adr >> 8)); + + return adr; +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/i2c_gpio.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/i2c_gpio.c new file mode 100644 index 000000000..096750d51 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/i2c_gpio.c @@ -0,0 +1,749 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/i2c_gpio.c,v 1.1 2002/12/10 15:12:26 alanh Exp $ */ +/* + * $Workfile: i2c_gpio.c $ + * + * This file contains routines to write to and read from the I2C bus using + * the GPIO pins of the CS5530. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* STATIC VARIABLES TO STORE WHAT GPIO PINS TO USE */ + +int gpio_clock = 0; +int gpio_data = 0; + +static int g_initialized = 0; + +#define I2CWRITE 0x00 /* Write address */ +#define I2CREAD 0x01 /* Read address */ + +#define I2CACK 0x00 /* Ack value */ +#define I2CNACK 0x01 /* Not - ack value */ + +#define CS5530_ID (0x80000000 | (0x00<<16) | (0x12<<11) | (0<<8) | 0x00) +#define CS5530_GPIO (0x80000000 | (0x00<<16) | (0x12<<11) | (0<<8) | 0x90) +#define SDA 0x0800 +#define SCL 0x0400 +#define SDADIR 0x0008 +#define SCLDIR 0x0004 + +int I2C_init(void); +void I2C_cleanup(void); + +int I2C_Read(unsigned char address, unsigned int reg, unsigned long *p_value, + unsigned int bytes); +int I2C_Write(unsigned char address, unsigned int reg, unsigned long value, + unsigned int bytes); +int I2CAL_init(void); +void I2CAL_cleanup(void); + +void I2CAL_output_clock(int state); +void I2CAL_output_data(int state); +unsigned char I2CAL_input_data(void); + +void I2CAL_set_data_for_input(void); +void I2CAL_set_data_for_output(void); + +void SendI2CStart(void); +void SendI2CData(unsigned char inData); + +unsigned char ReceiveI2CAck(void); +void SendI2CStop(void); +void SendI2CNack(void); +void SendI2CAck(void); +unsigned char ReceiveI2CData(void); + +int gpio_i2c_reset(unsigned char busnum, short adr, char freq); +int gpio_i2c_write(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, + unsigned char *data); +int gpio_i2c_read(unsigned char busnum, unsigned char chipadr, + unsigned char subadr, unsigned char bytes, + unsigned char *data); +int gpio_i2c_select_gpio(int clock, int data); +int gpio_i2c_init(void); +void gpio_i2c_cleanup(void); + +/* ### ADD ### ANY LOCAL ROUTINE DEFINITIONS SPECIFIC TO GPIO */ + +/*--------------------------------------------------------------------------- + * gfx_i2c_reset + * + * This routine resets the I2C bus. + *--------------------------------------------------------------------------- + */ + +#if GFX_I2C_DYNAMIC +int +gpio_i2c_reset(unsigned char busnum, short adr, char freq) +#else +int +gfx_i2c_reset(unsigned char busnum, short adr, char freq) +#endif +{ + /* ### ADD ### Any code needed to reset the state of the GPIOs. */ + return GFX_STATUS_OK; +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_select_gpio + * + * This routine selects which GPIO pins to use. + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +int +gpio_i2c_select_gpio(int clock, int data) +#else +int +gfx_i2c_select_gpio(int clock, int data) +#endif +{ + gpio_clock = clock; + gpio_data = data; + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_write + * + * This routine writes data to the specified I2C address. + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +int +gpio_i2c_write(unsigned char busnum, unsigned char address, unsigned char reg, + unsigned char bytes, unsigned char *value) +#else +int +gfx_i2c_write(unsigned char busnum, unsigned char address, unsigned char reg, + unsigned char bytes, unsigned char *value) +#endif +{ + /* ### ADD ### CODE TO WRITE BYTE TO I2B BUS */ + + int restart_count = 0; + + while (restart_count++ < 5) { + /* set the access pointer register. */ + /* The address is shifted left by one to make room for Read/Write bit */ + SendI2CStart(); + SendI2CData((char)((address << 1) | I2CWRITE)); + if (!ReceiveI2CAck()) { + SendI2CStop(); + gfx_delay_milliseconds(10); + continue; + } + SendI2CData((unsigned char)reg); + if (!ReceiveI2CAck()) { + SendI2CStop(); + gfx_delay_milliseconds(10); + continue; + } + + /* write the first byte */ + SendI2CData(*value); + if (!ReceiveI2CAck()) { + SendI2CStop(); + gfx_delay_milliseconds(10); + continue; + } + + /* write the second byte. */ + if (bytes == 2) { + SendI2CData(*(value + 1)); + if (!ReceiveI2CAck()) { + SendI2CStop(); + gfx_delay_milliseconds(10); + continue; + } + } + + /* done. */ + SendI2CStop(); + + return 0; + } + + return (0); + +} + +/*--------------------------------------------------------------------------- + * gfx_i2c_read + * + * This routine reads data from the specified I2C address. + *--------------------------------------------------------------------------- + */ +#if GFX_I2C_DYNAMIC +int +gpio_i2c_read(unsigned char busnum, unsigned char address, unsigned char reg, + unsigned char bytes, unsigned char *p_value) +#else +int +gfx_i2c_read(unsigned char busnum, unsigned char address, unsigned char reg, + unsigned char bytes, unsigned char *p_value) +#endif +{ + /* ### ADD ### CODE TO WRITE BYTE TO I2B BUS */ + /* For now return clock and data pins */ + + int restart_count = 0; + + if (!p_value) + return (1); + + while (restart_count++ < 5) { + /* set the access pointer register. */ + /* The address is shifted left by one to make room for Read/Write bit */ + SendI2CStart(); + SendI2CData((char)((address << 1) | I2CWRITE)); + if (!ReceiveI2CAck()) { + SendI2CStop(); + gfx_delay_milliseconds(10); + continue; + } + SendI2CData((unsigned char)(reg & 0xFF)); + SendI2CNack(); + + /* read the first data byte. */ + SendI2CStart(); + SendI2CData((char)((address << 1) | I2CREAD)); + if (!ReceiveI2CAck()) { + SendI2CStop(); + gfx_delay_milliseconds(10); + continue; + } + *p_value = ReceiveI2CData(); + + /* read the second byte. */ + if (bytes == 2) { + SendI2CAck(); + *(p_value + 1) = ReceiveI2CData(); + } + + /* done. */ + SendI2CNack(); + SendI2CStop(); + + return 0; + } + + return (1); +} + +/* Added i2c/gpio code to test fs451 chip. */ + +/* +//---------------------------------------------------------------------- +// +// void SendI2CStart(void) +// +// Sends an I2C start signal on the bus. +// +//---------------------------------------------------------------------- +*/ +void +SendI2CStart(void) +{ + I2CAL_output_data(1); + I2CAL_output_clock(1); + I2CAL_output_data(0); + I2CAL_output_clock(0); +} + +/* +//---------------------------------------------------------------------- +// +// void SendI2CStop(void) +// +// Sends an I2C stop signal on the bus. +// +//---------------------------------------------------------------------- +*/ +void +SendI2CStop(void) +{ + I2CAL_output_data(0); + I2CAL_output_clock(1); + I2CAL_output_data(1); +} + +/* +//---------------------------------------------------------------------- +// +// void SendI2CAck(void) +// +// Sends the Ack signal on the I2C bus. +// +//---------------------------------------------------------------------- +*/ +void +SendI2CAck(void) +{ + I2CAL_output_data(0); + I2CAL_output_clock(1); + I2CAL_output_clock(0); +} + +/* +//---------------------------------------------------------------------- +// +// void SendI2CNack(void) +// +// Sends the Nt-Ack signal on the I2C bus. +// +//---------------------------------------------------------------------- +*/ +void +SendI2CNack(void) +{ + I2CAL_output_data(1); + I2CAL_output_clock(1); + I2CAL_output_clock(0); +} + +/* +//---------------------------------------------------------------------- +// +// UInt8 SendI2CData( UInt8 inData ) +// +// Sends a byte of data on the I2C bus and returns the TRUE if the slave ACK'd +// the data. +// +// Input: inData - the byte of data to send +// Output: (return) - TRUE (1) if ACK was received, FALSE (0) if not +// +//---------------------------------------------------------------------- +*/ +void +SendI2CData(unsigned char inData) +{ + unsigned char bit; + + /* Send all 8 bits of data byte, MSB to LSB */ + for (bit = 0x80; bit != 0; bit >>= 1) { + if (inData & bit) + I2CAL_output_data(1); + else + I2CAL_output_data(0); + + I2CAL_output_clock(1); + I2CAL_output_clock(0); + } +} + +/* +//---------------------------------------------------------------------- +// +// UInt8 ReceiveI2CAck( ) +// +// Receives the Ack (or Nack) from the slave. +// +// Output: (return) - TRUE (1) if ACK was received, FALSE (0) if not +// +//---------------------------------------------------------------------- +*/ +unsigned char +ReceiveI2CAck(void) +{ + unsigned char bit; + + /* Test for Ack/Nack */ + I2CAL_set_data_for_input(); + I2CAL_output_data(1); + I2CAL_output_clock(1); + bit = I2CAL_input_data(); + I2CAL_output_clock(0); + I2CAL_set_data_for_output(); + return !bit; +} + +/* +//---------------------------------------------------------------------- +// +// unsigned char ReceiveI2CData(void) +// +// Receives a byte of data from the I2C bus. +// +// Output: (return) - The data byte recehved from the bus +// +//---------------------------------------------------------------------- +*/ +unsigned char +ReceiveI2CData(void) +{ + unsigned char data = 0; + unsigned char x; + + /* make sure the data line is released */ + I2CAL_set_data_for_input(); + I2CAL_output_data(1); + + /* shift in the data */ + for (x = 0; x < 8; x++) { + /* shift the data left */ + I2CAL_output_clock(1); + data <<= 1; + data |= I2CAL_input_data(); + I2CAL_output_clock(0); + } + + I2CAL_set_data_for_output(); + I2CAL_output_data(1); + return data; +} + +/* +//---------------------------------------------------------------------- +// +// void I2C_init(void) +// +// This routine initializes the I2C interface. Clients of the I2C.c +// will call this routine before calling any other routine in the I2C.c +// +//---------------------------------------------------------------------- +*/ + +#if GFX_I2C_DYNAMIC +int +gpio_i2c_init(void) +#else +int +gfx_i2c_init(void) +#endif +{ + int errc; + + /* init I2CAL */ + errc = I2CAL_init(); + if (errc) + return errc; + + /* set the clock and data lines to the proper states */ + I2CAL_output_clock(1); + I2CAL_output_data(1); + I2CAL_set_data_for_output(); + + SendI2CStart(); + SendI2CStop(); + SendI2CStop(); + + g_initialized = 1; + + return 0; +} + +/* +//---------------------------------------------------------------------- +// +// void I2C_cleanup(void) +// +// This routine disables the I2C interface. Clients of the I2C.c will not +// call any other I2C routine after calling this routine. +// +//---------------------------------------------------------------------- +*/ + +#if GFX_I2C_DYNAMIC +void +gpio_i2c_cleanup(void) +#else +void +gfx_i2c_cleanup(void) +#endif +{ + if (g_initialized) { + + /* set the clock and data lines to a harmless state */ + I2CAL_output_clock(1); + I2CAL_output_data(1); + + g_initialized = 0; + } + + I2CAL_cleanup(); +} + +int +I2CAL_init(void) +{ + unsigned long l_reg; + unsigned short reg; + + /* initialize the i2c port. */ + l_reg = gfx_pci_config_read(CS5530_GPIO); + + if (l_reg != 0x01001078) + return 1; + + l_reg = gfx_pci_config_read(CS5530_GPIO); + reg = (unsigned short)l_reg; + + /* both outputs, both high. */ + reg |= (SDADIR | SCLDIR | SDA | SCL); + l_reg = reg; + gfx_pci_config_write(CS5530_GPIO, l_reg); + + g_initialized = 1; + + return 0; +} + +void +I2CAL_cleanup(void) +{ + if (g_initialized) { + + g_initialized = 0; + } +} + +/* +//-------------------------------------------------------------------------------- +// +// set the I2C clock line state +// +//-------------------------------------------------------------------------------- +*/ +void +I2CAL_output_clock(int inState) +{ + unsigned short reg; + unsigned long value; + + value = gfx_pci_config_read(CS5530_GPIO); + reg = (unsigned short)value; + + if (inState) { /* write a 1. */ + reg |= SCL; + } else { /* write a 0. */ + reg &= ~SCL; + } + + value = reg; + gfx_pci_config_write(CS5530_GPIO, value); + + /* hold it for a minimum of 4.7us */ + gfx_delay_microseconds(5); +} + +/* +//-------------------------------------------------------------------------------- +// +// set the I2C data line state +// +//-------------------------------------------------------------------------------- +*/ +void +I2CAL_output_data(int inState) +{ + unsigned short reg; + unsigned long value; + + value = gfx_pci_config_read(CS5530_GPIO); + reg = (unsigned short)value; + + if (inState) { /* write a 1. */ + reg |= SDA; + } else { + /* write a 0. */ + reg &= ~SDA; + } + value = reg; + gfx_pci_config_write(CS5530_GPIO, value); + + /* 250 ns setup time */ + gfx_delay_microseconds(1); +} + +/* +//-------------------------------------------------------------------------------- +// +// read the state of the data line +// +//-------------------------------------------------------------------------------- +*/ +unsigned char +I2CAL_input_data(void) +{ + unsigned short reg; + unsigned long value; + + value = gfx_pci_config_read(CS5530_GPIO); + reg = (unsigned short)value; + + if (reg & SDA) + return 1; + else + return 0; +} + +/* +//-------------------------------------------------------------------------------- +// +// set the I2C data for input mode +// +//-------------------------------------------------------------------------------- +*/ +void +I2CAL_set_data_for_input(void) +{ + unsigned short reg; + unsigned long value; + + value = gfx_pci_config_read(CS5530_GPIO); + reg = (unsigned short)value; + + reg &= ~SDADIR; + + value = reg; + + gfx_pci_config_write(CS5530_GPIO, value); +} + +/* +//-------------------------------------------------------------------------------- +// +// set the I2C data for output mode +// +//-------------------------------------------------------------------------------- +*/ +void +I2CAL_set_data_for_output(void) +{ + unsigned short reg; + unsigned long value; + + value = gfx_pci_config_read(CS5530_GPIO); + reg = (unsigned short)value; + reg |= SDADIR; + value = reg; + + gfx_pci_config_write(CS5530_GPIO, value); + +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/init_gu1.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/init_gu1.c new file mode 100644 index 000000000..09fb79cba --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/init_gu1.c @@ -0,0 +1,363 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/init_gu1.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: init_gu1.c $ + * + * This file contains routines used in the initialization of Geode-family + * processors. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +unsigned char gfx_gxm_config_read(unsigned char index); +unsigned long gu1_get_core_freq(void); +unsigned long gu1_detect_cpu(void); +unsigned long gu1_detect_video(void); +unsigned long gu1_get_cpu_register_base(void); +unsigned long gu1_get_graphics_register_base(void); +unsigned long gu1_get_frame_buffer_base(void); +unsigned long gu1_get_frame_buffer_size(void); +unsigned long gu1_get_vid_register_base(void); +unsigned long gu1_get_vip_register_base(void); + +/*----------------------------------------------------------------------------- + * gfx_gxm_config_read + * + * This routine reads the value of the specified GXm configuration register. + *----------------------------------------------------------------------------- + */ +unsigned char +gfx_gxm_config_read(unsigned char index) +{ + unsigned char value = 0xFF; + unsigned char lock; + + OUTB(0x22, GXM_CONFIG_CCR3); + lock = INB(0x23); + OUTB(0x22, GXM_CONFIG_CCR3); + OUTB(0x23, (unsigned char)(lock | 0x10)); + OUTB(0x22, index); + value = INB(0x23); + OUTB(0x22, GXM_CONFIG_CCR3); + OUTB(0x23, lock); + return (value); +} + +/*----------------------------------------------------------------------------- + * gfx_get_core_freq + * + * This routine returns the core clock frequency of a GXm if valid jumper settings are + * detected; 0 if not. It assumes that a 33.3 MHz PCI clock is being used. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu1_get_core_freq(void) +#else +unsigned long +gfx_get_core_freq(void) +#endif +{ + unsigned char dir0, dir1; + + dir0 = gfx_gxm_config_read(GXM_CONFIG_DIR0) & 0x0F; + dir1 = gfx_gxm_config_read(GXM_CONFIG_DIR1); + + /* REVISION 4.0 AND UP */ + + if (dir1 >= 0x50) { + switch (dir0) { + case 0: + case 2: + return 133; + + case 5: + return 166; + case 3: + return 200; + case 6: + return 233; + case 7: + return 266; + case 4: + return 300; + case 1: + return 333; + default: + return (0); + } + } else { + switch (dir0) { + case 0: + case 2: + return 133; + + case 7: + return 166; + + case 1: + case 3: + return 200; + + case 4: + case 6: + return 233; + + case 5: + return 266; + default: + return (0); + } + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cpu_register_base + * + * This routine returns the base address for graphics registers. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu1_get_cpu_register_base(void) +#else +unsigned long +gfx_get_cpu_register_base(void) +#endif +{ + unsigned long base; + + base = (unsigned long)gfx_gxm_config_read(GXM_CONFIG_GCR); + base = (base & 0x03) << 30; + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_frame_buffer_base + * + * This routine returns the base address for graphics memory. This is an + * offset of 0x00800000 from the base address specified in the GCR register. + * + * The function returns zero if the GCR indicates the graphics subsystem + * is disabled. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu1_get_frame_buffer_base(void) +#else +unsigned long +gfx_get_frame_buffer_base(void) +#endif +{ + unsigned long base; + + base = (unsigned long)gfx_gxm_config_read(GXM_CONFIG_GCR); + base = (base & 0x03) << 30; + if (base) + base |= 0x00800000; + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_frame_buffer_size + * + * This routine returns the total size of graphics memory, in bytes. + * + * Currently this routine is hardcoded to return 2 Meg. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu1_get_frame_buffer_size(void) +#else +unsigned long +gfx_get_frame_buffer_size(void) +#endif +{ +#if FB4MB + return (0x00400000); +#else + return (0x00200000); +#endif +} + +/*----------------------------------------------------------------------------- + * gfx_get_vid_register_base + * + * This routine returns the base address for the video hardware. It assumes + * an offset of 0x00010000 from the base address specified by the GCR. + * + * The function returns zero if the GCR indicates the graphics subsystem + * is disabled. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu1_get_vid_register_base(void) +#else +unsigned long +gfx_get_vid_register_base(void) +#endif +{ + unsigned long base; + + base = (unsigned long)gfx_gxm_config_read(GXM_CONFIG_GCR); + base = (base & 0x03) << 30; + if (base) + base |= 0x00010000; + return (base); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_register_base + * + * This routine returns the base address for the VIP hardware. This is + * only applicable to the SC1200, for which this routine assumes an offset + * of 0x00015000 from the base address specified by the GCR. + * + * The function returns zero if the GCR indicates the graphics subsystem + * is disabled. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu1_get_vip_register_base(void) +#else +unsigned long +gfx_get_vip_register_base(void) +#endif +{ + unsigned long base = 0; + + if ((gfx_cpu_version & 0xFF) == GFX_CPU_SC1200) { + base = (unsigned long)gfx_gxm_config_read(GXM_CONFIG_GCR); + base = (base & 0x03) << 30; + if (base) + base |= 0x00015000; + } + return (base); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/init_gu2.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/init_gu2.c new file mode 100644 index 000000000..143ce5207 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/init_gu2.c @@ -0,0 +1,267 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/init_gu2.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: init_gu2.c $ + * + * This file contains routines used in Redcloud initialization. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +unsigned long gu2_pci_config_read(unsigned long address); +void gu2_pci_config_write(unsigned long address, unsigned long data); +unsigned long gu2_get_core_freq(void); +unsigned long gu2_detect_cpu(void); +unsigned long gu2_detect_video(void); +unsigned long gu2_get_cpu_register_base(void); +unsigned long gu2_get_graphics_register_base(void); +unsigned long gu2_get_frame_buffer_base(void); +unsigned long gu2_get_frame_buffer_size(void); +unsigned long gu2_get_vid_register_base(void); +unsigned long gu2_get_vip_register_base(void); + +/*----------------------------------------------------------------------------- + * gfx_get_core_freq + * + * Returns the core clock frequency of a GX2. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu2_get_core_freq(void) +#else +unsigned long +gfx_get_core_freq(void) +#endif +{ + unsigned long value; + + /* CPU SPEED IS REPORTED BY A VSM IN VSA II */ + /* Virtual Register Class = 0x12 (Sysinfo) */ + /* CPU Speed Register = 0x01 */ + + OUTW(0xAC1C, 0xFC53); + OUTW(0xAC1C, 0x1201); + + value = (unsigned long)(INW(0xAC1E)); + + return (value); +} + +/*----------------------------------------------------------------------------- + * gfx_get_cpu_register_base + * + * This routine returns the base address for display controller registers. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu2_get_cpu_register_base(void) +#else +unsigned long +gfx_get_cpu_register_base(void) +#endif +{ + return gfx_pci_config_read(0x80000918); +} + +/*----------------------------------------------------------------------------- + * gfx_get_graphics_register_base + * + * This routine returns the base address for the graphics acceleration. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu2_get_graphics_register_base(void) +#else +unsigned long +gfx_get_graphics_register_base(void) +#endif +{ + return gfx_pci_config_read(0x80000914); +} + +/*----------------------------------------------------------------------------- + * gfx_get_frame_buffer_base + * + * This routine returns the base address for graphics memory. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu2_get_frame_buffer_base(void) +#else +unsigned long +gfx_get_frame_buffer_base(void) +#endif +{ + return gfx_pci_config_read(0x80000910); +} + +/*----------------------------------------------------------------------------- + * gfx_get_frame_buffer_size + * + * This routine returns the total size of graphics memory, in bytes. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu2_get_frame_buffer_size(void) +#else +unsigned long +gfx_get_frame_buffer_size(void) +#endif +{ + unsigned long value; + + /* FRAME BUFFER SIZE IS REPORTED BY A VSM IN VSA II */ + /* Virtual Register Class = 0x02 */ + /* VG_MEM_SIZE (512KB units) = 0x00 */ + + OUTW(0xAC1C, 0xFC53); + OUTW(0xAC1C, 0x0200); + + value = (unsigned long)(INW(0xAC1E)) & 0xFFl; + + return (value << 19); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vid_register_base + * + * This routine returns the base address for the video hardware. + *----------------------------------------------------------------------------- + */ +#if GFX_INIT_DYNAMIC +unsigned long +gu2_get_vid_register_base(void) +#else +unsigned long +gfx_get_vid_register_base(void) +#endif +{ + return gfx_pci_config_read(0x8000091C); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/msr_rdcl.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/msr_rdcl.c new file mode 100644 index 000000000..ce3ce05dc --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/msr_rdcl.c @@ -0,0 +1,729 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/msr_rdcl.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: msr_rdcl.c $ + * + * This file contains MSR access routines for Redcloud. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +int redcloud_msr_init(void); +DEV_STATUS redcloud_id_msr_device(MSR * pDev, unsigned long address); +DEV_STATUS redcloud_get_msr_dev_address(unsigned int device, + unsigned long *address); +DEV_STATUS redcloud_get_glink_id_at_address(unsigned int *device, + unsigned long address); +DEV_STATUS redcloud_msr_read(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue); +DEV_STATUS redcloud_msr_write(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue); + +void redcloud_build_mbus_tree(void); /* private routine definition */ +int redcloud_init_msr_devices(MSR aDev[], unsigned int array_size); /* private routine definition */ +DEV_STATUS redcloud_find_msr_device(MSR * pDev); /* private routine definition */ + +/* REDCLOUD MSR BITMASKS */ + +#define MBD_MSR_CAP 0x2000 +#define MSR_CAP_ID_MASK 0xFF000 +#define MSR_CAP_ID_SHIFT 12 +#define MSR_CAP_REV_MASK 0x0F +#define MBIU_CAP 0x86 +#define NUM_PORTS_MASK 0x00380000 +#define NUM_PORTS_SHIFT 19 +#define MBIU_WHOAMI 0x8B +#define WHOAMI_MASK 0x07 + +/* REDCLOUD and CS5535 MSR DEVICES */ + +MSR msrDev[] = { + {FOUND, RC_CC_MBIU, RC_MB0_MBIU0}, + {FOUND, RC_CC_MBIU, RC_MB0_MBIU1}, + {NOT_KNOWN, RC_CC_MCP, FAKE_ADDRESS}, + {NOT_KNOWN, RC_CC_MPCI, FAKE_ADDRESS}, + {NOT_KNOWN, RC_CC_MC, FAKE_ADDRESS}, + {NOT_KNOWN, RC_CC_GP, FAKE_ADDRESS}, + {NOT_KNOWN, RC_CC_VG, FAKE_ADDRESS}, + {NOT_KNOWN, RC_CC_DF, FAKE_ADDRESS}, + {NOT_KNOWN, RC_CC_FG, FAKE_ADDRESS}, + {FOUND, RC_CC_VA, RC_MB0_CPU}, + {FOUND, CP_CC_MBIU, CP_MB0_MBIU0}, + {NOT_KNOWN, CP_CC_MPCI, FAKE_ADDRESS}, + {NOT_KNOWN, CP_CC_USB2, FAKE_ADDRESS}, + {NOT_KNOWN, CP_CC_ATAC, FAKE_ADDRESS}, + {NOT_KNOWN, CP_CC_MDD, FAKE_ADDRESS}, + {NOT_KNOWN, CP_CC_ACC, FAKE_ADDRESS}, + {NOT_KNOWN, CP_CC_USB1, FAKE_ADDRESS}, + {NOT_KNOWN, CP_CC_MCP, FAKE_ADDRESS}, +}; + +#define NUM_DEVS sizeof(msrDev) / sizeof(struct msr) + +/* CAPISTRANO DEVICE INDEX LIMITS */ +/* These defines represent the start and stop indexes into the device array */ +/* for all Capistrano devices. These should be updated whenever a device is */ +/* added or removed to the Capistrano list. */ + +#define CP_INDEX_START CP_ID_MBIU +#define CP_INDEX_STOP CP_ID_MCP + +/* GLOBAL MBUS CACHE STRUCTURES */ +/* These structures contain a "cached" copy of the MBUS topology */ +/* for easy future lookup. */ + +MBUS_NODE MBIU0[8], MBIU1[8], MBIU2[8]; + +/* REGISTER MACROS */ + +#define GET_DEVICE_ID( CAPABILITIES_HIGH, CAPABILITIES_LOW ) \ + ((unsigned int)(( (CAPABILITIES_LOW) & MSR_CAP_ID_MASK ) >> MSR_CAP_ID_SHIFT )) + +#define GET_NUM_PORTS( MBIU_CAP_HIGH, MBIU_CAP_LOW ) (((MBIU_CAP_HIGH) & NUM_PORTS_MASK ) >> NUM_PORTS_SHIFT) + +/*----------------------------------------------------------------------------- + * gfx_msr_init + * + * This routine initializes the base addresses of all known MBUS devices. + *----------------------------------------------------------------------------- + */ +#if GFX_MSR_DYNAMIC +int +redcloud_msr_init(void) +#else +int +gfx_msr_init(void) +#endif +{ + Q_WORD msrValue; + int return_value = 1; + + /* CHECK FOR VALID MBUS CONFIGURATION */ + /* The CPU and the two MBIUs are assumed to be at known static addresses, so */ + /* we will check the device IDs at these addresses as proof of a valid mbus */ + /* configuration. */ + + MSR_READ(MBD_MSR_CAP, RC_MB0_CPU, &(msrValue.high), &(msrValue.low)); + if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_VA) + return_value = 0; + + MSR_READ(MBD_MSR_CAP, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low)); + if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_MBIU) + return_value = 0; + + MSR_READ(MBD_MSR_CAP, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low)); + if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_MBIU) + return_value = 0; + + /* ENUMERATE VALID BUS */ + /* If all static devices were identified, continue with the enumeration */ + + if (return_value) { + /* OPTIMIZATION */ + /* Build a local copy of the MBUS topology. This allows us to */ + /* quickly search the entire MBUS for a given device ID without */ + /* repeated MSR accesses. */ + + redcloud_build_mbus_tree(); + + /* INITIALIZE MSR DEVICES */ + + return_value = redcloud_init_msr_devices(msrDev, NUM_DEVS); + + } + + return return_value; + +} + +/*-------------------------------------------------------------------------- + * void redcloud_build_mbus_tree() (PRIVATE ROUTINE - NOT PART OF DURANGO API) + * + * This routine walks through the MBUS and records the address value and + * device ID found at each node. If a node (aka port) is not populated, + * that node returns '0'. The deviceID for that node is set to '0' + * (NOT_POPULATED) to reflect this. If the node being queried points back to + * Vail or MBIU0, the deviceID for that node is set to 'REFLECTIVE'. Reflective + * nodes are nodes that forward the given MBUS address BACK to the initiator. + *----------------------------------------------------------------------------- + */ +void +redcloud_build_mbus_tree(void) +{ + unsigned long mbiu_port_count, reflective; + unsigned long port; + Q_WORD msrValue; + + /* */ + /* ENUMERATE MBIU0 */ + /* */ + + /* COUNT MBIU PORTS */ + + MSR_READ(MBIU_CAP, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low)); + mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low); + + /* FIND REFLECTIVE PORT */ + /* Query the MBIU for the port through which we are communicating. */ + /* We will avoid accesses to this port to avoid a self-reference. */ + + MSR_READ(MBIU_WHOAMI, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low)); + reflective = msrValue.low & WHOAMI_MASK; + + /* ENUMERATE ALL PORTS */ + /* For every possible port, set the MBIU.deviceId to something. */ + + for (port = 0; port < 8; port++) { + /* FILL IN CLAIMED FIELD */ + /* All MBIU ports can only be assigned to one device from the */ + /* Durango table */ + + MBIU0[port].claimed = 0; + + /* MBIU0 PORT NUMBERS ARE IN ADDRESS BITS 31:29 */ + + MBIU0[port].address = port << 29; + + /* SPECIAL CASE FOR MBIU0 */ + /* MBIU0 port 0 is a special case, as it points back to MBIU0. MBIU0 */ + /* responds at address 0x40000xxx, which does not equal 0 << 29. */ + + if (port == 0) + MBIU0[port].deviceId = RC_CC_MBIU; + else if (port == reflective) + MBIU0[port].deviceId = REFLECTIVE; + else if (port > mbiu_port_count) + MBIU0[port].deviceId = NOT_POPULATED; + else { + MSR_READ(MBD_MSR_CAP, MBIU0[port].address, &(msrValue.high), + &(msrValue.low)); + MBIU0[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low); + } + } + + /* */ + /* ENUMERATE MBIU1 */ + /* */ + + /* COUNT MBIU PORTS */ + + MSR_READ(MBIU_CAP, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low)); + mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low); + + /* FIND REFLECTIVE PORT */ + /* Query the MBIU for the port through which we are communicating. */ + /* We will avoid accesses to this port to avoid a self-reference. */ + + MSR_READ(MBIU_WHOAMI, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low)); + reflective = msrValue.low & WHOAMI_MASK; + + /* ENUMERATE ALL PORTS */ + /* For every possible port, set the MBIU.deviceId to something. */ + + for (port = 0; port < 8; port++) { + /* FILL IN CLAIMED FIELD */ + /* All MBIU ports can only be assigned to one device from the */ + /* Durango table */ + + MBIU1[port].claimed = 0; + + /* MBIU1 PORT NUMBERS ARE IN 28:26 AND 31:29 = 010B */ + + MBIU1[port].address = (0x02l << 29) + (port << 26); + + if (port == reflective) + MBIU1[port].deviceId = REFLECTIVE; + else if (port > mbiu_port_count) + MBIU1[port].deviceId = NOT_POPULATED; + else { + MSR_READ(MBD_MSR_CAP, MBIU1[port].address, &(msrValue.high), + &(msrValue.low)); + MBIU1[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low); + } + } + + /* */ + /* ENUMERATE MBIU2 (CS5535) */ + /* (if present) */ + + MSR_READ(MBD_MSR_CAP, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low)); + if (GET_DEVICE_ID(msrValue.high, msrValue.low) == CP_CC_MBIU) { + /* COUNT MBIU PORTS */ + + MSR_READ(MBIU_CAP, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low)); + mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low); + + /* FIND REFLECTIVE PORT */ + /* Query the MBIU for the port through which we are communicating. */ + /* We will avoid accesses to this port to avoid a self-reference. */ + + MSR_READ(MBIU_WHOAMI, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low)); + reflective = msrValue.low & WHOAMI_MASK; + + /* ENUMERATE ALL PORTS */ + /* For every possible port, set the MBIU.deviceId to something. */ + + for (port = 0; port < 8; port++) { + /* FILL IN CLAIMED FIELD */ + /* All MBIU ports can only be assigned to one device from the */ + /* Durango table */ + + MBIU2[port].claimed = 0; + + /* MBIU2 PORT NUMBERS ARE IN 22:20 AND 31:23 = 010100010B */ + + MBIU2[port].address = + (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20); + + if (port == reflective) + MBIU2[port].deviceId = REFLECTIVE; + else if (port > mbiu_port_count) + MBIU2[port].deviceId = NOT_POPULATED; + else { + MSR_READ(MBD_MSR_CAP, MBIU2[port].address, &(msrValue.high), + &(msrValue.low)); + MBIU2[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low); + } + } + } else { + /* NO 5535 */ + /* If the CS5535 is not installed, fill in the cached table */ + /* with the 'NOT_INSTALLED' flag. Also, fill in the device */ + /* status from NOT_KNOWN to REQ_NOT_INSTALLED. */ + + for (port = 0; port < 8; port++) { + MBIU2[port].claimed = 0; + MBIU2[port].deviceId = NOT_INSTALLED; + MBIU2[port].address = + (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20); + } + for (port = CP_INDEX_START; port <= CP_INDEX_STOP; port++) { + msrDev[port].Present = REQ_NOT_INSTALLED; + } + } +} + +/*------------------------------------------------------------------ + * redcloud_init_msr_devices (PRIVATE ROUTINE - NOT PART OF DURANGO API) + + * Handles the details of finding each possible device on the MBUS. + * If a given device is not found, its structure is left uninitialized. + * If a given device is found, its structure is updated. + * + * This init routine only checks for devices in aDev[]. + * + * Passed: + * aDev - is a pointer to the array of MBUS devices. + * arraySize - number of elements in aDev. + * + * Returns: + * 1 - If, for every device, its address was found. + * 0 - If, for any device, an error was encountered. + *------------------------------------------------------------------ + */ +int +redcloud_init_msr_devices(MSR aDev[], unsigned int array_size) +{ + unsigned int i, issues = 0; + + /* TRY TO FIND EACH ITEM IN THE ARRAY */ + + for (i = 0; i < array_size; i++) { + /* IGNORE DEVICES THAT ARE ALREADY FOUND */ + /* The addresses for "found" devices are already known. */ + + if (aDev[i].Present == FOUND || aDev[i].Present == REQ_NOT_INSTALLED) + continue; + + /* TRY TO FIND THE DEVICE ON THE MBUS */ + + aDev[i].Present = redcloud_find_msr_device(&aDev[i]); + + /* INCREMENT ERROR COUNT IF DEVICE NOT FOUND */ + + if (aDev[i].Present != FOUND) + issues++; + } + + return (issues == 0); +} + +/*------------------------------------------------------------------ + * redcloud_find_msr_device (PRIVATE ROUTINE - NOT PART OF DURANGO API) + * + * Passed: + * pDev - is a pointer to one element in the array of MBUS devices + * + * Returns: + * FOUND - Device was found and pDev->Address has been updated. + * + * REQ_NOT_FOUND - Device was not found and pDev->Address has not + * been updated. + * + *------------------------------------------------------------------ +*/ +DEV_STATUS +redcloud_find_msr_device(MSR * pDev) +{ + unsigned int i; + + /* SEARCH DURANGO'S CACHED MBUS TOPOLOGY */ + /* This gets a little tricky. As the only identifier we have for each */ + /* device is the device ID and we have multiple devices of the same type */ + /* MCP, MPCI, USB, etc. we need to make some assumptions based on table */ + /* order. These are as follows: */ + /* 1. All Redcloud nodes are searched first, as we assume that they */ + /* are first in the table. */ + /* 2. If two devices have the same device ID and are found on the same */ + /* device (GX2, CS5535, etc.) we assume that they are listed such */ + /* that the first device in the table with this device ID has a lower */ + /* port address. */ + /* 3. After a device ID has been matched, the port is marked as */ + /* 'claimed', such that future enumerations continue searching the */ + /* GeodeLink topology. */ + + /* SEARCH MBIU0 */ + + for (i = 0; i < 8; i++) { + if (MBIU0[i].deviceId == pDev->Id && !(MBIU0[i].claimed)) { + MBIU0[i].claimed = 1; + pDev->Address = MBIU0[i].address; + return FOUND; + } + } + + /* SEARCH MBIU1 */ + + for (i = 0; i < 8; i++) { + if (MBIU1[i].deviceId == pDev->Id && !(MBIU1[i].claimed)) { + MBIU1[i].claimed = 1; + pDev->Address = MBIU1[i].address; + return FOUND; + } + } + + /* SEARCH MBIU2 */ + + for (i = 0; i < 8; i++) { + if (MBIU2[i].deviceId == pDev->Id && !(MBIU2[i].claimed)) { + MBIU2[i].claimed = 1; + pDev->Address = MBIU2[i].address; + return FOUND; + } + } + + return REQ_NOT_FOUND; +} + +/*-------------------------------------------------------------------- + * gfx_id_msr_device + * + * This routine handles reading the capabilities MSR register (typically 0x2000) + * and checking if the 'id' field matchs pDev.Id. This routine is + * used by applications/drivers that need to extend the list of known + * MBUS devices beyond those known by Durango. + * + * Passed: + * pDev - Pointer to MSR structure containing the device's ID. + * address - device address. + * + * Returns: + * FOUND - The IDs do match. + * REQ_NOT_FOUND - There was not a match. + * + *-------------------------------------------------------------------- + */ +#if GFX_MSR_DYNAMIC +DEV_STATUS +redcloud_id_msr_device(MSR * pDev, unsigned long address) +#else +DEV_STATUS +gfx_id_msr_device(MSR * pDev, unsigned long address) +#endif +{ + Q_WORD msrValue; + + MSR_READ(MBD_MSR_CAP, address, &(msrValue.high), &(msrValue.low)); + + if (GET_DEVICE_ID(msrValue.high, msrValue.low) == pDev->Id) + return FOUND; + else + return REQ_NOT_FOUND; +} + +/*-------------------------------------------------------------------- + * gfx_get_msr_dev_address + * + * This function returns the 32-bit address of the requested device. + * The device must be a known MBUS device. (It must be in Durango's + * device table.) DEV_STATUS should be checked to verify that the address + * was updated. + * + * + * Passed: + * device - device index of the device in question. + * *address - ptr to location where address should be stored. + * + * Returns: + * DEV_STATUS of device in question. (NOT_KNOWN if device is out of range.) + * *address - updated if 'device' is within range + * + * Notes: + * This function should only be called after gfx_msr_init + * + *-------------------------------------------------------------------- + */ +#if GFX_MSR_DYNAMIC +DEV_STATUS +redcloud_get_msr_dev_address(unsigned int device, unsigned long *address) +#else +DEV_STATUS +gfx_get_msr_dev_address(unsigned int device, unsigned long *address) +#endif +{ + if (device < NUM_DEVS) { + if (msrDev[device].Present == FOUND) + *address = msrDev[device].Address; + + return msrDev[device].Present; + } + return NOT_KNOWN; + +} + +/*-------------------------------------------------------------------- + * gfx_get_glink_id_at_address + * + * This function returns the 16-bit deviceId at the requested address. + * DEV_STATUS should be checked to make sure that device was updated. + * + * Passed: + * device - ptr to location where device ID should be stored. + * address - address of desired device ID. + * + * Returns: + * FOUND if address is a valid address, NOT_KNOWN if address cannot be found + * on the mbus. + * *device - updated with device Id info. + * + * Notes: + * This function should be called after gfx_msr_init + * + *-------------------------------------------------------------------- + */ +#if GFX_MSR_DYNAMIC +DEV_STATUS +redcloud_get_glink_id_at_address(unsigned int *device, unsigned long address) +#else +DEV_STATUS +gfx_get_glink_id_at_address(unsigned int *device, unsigned long address) +#endif +{ + int port; + + for (port = 0; port < 8; port++) { + if (MBIU0[port].address == address) { + *device = MBIU0[port].deviceId; + return FOUND; + } else if (MBIU1[port].address == address) { + *device = MBIU1[port].deviceId; + return FOUND; + } else if (MBIU2[port].address == address) { + *device = MBIU2[port].deviceId; + return FOUND; + } + } + + return NOT_KNOWN; + +} + +/*-------------------------------------------------------------------- + * gfx_msr_read + * + * Performs a 64-bit read from 'msrRegister' in device 'device'. 'device' is + * an index into Durango's table of known MBUS devices. + * + * Returns: + * FOUND - if no errors were detected and msrValue has been updated. + * NOT_KNOWN - an error was detected. msrValue is not updated. + * REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown. Caller + * should call msrInit() first. msrValue is not updated. + * Notes: + * This function should be called after gfx_msr_init + *-------------------------------------------------------------------- + */ +#if GFX_MSR_DYNAMIC +DEV_STATUS +redcloud_msr_read(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue) +#else +DEV_STATUS +gfx_msr_read(unsigned int device, unsigned int msrRegister, Q_WORD * msrValue) +#endif +{ + if (device < NUM_DEVS) { + if (msrDev[device].Present == FOUND) + MSR_READ(msrRegister, msrDev[device].Address, &(msrValue->high), + &(msrValue->low)); + + return msrDev[device].Present; + } + return NOT_KNOWN; +} + +/*-------------------------------------------------------------------- + * gfx_msr_write + * + * Performs a 64-bit write to 'msrRegister' in device 'devID'. + * + * Returns: + * FOUND - if no errors were detected and msrValue has been updated. + * NOT_KNOWN - an error was detected. msrValue is not updated. + * REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown. Caller + * should call msrInit() first. msrValue is not updated. + * + * Notes: + * This function is valid to call after initMSR_API() + * + *-------------------------------------------------------------------- + */ +#if GFX_MSR_DYNAMIC +DEV_STATUS +redcloud_msr_write(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue) +#else +DEV_STATUS +gfx_msr_write(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue) +#endif +{ + if (device < NUM_DEVS) { + if (msrDev[device].Present == FOUND) + MSR_WRITE(msrRegister, msrDev[device].Address, &(msrValue->high), + &(msrValue->low)); + + return msrDev[device].Present; + } + return NOT_KNOWN; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/release.txt b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/release.txt new file mode 100644 index 000000000..8d0c87fe7 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/release.txt @@ -0,0 +1,464 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/release.txt,v 1.3 2003/02/06 17:46:02 alanh Exp $ */ +Durango Release Notes +Version 2.49.01 +Win98/WinXP/DOS/Linux +January 29, 2003 + +----------------------------------------------------------------------------- +PRODUCT INFORMATION +----------------------------------------------------------------------------- +Durango is a graphics/video software support package designed to assist in the +development of display drivers and embedded applications. The core of this +package is source code that performs most of the graphics related +functionality for the National Semiconductor ® Geode family of products. +Development time for new software is reduced by using these routines to access +the hardware. + +----------------------------------------------------------------------------- +INSTALLATION INSTRUCTIONS +----------------------------------------------------------------------------- +Download the file to a directory. Modify and include the file durango.c +according to the needs of the application. + +----------------------------------------------------------------------------- +REVISION HISTORY +----------------------------------------------------------------------------- + +02/05/03 Version 2.49.02 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Fixed GX2 left clipping for 4:2:0 video. + +============================================================================= + +01/29/03 Version 2.49.01 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Removed unused variable in CS5530 video code. +* Changed max supported pixel clock for SCx2xx to 157.5 MHz. + +============================================================================= + +01/10/03 Version 2.49.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Added extra wait loop when polling for CRC completion. +* Removed code that sets the pitch offsets for 4:2:0 video within + gfx_set_video_size. +* Fixed panning code to work with any display pitch. +* Added code to clear the PLL bypass bit when setting the dot PLL. +* Fixed panning code so cursor never disappears when panning. +* Changed GX2 delay loops to do a volatile register read to prevent + the entire delay loop from being discarded by a compiler. + +============================================================================= + +11/19/02 Version 2.47.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Updated gfx2_* routines to use a signed stride. +* SW workaround for issue #134.8 - Strange horizontal lines appearing while + drawing lines. +* Implemented gfx_set_video_left_crop for CS5530 +* Updated sub carrier reset values for NTSC and PAL. + +============================================================================= + +08/29/02 Version 2.45.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Modified gfx_set_cursor_position to use cursor position when panning and not adjust + using hotspots. +* Added new routine gfx_get_refreshrate_from_mode. +* Added gfx_text_blt routine. +* Added gfx_get_tv_display_mode_frequency routine. +* Added gfx_get_frequency_from_refreshrate routine. +* Added gfx_set_video_cursor_enable routine. +* Fixed Linux compilation warnings. +* Updated modeset code to clear panning variables. +* Added panel timings for 1600x1200 desktops. +* Removed wait for VBlank when panning using cursor routines. + +============================================================================= + +07/12/02 Version 2.43.03 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Modified gfx_get_display_mode to support 56 Hz modes. +* Added support for 8K pitch when setting a true color mode above 1024x768 +* Added a byte-packed option to gfx2_mono_expand_blt +* Fix for Carmel D2 alpha blending issue. +* Added typecasts for proper compilation. +* Fixed CS5535 MBIU address. +* Added new GX2 routine, gfx2_text_blt +* Added MSR implementations for Linux. +* Further optimized default GX1 string macros. +* Added new routine, gfx_set_panel_present to allow panning without adjusting panel timings. +* Added assembly macros for 32-bit Windows applications. + +============================================================================= + +03/21/02 Version 2.41.02 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Optimized GX2 Bitmap-to-screen BLTs by using a 2-line offscreen scratch area. +* Fixed a bug in GX2 monochrome bitmap BLTs. +* Fixed gfx_get_clock_frequency for GX2 2.0 +* Added 56 Hz support to gfx_get_clock_frequency +* Changed gfx_set_compression_size to subtract header size +* Changed gfx_get_compression_size to add header size + +============================================================================= + +03/04/02 Version 2.39.01 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Added support for CS5535 MSRs. +* Fixed a bug in monochrome bitmap BLTs. +* Added support for 32-bit CRC mechanism in GX2 2.0. +* First official GX2 release. +* Added support for new Dot PLL mechanism in GX2 2.0 +* Added support for Carmel D1.1 and D2. + +============================================================================= + +01/24/02 Version 2.37.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* Changed gfx_get_clock_frequency, gfx_get_cursor_offset and gfx_get_display_offset + to be outside the GFX_READ_ROUTINES flag. +* Modified the modeset code to set higher FIFO priority levels for high bandwidth + modes. +* Init code no longer returns Redcloud ID when no chip detected. +* Added fix for Redcloud 1.x rev ID +* New GX2 PLL settings - updates to the 14 MHz table and a new 48 MHz table. +* Optimized all bitmap-to-screen routines. Optimizations include new macros that + allow correct operation in a 16-bit environment. +* 3K cache is now assumed to be the default scratchpad configuration. +* gfx_get_frame_buffer_size for GX2 no longer uses a VGA register. This allows + correct operation even with an external VGA card present in the system. +* Added support for 1152x864 desktop resolution on a flat panel. +* Added 24BPP support for large display modes. +* Modified gfx_set_video_scale such that an identity scale is now default. +* Modifed flat panel modeset code to dynamically determine the size of the mode table. +* Added support for Carmel Rev D2. + +============================================================================= + +10/22/01 Version 2.35.01 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- + +* New release notes format. +* Added fix for SC1200 issue #813 (TVOut field indication is reversed. +* Added check for invalid values in video upscale. +* Fixed compilation warnings and run-time errors under DOS. +* Added new macros for word I/O. +* Optimized VSAII MSR code to used DWORD I/O. +* Fixed SoftVG base PCI base addresses. +* Several fixes to Redcloud API found during bringup. +* Modified Durango to support 4-pixel video alignment for Redcloud. +* Added the functions gfx_test_vip_overflow, gfx_get_vip_line, + gfx_set_decoder_luminance_filter, gfx_set_tv_YV_delya and + gfx_set_tv_field_status_invert. +* Added support for Carmel D1 revision ID. +* Moved gfx_get_vip_base and gfx_get_vbi_pitch outside of the + GXF_READ_ROUTINES flag. +* Minor fixes to saa7114.c and gfx_set_tv-enable. +* Added don't care option in gfx_set_vip_base. +* Added fix for SC1200 issue #1121 (VIP FIFO bus request threshold bit + is inverted. + +============================================================================= + +07/31/01 Version 2.33.02 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Completed implementation of vertical downscaling support for GX2. +* Added a method to lock the display controller timings. +* Added support for SC1200 Rev C. +* Small modifications to gfx_set_video_format. +* Removed unused and unimplemented I2C functions. +* Changes to prevent errors and compiler warnings in DOS. +* Updated headers to include both BSD and GPL licenses. + +============================================================================= + +06/08/01 Version 2.31.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Added new routines to manipulate vertical video downscaling on GX2. +* Minor fixes to the function gfx_read_window_crc. +* Implemented all init routines for GX2 except gfx_get_core_freq. +* Added support for 27MHz reference frequency to the GX2 PLL. +* Added new function gfx_get_softvga_active. +* Minor changes to the function sc1200_reset_video. +* Fixed some minor compiler warnings. + +============================================================================= + +04/25/01 Version 2.29.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Disabled all CSC when setting an RGB video format. +* Modified sc1200_set_video_size to add 2 to the window height. +* Modified code to support the accelerator and cursor in pixel and line double modes. +* Modified gfx_get_core_freq to be a dynamic API routine. +* Added the function gfx_read_window_crc for GX2. +* Added init routine gfx_get_graphics_register_base for GX2. +* Added new macros to access the scratchpad RAM to support Win2K and WinME. +* Added mew macros to access the GP registers for GX2. + +============================================================================= + +04/06/01 Version 2.27.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Added new TV read functions: + gfx_get_tv_enable, gfx_get_tv_output, gfx_get_tv_display_mode, + gfx_get_tv_mode_count, gfx_is_tv_display_mode_supported +* Added new function gfx_set_display_bpp. +* Added new function gfx_get_frame_buffer_line_size. +* Modified gfx_set_vbi_base to accept pure physical addresses instead of offsets. +* Implemented video and display controller routines for GX2. +* Modified some initialization routines to be dynamic. +* Created new API extension for GX2 MSR accesses. +* Added new icon routines for GX2. +* Modified gfx_set_tv_display to preserve current bpp. +* Minor modifications to gfx_set_tv_format, gfx_set_video_palette and + gfx_set_video_palette entry. +* Added support for 1152x864@75Hz + +============================================================================= + +03/12/01 Version 2.25.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Adapted new revision format system. +* Synchronized with NSTA Durango. Updated support for all SC1200 features. +* Added support for 640x400 as well as emulated VGA modes. +* Added new routines to access single palette color entries. +* Added new routine to return the maximum supported pixel clock. +* Added new routine gfx_set_crt_enable to manipulate the CRT display logic. +* Added new rendering routine gfx_color_pattern_fill. +* Added 4:2:0 and RGB video format support for CS5530 and SC1200. +* Modified code to allow operation under DOS. + +============================================================================= + +07/21/00 Version 2.04 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Verified Xfree86 driver version 1.1.4 under Linux, and ce v2.3. +* Merged sc1200 changes. +* Added routines to support the query of current display mode. +* Added functions gfx_enable_softvga, dfx_disable_softvga. +* Added code optimization in rendering loops to use 32 bit writes where possible. +* Added gfx_is_mode_supported to query if given mode supported by the h/w. +* Added Flat panel support, realy testing with panel done only for 800x600. +* Removed subtraction of 16 from gfx_set_compression_size. +* Added version.h file to reflect the version of the durango used. + +============================================================================= + +03/03/00 Version 2.01 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Verified Xfree86 driver version 1.1 under FreeBSD and Linux. +* Added automatic detection of BLT buffer bases in "gfx_set_bpp" routine. +* Fixed improper setting of VGA attrubute controller index register. +* Moved "gfx_get_display_bpp" to always be included. +* Moved "gfx_get_hactive" and "gfx_get_vactive" to always be included. +* Clipped video source size if off bottom or right side. +* Properly adjusted video offset if clipped on the top side. +* Added "gfx_get_video_line_size" and "gfx_get_video_xclip" routines. + +============================================================================= + +02/21/00 Version 2.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Added gfx_vga.c. +* Added write to GP_BLIT_STATUS in "gfx_set_bpp" routine. +* Verified alpha blending on SC1200. +* Removed "gfx_set_blt_buffers" routine. + +============================================================================= + +02/09/00 Version 1.20 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Verified display modes and graphics rendering on SC1200. +* Updated PLL table for SC1200 to set modes. +* DURANGO.C FILE CHANGE!: Modifed and added compiler definitions. +* Split gfx_disp.c file into gu1_disp.c and gu2_disp.c +* Split gfx_rndr.c file into gu1_rndr.c and gu2_rndr.c +* Split gfx_vid.c file into vid_5530.c, vid_1400.c, and vid_1200.c +* Split gfx_vip.c file into vip_1400.c and vip_1200.c +* Split gfx_tv.c file into geode_tv.c and fs451_tv.c +* Split gfx_i2c.c file into acc_i2c.c and gpio_i2c.c. +* Split gfx_dcdr.c file to saa7114.c +* Added GFX_READ_ROUTINES compiler definition. +* Moved routines from gfx_read.c (no longer exists) to other files. +* Abstracted display controller access in the video overlay routines. +* Added routines to control display compression hardware. + +============================================================================= + +01/28/00 Version 1.13 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Passes randomly generated rendering tests in Darwin for GXLV. +* Fixed bug for large bitmap to screen BLTs (greater than 64K). +* Fixed bug for pattern fills using solid source data for plane masks. + +============================================================================= + +01/14/00 Version 1.12 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Added proper use of hotspot to gfx_set_cursor_position. +* Fixed buffer size to handle all frame buffer start address alignments. +* Added initial version of gfx_tv.c. + +============================================================================= + +01/07/00 Version 1.11 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Fixed bug with transparent BLTs (loading transparent color into BB1). +* Added definition of gfx_color_bitmap_to_screen_blt to gfx_rtns.h. +* Added gfx_color_bitmap_to_screen_xblt (transparent bitmap to screen). + +============================================================================= + +12/21/99 Version 1.10 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Added additional video decoder routines to gfx_dcdr.c. +* Added VBI routines to gfx_vip.c. +* Added alpha blending routines for SC1200 to gfx_vid.c + +============================================================================= + +10/01/99 Version 1.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Added video port, video decoder, I2C, and hardware query rouines. +* New files: gfx_vip.c, gfx_dcdr.c, gfx_i2c.c, gfx_read.c. + +============================================================================= + +08/27/99 Version 0.05 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* INTERFACE CHANGE: Changed "gfx_csptr[]" to "gfx_vidptr" and "gfx_vipptr". +* Added "gfx_get_vid_register_base" and "gfx_get_vip_register_base". +* Added initial PLL table for SC1400. +* Verified mode set and video overlay routines work correctly on SC1400. +* Updated initilization routines. +* Added update of graphics engine in "gfx_set_display_pitch". + +============================================================================= + +08/20/99 Version 0.04 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* INTERFACE CHANGE: "gfx_load_*" routines changed to "gfx_set_*" for naming + consistency. The "gfx_text_glyph" routine was removed. +* Added video overlay routines. +* Added gfx_vid.c file. + +============================================================================= + +08/16/99 Version 0.03 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* INTERFACE CHANGE: Access to CS5530 now through separate pointer. Project + must declare and map the gfx_csptr[GFX_CSPTR_SIZE] variable. +* Added durango.c file as template for main source file. +* Added gfx_init.c file. + +============================================================================= + +08/04/99 Version 0.02 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Additional modes in gfx_mode.h file. +* Separated register definitions from gfx_defs.h into gfx_regs.h. + +============================================================================= + +07/30/99 Version 0.01 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +* Initial release. +----------------------------------------------------------------------------- + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu1.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu1.c new file mode 100644 index 000000000..6d71f59ce --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu1.c @@ -0,0 +1,1750 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu1.c,v 1.2 2003/01/14 09:34:34 alanh Exp $ */ +/* + * $Workfile: rndr_gu1.c $ + * + * This file contains routines to program the 2D acceleration hardware for + * the first generation graphics unit (GXLV, SC1200). + * + * gfx_set_bpp + * gfx_set_solid_pattern + * gfx_set_mono_pattern + * gfx_set_color_pattern + * gfx_set_solid_source + * gfx_set_mono_source + * gfx_set_raster_operation + * gfx_pattern_fill + * gfx_screen_to_screen_blt + * gfx_screen_to_screen_xblt + * gfx_color_bitmap_to_screen_blt + * gfx_color_bitmap_to_screen_xblt + * gfx_mono_bitmap_to_screen_blt + * gfx_bresenham_line + * gfx_wait_until_idle + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +void gu1_set_bpp(unsigned short bpp); +void gu1_set_solid_pattern(unsigned long color); +void gu1_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparency); +void gu1_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned long data2, unsigned long data3, + unsigned char transparency); +void gu1_load_color_pattern_line(short y, unsigned long *pattern_8x8); +void gu1_set_solid_source(unsigned long color); +void gu1_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned short transparent); +void gu1_set_pattern_flags(unsigned short flags); +void gu1_set_raster_operation(unsigned char rop); +void gu1_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height); +void gu1_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long *pattern); +void gu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height); +void gu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color); +void gu1_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, + unsigned short height, + unsigned char *data, long pitch); +void gu1_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, + unsigned short height, + unsigned char *data, long pitch, + unsigned long color); +void gu1_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, + unsigned short height, unsigned char *data, + short pitch); +void gu1_text_blt(unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data); +void gu1_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags); +void gu1_wait_until_idle(void); + +#if GFX_NO_IO_IN_WAIT_MACROS +#define GFX_WAIT_PENDING while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { ; } +#define GFX_WAIT_BUSY while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { ; } +#define GFX_WAIT_PIPELINE while (READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY) { ; } +#else +#define GFX_WAIT_PENDING while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { INB (0x80); } +#define GFX_WAIT_BUSY while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { INB (0x80); } +#define GFX_WAIT_PIPELINE while (READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY) { INB (0x80); } +#endif + +void gu1_detect_blt_buffer_base(void); +int gu1_test_blt_pending(void); +void gu1_solid_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long color); + +/*--------------------------------------------------------------------------- + * GFX_SET_BPP + * + * This routine sets the bits per pixel value in the graphics engine. + * It is also stored in a static variable to use in the future calls to + * the rendering routines. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu1_set_bpp(unsigned short bpp) +#else +void +gfx_set_bpp(unsigned short bpp) +#endif +{ + int control = 0; + unsigned short pitch = gfx_get_display_pitch(); + + GFXbpp = bpp; + + /* DETECT BASE ADDRESSES FOR BLT BUFFERS */ + /* Different for 2K or 3K of scratchpad. Also need to calculate */ + /* the number of pixels that can fit in a BLT buffer - need to */ + /* subtract 16 for alignment considerations. The 2K case, for */ + /* example, is 816 bytes wide, allowing 800 pixels in 8 BPP, which */ + /* means rendering operations won't be split for 800x600. */ + + gu1_detect_blt_buffer_base(); + GFXbufferWidthPixels = GFXbb1Base - GFXbb0Base - 16; + if (bpp > 8) { + /* If 16bpp, divide GFXbufferWidthPixels by 2 */ + GFXbufferWidthPixels >>= 1; + } + + /* SET THE GRAPHICS CONTROLLER BPP AND PITCH */ + if (bpp > 8) { + /* Set the 16bpp bit if necessary */ + control = BC_16BPP; + } + if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) { + control |= BC_FB_WIDTH_4096; + } else if (pitch > 1024) { + control |= BC_FB_WIDTH_2048; + } + GFX_WAIT_BUSY; + WRITE_REG32(GP_BLIT_STATUS, control); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_SOLID_SOURCE +// +// This routine is used to specify a solid source color. For the Xfree96 +// display driver, the source color is used to specify a planemask and the +// ROP is adjusted accordingly. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_set_solid_source(unsigned long color) +#else +void +gfx_set_solid_source(unsigned long color) +#endif +{ + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* FORMAT 8 BPP COLOR */ + /* GX requires 8BPP color data be duplicated into bits [15:8]. */ + + if (GFXbpp == 8) { + color &= 0x00FF; + color |= (color << 8); + } + + /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_SRC_COLOR_0, (unsigned short)color); + WRITE_REG16(GP_SRC_COLOR_1, (unsigned short)color); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_MONO_SOURCE +// +// This routine is used to specify the monochrome source colors. +// It must be called *after* loading any pattern data (those routines +// clear the source flags). +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned short transparent) +#else +void +gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned short transparent) +#endif +{ + /* SET TRANSPARENCY FLAG */ + + GFXsourceFlags = transparent ? RM_SRC_TRANSPARENT : 0; + + /* FORMAT 8 BPP COLOR */ + /* GX requires 8BPP color data be duplicated into bits [15:8]. */ + + if (GFXbpp == 8) { + bgcolor &= 0x00FF; + bgcolor |= (bgcolor << 8); + fgcolor &= 0x00FF; + fgcolor |= (fgcolor << 8); + } + + /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_SRC_COLOR_0, (unsigned short)bgcolor); + WRITE_REG16(GP_SRC_COLOR_1, (unsigned short)fgcolor); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_SOLID_PATTERN +// +// This routine is used to specify a solid pattern color. It is called +// before performing solid rectangle fills or more complicated BLTs that +// use a solid pattern color. +// +// The driver should always call "gfx_load_raster_operation" after a call +// to this routine to make sure that the pattern flags are set appropriately. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_set_solid_pattern(unsigned long color) +#else +void +gfx_set_solid_pattern(unsigned long color) +#endif +{ + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* SET PATTERN FLAGS */ + + GFXpatternFlags = 0; + + /* FORMAT 8 BPP COLOR */ + /* GX requires 8BPP color data be duplicated into bits [15:8]. */ + + if (GFXbpp == 8) { + color &= 0x00FF; + color |= (color << 8); + } + + /* SAVE THE REFORMATTED COLOR FOR LATER */ + /* Used to call the "GFX_solid_fill" routine for special cases. */ + + GFXsavedColor = color; + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_MONO_PATTERN +// +// This routine is used to specify a monochrome pattern. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparent) +#else +void +gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparent) +#endif +{ + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* SET PATTERN FLAGS */ + + GFXpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT : + RM_PAT_MONO; + + /* FORMAT 8 BPP COLOR */ + /* GXm requires 8BPP color data be duplicated into bits [15:8]. */ + + if (GFXbpp == 8) { + bgcolor &= 0x00FF; + bgcolor |= (bgcolor << 8); + fgcolor &= 0x00FF; + fgcolor |= (fgcolor << 8); + } + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)bgcolor); + WRITE_REG16(GP_PAT_COLOR_1, (unsigned short)fgcolor); + WRITE_REG32(GP_PAT_DATA_0, data0); + WRITE_REG32(GP_PAT_DATA_1, data1); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_COLOR_PATTERN +// +// This routine is used to specify a color pattern. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned long data2, unsigned long data3, + unsigned char transparent) +#else +void +gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned long data2, unsigned long data3, + unsigned char transparent) +#endif +{ + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* SET PATTERN FLAGS */ + + GFXpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT : + RM_PAT_MONO; + + GFXpatternFlags |= RM_PAT_COLOR; + /* FORMAT 8 BPP COLOR */ + /* GXm requires 8BPP color data be duplicated into bits [15:8]. */ + + if (GFXbpp == 8) { + bgcolor &= 0x00FF; + bgcolor |= (bgcolor << 8); + fgcolor &= 0x00FF; + fgcolor |= (fgcolor << 8); + } + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)bgcolor); + WRITE_REG16(GP_PAT_COLOR_1, (unsigned short)fgcolor); + WRITE_REG32(GP_PAT_DATA_0, data0); + WRITE_REG32(GP_PAT_DATA_1, data1); + if (GFXbpp > 8) { + WRITE_REG32(GP_PAT_DATA_2, data2); + WRITE_REG32(GP_PAT_DATA_3, data3); + } +} + +/* +//--------------------------------------------------------------------------- +// GFX_LOAD_COLOR_PATTERN_LINE +// +// This routine is used to load a single line of a 8x8 color pattern. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_load_color_pattern_line(short y, unsigned long *pattern_8x8) +#else +void +gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8) +#endif +{ + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* SET PATTERN FLAGS */ + + GFXpatternFlags = RM_PAT_COLOR; + + y &= 7; + + if (GFXbpp > 8) + pattern_8x8 += (y << 2); + else + pattern_8x8 += (y << 1); + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ + + GFX_WAIT_PENDING; + WRITE_REG32(GP_PAT_DATA_0, pattern_8x8[0]); + WRITE_REG32(GP_PAT_DATA_1, pattern_8x8[1]); + if (GFXbpp > 8) { + WRITE_REG32(GP_PAT_DATA_2, pattern_8x8[2]); + WRITE_REG32(GP_PAT_DATA_3, pattern_8x8[3]); + } +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_RASTER_OPERATION +// +// This routine loads the specified raster operation. It sets the pattern +// flags appropriately. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_set_raster_operation(unsigned char rop) +#else +void +gfx_set_raster_operation(unsigned char rop) +#endif +{ + unsigned short rop16; + + /* GENERATE 16-BIT VERSION OF ROP WITH PATTERN FLAGS */ + + rop16 = (unsigned short)rop | GFXpatternFlags; + if ((rop & 0x33) ^ ((rop >> 2) & 0x33)) + rop16 |= GFXsourceFlags; + + /* SAVE ROP FOR LATER COMPARISONS */ + /* Need to have the pattern flags included */ + + GFXsavedRop = rop16; + + /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */ + /* True if even bits (0:2:4:6) do not equal the correspinding */ + /* even bits (1:3:5:7). */ + + GFXusesDstData = ((rop & 0x55) ^ ((rop >> 1) & 0x55)); + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + /* Only one operation can be pending at a time. */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_RASTER_MODE, rop16); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SOLID_FILL +// +// This routine MUST be used when performing a solid rectangle fill with +// the ROPs of PATCOPY (0xF0), BLACKNESS (0x00), WHITENESS (0xFF), or +// PATINVERT (0x0F). There is a bug in GXm for these cases that requires a +// workaround. +// +// For BLACKNESS (ROP = 0x00), set the color to 0x0000. +// For WHITENESS (ROP = 0xFF), set the color to 0xFFFF. +// For PATINVERT (ROP = 0x0F), invert the desired color. +// +// X screen X position (left) +// Y screen Y position (top) +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// COLOR fill color +// +// THIS ROUTINE SHOULD NOT BE DIRECTLY CALLED FROM THE DRIVER. The driver +// should always use GFX_pattern_fill and let that routine call this one +// when approipriate. This is to hide quirks specific to MediaGX hardware. +//--------------------------------------------------------------------------- +*/ +void +gu1_solid_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long color) +{ + unsigned short section; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Only one operation can be pending at a time. */ + + GFX_WAIT_PENDING; + + /* SET REGISTERS TO DRAW RECTANGLE */ + + WRITE_REG16(GP_DST_XCOOR, x); + WRITE_REG16(GP_DST_YCOOR, y); + WRITE_REG16(GP_HEIGHT, height); + WRITE_REG16(GP_RASTER_MODE, 0x00F0); /* PATCOPY */ + WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color); + + /* CHECK WIDTH FOR GX BUG WORKAROUND */ + + if (width <= 16) { + /* OK TO DRAW SMALL RECTANGLE IN ONE PASS */ + + WRITE_REG16(GP_WIDTH, width); + WRITE_REG16(GP_BLIT_MODE, 0); + } else { + /* DRAW FIRST PART OF RECTANGLE */ + /* Get to a 16 pixel boundary. */ + + section = 0x10 - (x & 0x0F); + WRITE_REG16(GP_WIDTH, section); + WRITE_REG16(GP_BLIT_MODE, 0); + + /* POLL UNTIL ABLE TO LOAD THE SECOND RECTANGLE */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_DST_XCOOR, x + section); + WRITE_REG16(GP_DST_YCOOR, y); + WRITE_REG16(GP_WIDTH, width - section); + WRITE_REG16(GP_BLIT_MODE, 0); + } +} + +/* +//---------------------------------------------------------------------------- +// GFX_PATTERN_FILL +// +// This routine is used to fill a rectangular region. The pattern must +// be previously loaded using one of GFX_load_*_pattern routines. Also, the +// raster operation must be previously specified using the +// "GFX_load_raster_operation" routine. +// +// X screen X position (left) +// Y screen Y position (top) +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height) +#else +void +gfx_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height) +#endif +{ + unsigned short section, buffer_width, blit_mode; + + /* CHECK IF OPTIMIZED SOLID CASES */ + /* Check all 16 bits of the ROP to include solid pattern flags. */ + + switch (GFXsavedRop) { + /* CHECK FOR SPECIAL CASES WITHOUT DESTINATION DATA */ + /* Need hardware workaround for fast "burst write" cases. */ + + case 0x00F0: + gu1_solid_fill(x, y, width, height, (unsigned short)GFXsavedColor); + break; + case 0x000F: + gu1_solid_fill(x, y, width, height, (unsigned short)~GFXsavedColor); + break; + case 0x0000: + gu1_solid_fill(x, y, width, height, 0x0000); + break; + case 0x00FF: + gu1_solid_fill(x, y, width, height, 0xFFFF); + break; + + /* REMAINING CASES REQUIRE DESTINATION DATA OR NOT SOLID COLOR */ + + default: + + /* DETERMINE BLT MODE VALUE */ + /* Still here for non-solid patterns without destination data. */ + + blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0; + + /* SET SOURCE EXPANSION MODE */ + /* If the ROP requires source data, then the source data is all 1's */ + /* and then expanded into the desired color in GP_SRC_COLOR_1. */ + + blit_mode |= BM_SOURCE_EXPAND; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Write the registers that do not change for each section. */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, height); + + /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */ + /* Therefore, width available = BLT buffer width * 2. */ + + buffer_width = GFXbufferWidthPixels << 1; + + /* REPEAT UNTIL FINISHED WITH RECTANGLE */ + /* Perform BLT in vertical sections, as wide as the BLT buffer */ + /* allows. Hardware does not split the operations, so */ + /* software must do it to avoid large scanlines that would */ + /* overflow the BLT buffers. */ + + while (width > 0) { + /* DETERMINE WIDTH OF SECTION */ + + if (width > buffer_width) + section = buffer_width; + else + section = width; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_DST_XCOOR, x); + WRITE_REG16(GP_DST_YCOOR, y); + WRITE_REG16(GP_WIDTH, section); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + + /* ADJUST PARAMETERS FOR NEXT SECTION */ + + width -= section; + x += section; + } + break; + } +} + +/* +//---------------------------------------------------------------------------- +// GFX_COLOR_PATTERN_FILL +// +// This routine is used to render a rectangle using the current raster +// operation and the specified color pattern. It allows an 8x8 color +// pattern to be rendered without multiple calls to the gfx_set_color_pattern +// and gfx_pattern_fill routines. +// +// X screen X position (left) +// Y screen Y position (top) +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *PATTERN pointer to 8x8 color pattern data +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long *pattern) +#else +void +gfx_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long *pattern) +#endif +{ + unsigned short blit_mode, passes, cur_y, pat_y, i; + unsigned short buffer_width, line_width; + unsigned short bpp_shift, section, cur_x; + + /* SET APPROPRIATE INCREMENT */ + + bpp_shift = (GFXbpp > 8) ? 2 : 1; + + /* SET DESTINATION REQUIRED */ + + blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0; + + /* SET SOURCE EXPANSION */ + + blit_mode |= BM_SOURCE_EXPAND; + + /* OVERRIDE RASTER MODE TO FORCE A COLOR PATTERN */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_RASTER_MODE, + (GFXsavedRop & ~RM_PAT_MASK & ~RM_PAT_TRANSPARENT) | + RM_PAT_COLOR); + + /* WRITE THE REGISTERS THAT DO NOT CHANGE */ + /* If destination data is required, the width and */ + /* x position will be overwritten. */ + + WRITE_REG16(GP_HEIGHT, 1); + WRITE_REG16(GP_WIDTH, width); + WRITE_REG16(GP_DST_XCOOR, x); + + /* THE ENTIRE PATTERN WILL NOT BE DRAWN IF THE HEIGHT IS LESS THAN 8 */ + + passes = (height < 8) ? height : 8; + + /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */ + /* Therefore, width available = BLT buffer width * 2. */ + + buffer_width = GFXbufferWidthPixels << 1; + + for (i = 0; i < passes; i++) { + pat_y = ((y + i) & 7) << bpp_shift; + cur_y = y + i; + + /* WRITE THE PATTERN DATA FOR THE ACTIVE LINE */ + + GFX_WAIT_PENDING; + WRITE_REG32(GP_PAT_DATA_0, pattern[pat_y]); + WRITE_REG32(GP_PAT_DATA_1, pattern[pat_y + 1]); + + if (GFXbpp > 8) { + WRITE_REG32(GP_PAT_DATA_2, pattern[pat_y + 2]); + WRITE_REG32(GP_PAT_DATA_3, pattern[pat_y + 3]); + } + + /* SPLIT BLT LINE INTO SECTIONS IF REQUIRED */ + /* If no destination data is required, we can ignore */ + /* the BLT buffers. Otherwise, we must separate the BLT */ + /* so as not to overflow the buffers */ + + if (blit_mode & BM_READ_DST_BB0) { + line_width = width; + cur_x = x; + + while (line_width) { + section = (line_width > buffer_width) ? buffer_width : line_width; + cur_y = y + i; + + GFX_WAIT_PENDING; + WRITE_REG16(GP_DST_XCOOR, cur_x); + WRITE_REG16(GP_WIDTH, section); + + while (cur_y < y + height) { + GFX_WAIT_PENDING; + WRITE_REG16(GP_DST_YCOOR, cur_y); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + cur_y += 8; + } + + cur_x += section; + line_width -= section; + } + + } else { + while (cur_y < y + height) { + GFX_WAIT_PENDING; + WRITE_REG16(GP_DST_YCOOR, cur_y); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + cur_y += 8; + } + } + + } + + /* RESTORE ORIGINAL ROP AND FLAGS */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_RASTER_MODE, GFXsavedRop); + +} + +/* +//---------------------------------------------------------------------------- +// SCREEN TO SCREEN BLT +// +// This routine should be used to perform a screen to screen BLT when the +// ROP does not require destination data. +// +// SRCX screen X position to copy from +// SRCY screen Y position to copy from +// DSTX screen X position to copy to +// DSTY screen Y position to copy to +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height) +#else +void +gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height) +#endif +{ + unsigned short section, buffer_width; + unsigned short blit_mode; + + /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ + + blit_mode = GFXusesDstData ? BM_READ_DST_FB1 | BM_READ_SRC_FB : + BM_READ_SRC_FB; + + /* CHECK Y DIRECTION */ + /* Hardware has support for negative Y direction. */ + + if (dsty > srcy) { + blit_mode |= BM_REVERSE_Y; + srcy += height - 1; + dsty += height - 1; + } + + /* CHECK X DIRECTION */ + /* Hardware does not support negative X direction since at the time */ + /* of development all supported resolutions could fit a scanline of */ + /* data at once into the BLT buffers (using both BB0 and BB1). This */ + /* code is more generic to allow for any size BLT buffer. */ + + if (dstx > srcx) { + srcx += width; + dstx += width; + } + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Write the registers that do not change for each section. */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, height); + + /* CHECK AVAILABLE BLT BUFFER SIZE */ + /* Can use both BLT buffers if no destination data is required. */ + + buffer_width = GFXusesDstData ? GFXbufferWidthPixels : + GFXbufferWidthPixels << 1; + + /* REPEAT UNTIL FINISHED WITH RECTANGLE */ + /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ + /* Hardware does not split the operations, so software must do it to */ + /* avoid large scanlines that would overflow the BLT buffers. */ + + while (width > 0) { + /* CHECK WIDTH OF CURRENT SECTION */ + + if (width > buffer_width) + section = buffer_width; + else + section = width; + + /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_SRC_YCOOR, srcy); + WRITE_REG16(GP_DST_YCOOR, dsty); + WRITE_REG16(GP_WIDTH, section); + + /* CHECK X DIRECTION */ + + if (dstx > srcx) { + /* NEGATIVE X DIRECTION */ + /* Still positive X direction within the section. */ + + srcx -= section; + dstx -= section; + WRITE_REG16(GP_SRC_XCOOR, srcx); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + } else { + /* POSITIVE X DIRECTION */ + + WRITE_REG16(GP_SRC_XCOOR, srcx); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + dstx += section; + srcx += section; + } + width -= section; + } +} + +/* +//---------------------------------------------------------------------------- +// SCREEN TO SCREEN TRANSPARENT BLT +// +// This routine should be used to perform a screen to screen BLT when a +// specified color should by transparent. The only supported ROP is SRCCOPY. +// +// SRCX screen X position to copy from +// SRCY screen Y position to copy from +// DSTX screen X position to copy to +// DSTY screen Y position to copy to +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// COLOR transparent color +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color) +#else +void +gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color) +#endif +{ + unsigned short section, buffer_width; + unsigned short blit_mode = BM_READ_SRC_FB; + + /* CHECK Y DIRECTION */ + /* Hardware has support for negative Y direction. */ + + if (dsty > srcy) { + blit_mode |= BM_REVERSE_Y; + srcy += height - 1; + dsty += height - 1; + } + + /* CHECK X DIRECTION */ + /* Hardware does not support negative X direction since at the time */ + /* of development all supported resolutions could fit a scanline of */ + /* data at once into the BLT buffers (using both BB0 and BB1). This */ + /* code is more generic to allow for any size BLT buffer. */ + + if (dstx > srcx) { + srcx += width; + dstx += width; + } + + /* CALCULATE BLT BUFFER SIZE */ + /* Need to use BB1 to store the BLT buffer data. */ + + buffer_width = GFXbufferWidthPixels; + + /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */ + + if (GFXbpp == 8) { + color &= 0x00FF; + color |= (color << 8); + } + color = (color & 0x0000FFFF) | (color << 16); + + /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */ + /* Need to make sure any previous BLT using BB1 is complete. */ + /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */ + + GFX_WAIT_BUSY; + WRITE_SCRATCH32(GFXbb1Base, color); + + /* DO BOGUS BLT TO LATCH DATA FROM BB1 */ + /* Already know graphics pipeline is idle. */ + /* Only need to latch data into the holding registers for the current */ + /* data from BB1. A 1 pixel wide BLT will suffice. */ + + WRITE_REG32(GP_DST_XCOOR, 0); + WRITE_REG32(GP_SRC_XCOOR, 0); + WRITE_REG32(GP_WIDTH, 0x00010001); + WRITE_REG16(GP_RASTER_MODE, 0x00CC); + WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1); + + /* WRITE REGISTERS FOR REAL SCREEN TO SCREEN BLT */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, height); + WRITE_REG16(GP_RASTER_MODE, 0x10C6); + WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); + + /* REPEAT UNTIL FINISHED WITH RECTANGLE */ + /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ + /* Hardware does not split the operations, so software must do it to */ + /* avoid large scanlines that would overflow the BLT buffers. */ + + while (width > 0) { + /* CHECK WIDTH OF CURRENT SECTION */ + + if (width > buffer_width) + section = buffer_width; + else + section = width; + + /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_SRC_YCOOR, srcy); + WRITE_REG16(GP_DST_YCOOR, dsty); + WRITE_REG16(GP_WIDTH, section); + + /* CHECK X DIRECTION */ + /* Again, this must be done in software, and can be removed if the */ + /* display driver knows that the BLT buffers will always be large */ + /* enough to contain an entire scanline of a screen to screen BLT. */ + + if (dstx > srcx) { + /* NEGATIVE X DIRECTION */ + /* Still positive X direction within the section. */ + + srcx -= section; + dstx -= section; + WRITE_REG16(GP_SRC_XCOOR, srcx); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + } else { + /* POSITIVE X DIRECTION */ + + WRITE_REG16(GP_SRC_XCOOR, srcx); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + dstx += section; + srcx += section; + } + width -= section; + } +} + +/* +//---------------------------------------------------------------------------- +// COLOR BITMAP TO SCREEN BLT +// +// This routine transfers color bitmap data to the screen. For most cases, +// when the ROP is SRCCOPY, it may be faster to write a separate routine that +// copies the data to the frame buffer directly. This routine should be +// used when the ROP requires destination data. +// +// Transparency is handled by another routine. +// +// SRCX X offset within source bitmap +// SRCY Y offset within source bitmap +// DSTX screen X position to render data +// DSTY screen Y position to render data +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *DATA pointer to bitmap data +// PITCH pitch of bitmap data (bytes between scanlines) +//---------------------------------------------------------------------------- +*/ + +#if GFX_2DACCEL_DYNAMIC +void +gu1_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch) +#else +void +gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch) +#endif +{ + unsigned short section, buffer_width; + unsigned short blit_mode = BM_READ_SRC_BB0; + unsigned short temp_height; + unsigned long dword_bytes_needed, bytes_extra; + unsigned long bpp_shift; + long array_offset; + + /* CHECK SIZE OF BLT BUFFER */ + + buffer_width = GFXbufferWidthPixels; + + /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ + /* If no destination data, we have twice the room for */ + /* source data. */ + + if (GFXusesDstData) + blit_mode |= BM_READ_DST_FB1; + else + buffer_width <<= 1; + + /* SET THE SCRATCHPAD BASE */ + + SET_SCRATCH_BASE(GFXbb0Base); + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Write the registers that do not change for each section. */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, 1); + + bpp_shift = (GFXbpp + 7) >> 4; + + while (width > 0) { + if (width > buffer_width) + section = buffer_width; + else + section = width; + + dword_bytes_needed = (section << bpp_shift) & ~3l; + bytes_extra = (section << bpp_shift) & 3l; + + temp_height = height; + + /* WRITE THE REGISTERS FOR EACH SECTION */ + /* The GX hardware will auto-increment the Y coordinate, meaning */ + /* that we don't have to. */ + + WRITE_REG16(GP_WIDTH, section); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_DST_YCOOR, dsty); + + /* CALCULATE THE BITMAP OFFSET */ + + array_offset = + (unsigned long)srcy *(long)pitch + ((long)srcx << bpp_shift); + + while (temp_height--) { + GFX_WAIT_PIPELINE; + + /* WRITE ALL DATA TO THE BLT BUFFERS */ + /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ + /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ + + WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, + array_offset); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + + array_offset += pitch; + } + + width -= section; + srcx += section; + dstx += section; + } +} + +/* +//---------------------------------------------------------------------------- +// COLOR BITMAP TO SCREEN TRANSPARENT BLT +// +// This routine transfers color bitmap data to the screen with transparency. +// The transparent color is specified. The only supported ROP is SRCCOPY, +// meaning that transparency cannot be applied if the ROP requires +// destination data (this is a hardware restriction). +// +// SRCX X offset within source bitmap +// SRCY Y offset within source bitmap +// DSTX screen X position to render data +// DSTY screen Y position to render data +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *DATA pointer to bitmap data +// PITCH pitch of bitmap data (bytes between scanlines) +// COLOR transparent color +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch, + unsigned long color) +#else +void +gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch, + unsigned long color) +#endif +{ + unsigned short section, buffer_width; + unsigned short temp_height; + unsigned long dword_bytes_needed, bytes_extra; + unsigned long bpp_shift; + long array_offset; + + /* CHECK SIZE OF BLT BUFFER */ + + buffer_width = GFXbufferWidthPixels; + + /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */ + + if (GFXbpp == 8) { + color &= 0x00FF; + color |= (color << 8); + } + color = (color & 0x0000FFFF) | (color << 16); + + /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */ + /* Need to make sure any previous BLT using BB1 is complete. */ + /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */ + + GFX_WAIT_PIPELINE; + GFX_WAIT_PENDING; + WRITE_SCRATCH32(GFXbb1Base, color); + + /* DO BOGUS BLT TO LATCH DATA FROM BB1 */ + /* Already know graphics pipeline is idle. */ + /* Only need to latch data into the holding registers for the current */ + /* data from BB1. A 1 pixel wide BLT will suffice. */ + + WRITE_REG32(GP_DST_XCOOR, 0); + WRITE_REG32(GP_SRC_XCOOR, 0); + WRITE_REG32(GP_WIDTH, 0x00010001); + WRITE_REG16(GP_RASTER_MODE, 0x00CC); + WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1); + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Write the registers that do not change for each section. */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, 1); + WRITE_REG16(GP_RASTER_MODE, 0x10C6); + WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); + + bpp_shift = (GFXbpp + 7) >> 4; + + /* SET THE SCRATCHPAD BASE */ + + SET_SCRATCH_BASE(GFXbb0Base); + + while (width > 0) { + if (width > buffer_width) + section = buffer_width; + else + section = width; + + dword_bytes_needed = (section << bpp_shift) & ~3l; + bytes_extra = (section << bpp_shift) & 3l; + + temp_height = height; + + /* WRITE THE REGISTERS FOR EACH SECTION */ + /* The GX hardware will auto-increment the Y coordinate, meaning */ + /* that we don't have to. */ + + WRITE_REG16(GP_WIDTH, section); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_DST_YCOOR, dsty); + + /* CALCULATE THE BITMAP OFFSET */ + + array_offset = + (unsigned long)srcy *(long)pitch + ((long)srcx << bpp_shift); + + while (temp_height--) { + GFX_WAIT_PIPELINE; + + /* WRITE ALL DATA TO THE BLT BUFFERS */ + /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ + /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ + + WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, + array_offset); + WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0); + + array_offset += pitch; + } + + width -= section; + srcx += section; + dstx += section; + } +} + +/* +//---------------------------------------------------------------------------- +// MONOCHROME BITMAP TO SCREEN BLT +// +// This routine transfers monochrome bitmap data to the screen. +// +// SRCX X offset within source bitmap +// SRCY Y offset within source bitmap +// DSTX screen X position to render data +// DSTY screen Y position to render data +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *DATA pointer to bitmap data +// PITCH pitch of bitmap data (bytes between scanlines) +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, short pitch) +#else +void +gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, short pitch) +#endif +{ + unsigned short section, buffer_width; + unsigned short blit_mode = BM_READ_SRC_BB0 | BM_SOURCE_EXPAND; + unsigned short temp_height; + unsigned long dword_bytes_needed, bytes_extra; + long array_offset; + + /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ + /* If no destination data, the source data will always fit. */ + /* So, in that event we will set the buffer width to a */ + /* fictitiously large value such that the BLT is never split. */ + + if (GFXusesDstData) { + buffer_width = GFXbufferWidthPixels; + blit_mode |= BM_READ_DST_FB1; + } else + buffer_width = 3200; + + /* CHECK IF DATA ALREADY IN BLIT BUFFER */ + /* If the pointer is NULL, data for the full BLT is already there */ + /* WARNING: This could cause problems if destination data is */ + /* involved and it overflows the BLT buffer. Need to remove */ + /* this option and change the drivers to use a temporary buffer. */ + + if (!data) { + GFX_WAIT_PENDING; + WRITE_REG16(GP_SRC_XCOOR, srcx & 7); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_DST_YCOOR, dsty); + WRITE_REG16(GP_WIDTH, width); + WRITE_REG16(GP_HEIGHT, height); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + return; + } + + /* SET THE SCRATCHPAD BASE */ + + SET_SCRATCH_BASE(GFXbb0Base); + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Write the registers that do not change for each section. */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, 1); + + while (width > 0) { + if (width > buffer_width) + section = buffer_width; + else + section = width; + + /* CALCULATE BYTES NEEDED */ + /* Add 1 for possible alignment issues. */ + + dword_bytes_needed = ((section + 7 + (srcx & 7)) >> 3) & ~3l; + bytes_extra = ((section + 7 + (srcx & 7)) >> 3) & 3l; + + temp_height = height; + + /* WRITE THE REGISTERS FOR EACH SECTION */ + /* The GX hardware will auto-increment the Y coordinate, meaning */ + /* that we don't have to. */ + + WRITE_REG16(GP_WIDTH, section); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_DST_YCOOR, dsty); + WRITE_REG16(GP_SRC_XCOOR, srcx & 7); + + /* CALCULATE THE BITMAP OFFSET */ + + array_offset = (unsigned long)srcy *(long)pitch + ((long)srcx >> 3); + + while (temp_height--) { + GFX_WAIT_PIPELINE; + + /* WRITE ALL DATA TO THE BLT BUFFERS */ + /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ + /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ + + WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, + array_offset); + WRITE_REG16(GP_BLIT_MODE, blit_mode); + + array_offset += pitch; + } + + width -= section; + srcx += section; + dstx += section; + } +} + +/* +//---------------------------------------------------------------------------- +// MONOCHROME TEXT BLT +// +// This routine transfers contiguous monochrome text data to the screen. +// +// DSTX screen X position to render data +// DSTY screen Y position to render data +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *DATA pointer to bitmap data +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, + unsigned short height, unsigned char *data) +#else +void +gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, + unsigned short height, unsigned char *data) +#endif +{ + unsigned long dword_bytes_needed, bytes_extra; + long pitch, buffer_bytes, data_bytes; + + /* CALCULATE DATA SIZE */ + + pitch = (width + 7) >> 3; + data_bytes = (long)height *pitch; + + /* CHECK FOR SIMPLE CASE */ + /* This routine is designed to render a source copy text glyph. If destination */ + /* data is required or the source data will not fit, we will punt the operation */ + /* to the more versatile (and slow) mono bitmap routine. */ + + if (GFXbpp > 8) + buffer_bytes = GFXbufferWidthPixels << 1; + else + buffer_bytes = GFXbufferWidthPixels; + + if (GFXusesDstData || data_bytes > buffer_bytes) { + gfx_mono_bitmap_to_screen_blt(0, 0, dstx, dsty, width, height, data, + (short)pitch); + return; + } + + /* SET THE SCRATCHPAD BASE */ + + SET_SCRATCH_BASE(GFXbb0Base); + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + + dword_bytes_needed = data_bytes & ~3l; + bytes_extra = data_bytes & 3l; + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, height); + WRITE_REG16(GP_WIDTH, width); + WRITE_REG16(GP_DST_XCOOR, dstx); + WRITE_REG16(GP_DST_YCOOR, dsty); + WRITE_REG16(GP_SRC_XCOOR, 0); + + /* WRITE ALL DATA TO THE BLT BUFFERS */ + /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ + /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ + + GFX_WAIT_PIPELINE; + + WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 0); + WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_SOURCE_TEXT); +} + +/* +//---------------------------------------------------------------------------- +// BRESENHAM LINE +// +// This routine draws a vector using the specified Bresenham parameters. +// Currently this file does not support a routine that accepts the two +// endpoints of a vector and calculates the Bresenham parameters. If it +// ever does, this routine is still required for vectors that have been +// clipped. +// +// X screen X position to start vector +// Y screen Y position to start vector +// LENGTH length of the vector, in pixels +// INITERR Bresenham initial error term +// AXIALERR Bresenham axial error term +// DIAGERR Bresenham diagonal error term +// FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu1_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +#else +void +gfx_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +#endif +{ + unsigned short vector_mode = flags; + + if (GFXusesDstData) + vector_mode |= VM_READ_DST_FB; + + /* CHECK NULL LENGTH */ + + if (!length) + return; + + /* LOAD THE REGISTERS FOR THE VECTOR */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_DST_XCOOR, x); + WRITE_REG16(GP_DST_YCOOR, y); + WRITE_REG16(GP_VECTOR_LENGTH, length); + WRITE_REG16(GP_INIT_ERROR, initerr); + WRITE_REG16(GP_AXIAL_ERROR, axialerr); + WRITE_REG16(GP_DIAG_ERROR, diagerr); + WRITE_REG16(GP_VECTOR_MODE, vector_mode); +} + +/*--------------------------------------------------------------------------- + * GFX_WAIT_UNTIL_IDLE + * + * This routine waits until the graphics engine is idle. This is required + * before allowing direct access to the frame buffer. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu1_wait_until_idle(void) +#else +void +gfx_wait_until_idle(void) +#endif +{ + GFX_WAIT_BUSY; +} + +/*--------------------------------------------------------------------------- + * GFX_TEST_BLT_PENDING + * + * This routine returns 1 if a BLT is pending, meaning that a call to + * perform a rendering operation would stall. Otherwise it returns 0. + * It is used by Darwin during random testing to only start a BLT + * operation when it knows the Durango routines won't spin on graphics + * (so Darwin can continue to do frame buffer reads and writes). + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +int +gu1_test_blt_pending(void) +#else +int +gfx_test_blt_pending(void) +#endif +{ + if (READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * BLT BUFFERS!!!!! + *--------------------------------------------------------------------------- + */ + +/* THE BOOT CODE MUST SET THE BLT BUFFER BASES USING THE "CPU_WRITE" */ +/* INSTRUCTION TO ONE OF THE FOLLOWING VALUES: */ + +#define BB0_BASE_2K 0x800 +#define BB1_BASE_2K 0xB30 +#define BB0_BASE_3K 0x400 +#define BB1_BASE_3K 0x930 + +/*--------------------------------------------------------------------------- + * gu1_detect_blt_buffer_base + * + * This detection is hidden from the driver by being called from the + * "gfx_set_bpp" routine. + * + * This is fairly ugly for the following reasons: + * + * - It is the boot code that must set the BLT buffer bases to the + * appropriate values and load the scratchpad tags. + * - The old drivers would also set the base address values to what they + * knew they should be for the 2K or 3K scratchpad configuration. + * - Unfortunately, to set the base addresses requires the use of the + * CPU_WRITE instruction, an instruction specific to GX. + * - Using the CPU_WRITE instruction requires the use of assembly to + * produce the appropriate op codes. + * - Assembly is something that is avoided in Durango because it is not + * platform independent. Some compilers do not support inline assembly. + * - Therefore Durango cannot use the CPU_WRITE instruction. + * - Therefore drivers using Durango must rely on the boot code to set + * the appropriate values. Durango uses this routine to check where + * the base addresses have been set. + * - Unfortunately, it is not as simple as using IO to check for 2K or 3K + * scratchpad size. In VSA1, even though the boot code may set it for + * 3K, SoftVGA comes along and resets it to 2K for it's use in text + * redraws. It used to be that the display driver would set it back + * to 3K. + * - So, the Durango code was changed to just always use 2K. + * - But, the XpressROM code sets it for 3K, and the newer versions of + * SoftVGA do not interfere with that, so then Durango needs to use + * the 3K values to work properly. + * - Therefore, Durango does somewhat of a kludge by writing to directly + * to the scratchpad at both the 2K and 3K locations, then performing + * a unobtrusive BLT that loads data into BB0 (the graphics engine + * always knows the true base). After the BLT, Durango looks to see + * which location changed to know where the base address is. + * - This is a relatively simple way to allow Durango to work on old + * and new platforms without using theCPU_WRITE instructions. + * + * To summarize, the BLT buffers are one of the most painful aspects of + * the GX graphics unit design, and have been removed from future designs + * (the graphics unit has its own dedicated RAM). Durango has tried to + * hide the BLT buffer use from the drivers. + *--------------------------------------------------------------------------- + */ +void +gu1_detect_blt_buffer_base(void) +{ + /* ASSUME 2K */ + + GFXbb0Base = BB0_BASE_2K; + GFXbb1Base = BB1_BASE_2K; + + /* CHECK IF SCRATCHPAD IS SET TO 3K OR 4K */ + /* Boot code should still set 3K values for 4K. */ + + if (gfx_gxm_config_read(GXM_CONFIG_GCR) & 0x08) { + /* WRITE DATA TO 3K LOCATION */ + + GFX_WAIT_BUSY; + WRITE_SCRATCH32(BB0_BASE_3K, 0xFEEDFACE); + + /* HAVE THE GRAPHICS UNIT STORE SOMETHING IN BB0 */ + + WRITE_REG32(GP_DST_XCOOR, 0x00000000); /* AT (0,0) */ + WRITE_REG32(GP_WIDTH, 0x00010004); /* 4x1 BLT */ + WRITE_REG16(GP_RASTER_MODE, 0x00AA); /* KEEP DST */ + WRITE_REG16(GP_BLIT_MODE, BM_READ_DST_FB0); /* STORE IN BB0 */ + + /* CHECK 3K LOCATION */ + /* Breaks if data happened to be 0xFEEDFACE - unlikely. */ + + GFX_WAIT_BUSY; + if (READ_SCRATCH32(BB0_BASE_3K) != 0xFEEDFACE) { + GFXbb0Base = BB0_BASE_3K; + GFXbb1Base = BB1_BASE_3K; + } + } +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu2.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu2.c new file mode 100644 index 000000000..93783281f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu2.c @@ -0,0 +1,2365 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu2.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: rndr_gu2.c $ + * + * This file contains routines to program the 2D acceleration hardware for + * the second generation graphics unit. + * + * Basic rendering routines (common to all Geode processors): + * gfx_set_bpp + * gfx_set_solid_pattern + * gfx_set_mono_pattern + * gfx_set_color_pattern + * gfx_set_solid_source + * gfx_set_mono_source + * gfx_set_raster_operation + * gfx_pattern_fill + * gfx_color_pattern_fill + * gfx_screen_to_screen_blt + * gfx_screen_to_screen_xblt + * gfx_color_bitmap_to_screen_blt + * gfx_color_bitmap_to_screen_xblt + * gfx_mono_bitmap_to_screen_blt + * gfx_bresenham_line + * gfx_wait_until_idle + * + * Extended rendering routines for second generation functionality: + * gfx2_set_source_stride + * gfx2_set_destination_stride + * gfx2_set_pattern_origins + * gfx2_set_source_transparency + * gfx2_set_alpha_mode + * gfx2_set_alpha_value + * gfx2_pattern_fill + * gfx2_color_pattern_fill + * gfx2_screen_to_screen_blt + * gfx2_mono_expand_blt + * gfx2_color_bitmap_to_screen_blt + * gfx2_mono_bitmap_to_screen_blt + * gfx2_bresenham_line + * gfx2_sync_to_vblank + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +void gu2_set_bpp(unsigned short bpp); +void gu2_set_solid_pattern(unsigned long color); +void gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparency); +void gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned long data2, unsigned long data3, + unsigned char transparency); +void gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8); +void gu2_set_solid_source(unsigned long color); +void gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned short transparent); +void gu2_set_pattern_flags(unsigned short flags); +void gu2_set_raster_operation(unsigned char rop); +void gu2_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height); +void gu2_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long *pattern); +void gu2_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height); +void gu2_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color); +void gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, + unsigned short height, + unsigned char *data, long pitch); +void gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, + unsigned short height, + unsigned char *data, long pitch, + unsigned long color); +void gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, + unsigned short height, unsigned char *data, + short pitch); +void gu2_text_blt(unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data); +void gu2_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags); +void gu2_wait_until_idle(void); +int gu2_test_blt_pending(void); + +/* SECOND GENERATION RENDERING ROUTINES */ + +void gu22_set_source_stride(unsigned short stride); +void gu22_set_destination_stride(unsigned short stride); +void gu22_set_pattern_origin(int x, int y); +void gu22_set_source_transparency(unsigned long color, unsigned long mask); +void gu22_set_alpha_mode(int mode); +void gu22_set_alpha_value(unsigned char value); +void gu22_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height); +void gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned long *pattern); +void gu22_screen_to_screen_blt(unsigned long srcoffset, + unsigned long dstoffset, unsigned short width, + unsigned short height, int flags); +void gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx, + unsigned short srcy, unsigned long dstoffset, + unsigned short width, unsigned short height, + int byte_packed); +void gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned long dstoffset, + unsigned short width, + unsigned short height, + unsigned char *data, short pitch); +void gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned long dstoffset, + unsigned short width, + unsigned short height, + unsigned char *data, short pitch); +void gu22_text_blt(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data); +void gu22_bresenham_line(unsigned long dstoffset, unsigned short length, + unsigned short initerr, unsigned short axialerr, + unsigned short diagerr, unsigned short flags); +void gu22_sync_to_vblank(void); +void gu2_reset_pitch(unsigned short pitch); + +#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING) +#define GU2_WAIT_BUSY while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY) +#define GU2_WAIT_HALF_EMPTY while(!(READ_GP32(MGP_BLT_STATUS) & MGP_BS_HALF_EMPTY)) + +/* PATTERN SWIZZLES */ + +#define WORD_SWIZZLE(x) (((x) << 16) | ((x) >> 16)) +#define BYTE_SWIZZLE(x) (((x) << 24) | ((x) >> 24) | (((x) << 8) & 0x00FF0000) | (((x) >> 8) & 0x0000FF00)) + +/* GLOBAL VARIABLES USED BY THE RENDERING ROUTINES */ + +unsigned long gu2_bpp; +unsigned long gu2_pitch = 1280; +unsigned long gu2_src_pitch = 1280; +unsigned long gu2_dst_pitch = 1280; +unsigned long gu2_xshift = 1; +unsigned long gu2_pattern_origin = 0; +unsigned long gu2_rop32; +unsigned long gu2_alpha32 = 0; +unsigned long gu2_alpha_value = 0; +unsigned long gu2_alpha_mode = 0; +unsigned long gu2_alpha_active = 0; +unsigned short gu2_alpha_blt_mode = 0; +unsigned short gu2_alpha_vec_mode = 0; +unsigned short gu2_blt_mode = 0; +unsigned short gu2_vector_mode = 0; +unsigned short gu2_bm_throttle = 0; +unsigned short gu2_vm_throttle = 0; +int gu2_current_line = 0; + +/*--------------------------------------------------------------------------- + * GFX_RESET_PITCH (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine resets all pitches in the graphics engine to one value. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu2_reset_pitch(unsigned short pitch) +#else +void +gfx_reset_pitch(unsigned short pitch) +#endif +{ + gu2_pitch = pitch; + gu2_dst_pitch = pitch; + gu2_src_pitch = pitch; +} + +/*--------------------------------------------------------------------------- + * GFX_SET_BPP + * + * This routine sets the bits per pixel value in the graphics engine. + * It is also stored in the static variable "gu2_bpp" to use in the future + * calls to the rendering routines. That variable contains the hardware + * specific value to load into the MGP_RASTER_MODE register. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu2_set_bpp(unsigned short bpp) +#else +void +gfx_set_bpp(unsigned short bpp) +#endif +{ + GFXbpp = bpp; + + /* COVERT TO BPP/FORMAT VALUE */ + /* Save in global to combine with ROP later. */ + /* Could write register here and then use byte access for */ + /* the ROP, but would need to set other 24 bits to make */ + /* sure all are set to their appropriate values. */ + + switch (bpp) { + case 8: + gu2_bpp = MGP_RM_BPPFMT_332; + gu2_xshift = 0; + break; + case 12: + gu2_bpp = MGP_RM_BPPFMT_4444; + gu2_xshift = 1; + break; + case 15: + gu2_bpp = MGP_RM_BPPFMT_1555; + gu2_xshift = 1; + break; + case 16: + gu2_bpp = MGP_RM_BPPFMT_565; + gu2_xshift = 1; + break; + case 32: + gu2_bpp = MGP_RM_BPPFMT_8888; + gu2_xshift = 2; + break; + } + + /* SET INITIAL ROP BASED ONLY ON BPP */ + /* Needs to be set before loading any pattern or source colors. */ + /* We must wait for BUSY because these bits are not pipelined */ + /* in the hardware. */ + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_RASTER_MODE, gu2_bpp); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_SOLID_SOURCE +// +// This routine is used to specify a solid source color. For the Xfree96 +// display driver, the source color is used to specify a planemask and the +// ROP is adjusted accordingly. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_set_solid_source(unsigned long color) +#else +void +gfx_set_solid_source(unsigned long color) +#endif +{ + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* WRITE REGISTERS TO SPECIFY SOURCE COLOR */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_COLOR_FG, color); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_MONO_SOURCE +// +// This routine is used to specify the monochrome source colors. +// It must be called *after* loading any pattern data (those routines +// clear the source flags). +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned short transparent) +#else +void +gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned short transparent) +#endif +{ + /* SET TRANSPARENCY FLAG */ + + GFXsourceFlags = transparent ? MGP_RM_SRC_TRANS : 0; + + /* WRITE COLOR VALUES */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_COLOR_FG, fgcolor); + WRITE_GP32(MGP_SRC_COLOR_BG, bgcolor); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_SOLID_PATTERN +// +// This routine is used to specify a solid pattern color. It is called +// before performing solid rectangle fills or more complicated BLTs that +// use a solid pattern color. +// +// The driver should always call "gfx_load_raster_operation" after a call +// to this routine to make sure that the pattern flags are set appropriately. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_set_solid_pattern(unsigned long color) +#else +void +gfx_set_solid_pattern(unsigned long color) +#endif +{ + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* SET PATTERN FLAGS */ + + GFXpatternFlags = 0; + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_bpp); + WRITE_GP32(MGP_PAT_COLOR_0, color); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_MONO_PATTERN +// +// This routine is used to specify a monochrome pattern. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparent) +#else +void +gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparent) +#endif +{ + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* SET PATTERN FLAGS */ + + if (transparent) + GFXpatternFlags = MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS; + else + GFXpatternFlags = MGP_RM_PAT_MONO; + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GFXpatternFlags); + WRITE_GP32(MGP_PAT_COLOR_0, bgcolor); + WRITE_GP32(MGP_PAT_COLOR_1, fgcolor); + WRITE_GP32(MGP_PAT_DATA_0, data0); + WRITE_GP32(MGP_PAT_DATA_1, data1); +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_COLOR_PATTERN +// +// This routine is used to specify a color pattern. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned long data2, unsigned long data3, + unsigned char transparent) +#else +void +gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned long data2, unsigned long data3, + unsigned char transparent) +#endif +{ + /* REMOVE */ +} + +/* +//--------------------------------------------------------------------------- +// GFX_LOAD_COLOR_PATTERN_LINE +// +// This routine is used to load a single line of a 8x8 color pattern. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8) +#else +void +gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8) +#endif +{ + unsigned long temp1, temp2, temp3, temp4; + + /* CLEAR TRANSPARENCY FLAG */ + + GFXsourceFlags = 0; + + /* SET PATTERN FLAGS */ + + GFXpatternFlags = MGP_RM_PAT_COLOR; + + /* OVERRIDE THE RASTER MODE REGISTER */ + /* If the pattern format is set to anything but color */ + /* before loading the registers, some of the data will */ + /* be duplicated according to the current mode. */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, + (gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR); + + /* LOAD THE PATTERN DATA */ + /* This routine is designed to work in tandem with gfx_pattern_fill. */ + /* It is used for cases when multiple BLTs with color pattern data */ + /* are desired on the same line. It would be inefficient to */ + /* repeatedly call gfx_color_pattern_fill for each single-line BLT. */ + /* So, we will simply replicate the pattern data across all available */ + /* lines such that the pattern y origin plays no part in the BLT. */ + + /* 8 BPP */ + + if (gu2_xshift == 0) { + pattern_8x8 += (y & 7) << 1; + temp1 = BYTE_SWIZZLE(pattern_8x8[0]); + temp2 = BYTE_SWIZZLE(pattern_8x8[1]); + WRITE_GP32(MGP_PAT_DATA_1, temp1); + WRITE_GP32(MGP_PAT_DATA_0, temp2); + WRITE_GP32(MGP_PAT_COLOR_1, temp1); + WRITE_GP32(MGP_PAT_COLOR_0, temp2); + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_3, temp1); + WRITE_GP32(MGP_PAT_COLOR_2, temp2); + WRITE_GP32(MGP_PAT_COLOR_5, temp1); + WRITE_GP32(MGP_PAT_COLOR_4, temp2); + } else if (gu2_xshift == 1) { + pattern_8x8 += (y & 7) << 2; + temp1 = WORD_SWIZZLE(pattern_8x8[0]); + temp2 = WORD_SWIZZLE(pattern_8x8[1]); + temp3 = WORD_SWIZZLE(pattern_8x8[2]); + temp4 = WORD_SWIZZLE(pattern_8x8[3]); + + WRITE_GP32(MGP_PAT_COLOR_1, temp1); + WRITE_GP32(MGP_PAT_COLOR_0, temp2); + WRITE_GP32(MGP_PAT_DATA_1, temp3); + WRITE_GP32(MGP_PAT_DATA_0, temp4); + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_5, temp1); + WRITE_GP32(MGP_PAT_COLOR_4, temp2); + WRITE_GP32(MGP_PAT_COLOR_3, temp3); + WRITE_GP32(MGP_PAT_COLOR_2, temp4); + } else { + pattern_8x8 += (y & 7) << 3; + + WRITE_GP32(MGP_PAT_COLOR_1, pattern_8x8[4]); + WRITE_GP32(MGP_PAT_COLOR_0, pattern_8x8[5]); + WRITE_GP32(MGP_PAT_DATA_1, pattern_8x8[6]); + WRITE_GP32(MGP_PAT_DATA_0, pattern_8x8[7]); + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_5, pattern_8x8[0]); + WRITE_GP32(MGP_PAT_COLOR_4, pattern_8x8[1]); + WRITE_GP32(MGP_PAT_COLOR_3, pattern_8x8[2]); + WRITE_GP32(MGP_PAT_COLOR_2, pattern_8x8[3]); + } +} + +/* +//--------------------------------------------------------------------------- +// GFX_SET_RASTER_OPERATION +// +// This routine loads the specified raster operation. It sets the pattern +// flags appropriately. +//--------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_set_raster_operation(unsigned char rop) +#else +void +gfx_set_raster_operation(unsigned char rop) +#endif +{ + gu2_blt_mode = 0; + + /* DISABLE ALPHA BLENDING */ + + gu2_alpha_active = 0; + + /* GENERATE 32-BIT VERSION OF ROP WITH PATTERN FLAGS */ + + gu2_rop32 = (unsigned long)rop | GFXpatternFlags | gu2_bpp; + + /* CHECK IF SOURCE FLAGS SHOULD BE MERGED */ + + if ((rop & 0x33) ^ ((rop >> 2) & 0x33)) + gu2_rop32 |= GFXsourceFlags; + else + gu2_blt_mode = 0x40; + + /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */ + /* True if even bits (0:2:4:6) do not equal the corresponding */ + /* even bits (1:3:5:7). */ + + if ((rop & 0x55) ^ ((rop >> 1) & 0x55)) { + gu2_blt_mode |= MGP_BM_DST_REQ; + gu2_vector_mode = MGP_VM_DST_REQ; + } else { + gu2_vector_mode = 0; + } +} + +/* +//---------------------------------------------------------------------------- +// GFX_PATTERN_FILL +// +// This routine is used to fill a rectangular region. The pattern must +// be previously loaded using one of GFX_load_*_pattern routines. Also, the +// raster operation must be previously specified using the +// "GFX_load_raster_operation" routine. +// +// X screen X position (left) +// Y screen Y position (top) +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height) +#else +void +gfx_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height) +#endif +{ + unsigned long offset = 0, size; + + size = (((unsigned long)width) << 16) | height; + + /* CALCULATE STARTING OFFSET */ + + offset = (unsigned long)y *gu2_pitch + (((unsigned long)x) << gu2_xshift); + + /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ + + if (GFXpatternFlags) { + /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ + + offset |= ((unsigned long)(x & 7)) << 26; + offset |= ((unsigned long)(y & 7)) << 29; + } + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + WRITE_GP32(MGP_DST_OFFSET, offset); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_pitch); + WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode); +} + +/* +//---------------------------------------------------------------------------- +// GFX_COLOR_PATTERN_FILL +// +// This routine is used to render a rectangle using the current raster +// operation and the specified color pattern. It allows an 8x8 color +// pattern to be rendered without multiple calls to the gfx_set_color_pattern +// and gfx_pattern_fill routines. +// +// X screen X position (left) +// Y screen Y position (top) +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *PATTERN pointer to 8x8 color pattern data +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long *pattern) +#else +void +gfx_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long *pattern) +#endif +{ + /* CALL GFX2 ROUTINE TO AVOID DUPLICATION OF CODE */ + + unsigned long offset = (unsigned long)y * gu2_pitch + + (((unsigned long)x) << gu2_xshift); + unsigned long origin = gu2_pattern_origin; + unsigned long pitch = gu2_dst_pitch; + + gfx2_set_pattern_origin(x, y); + gfx2_set_destination_stride((unsigned short)gu2_pitch); + gfx2_color_pattern_fill(offset, width, height, pattern); + + /* RESTORE GFX2 VALUES */ + + gu2_pattern_origin = origin; + gu2_dst_pitch = pitch; +} + +/* +//---------------------------------------------------------------------------- +// SCREEN TO SCREEN BLT +// +// This routine should be used to perform a screen to screen BLT when the +// ROP does not require destination data. +// +// SRCX screen X position to copy from +// SRCY screen Y position to copy from +// DSTX screen X position to copy to +// DSTY screen Y position to copy to +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height) +#else +void +gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height) +#endif +{ + unsigned long srcoffset, dstoffset, size; + unsigned short blt_mode; + + size = (((unsigned long)width) << 16) | height; + + /* CALCULATE THE DIRECTION OF THE BLT */ + + blt_mode = gu2_blt_mode | MGP_BM_SRC_FB; + if (dstx > srcx) { + blt_mode |= MGP_BM_NEG_XDIR; + srcx += width - 1; + dstx += width - 1; + } + if (dsty > srcy) { + blt_mode |= MGP_BM_NEG_YDIR; + srcy += height - 1; + dsty += height - 1; + } + + /* CALCULATE STARTING OFFSETS */ + + srcoffset = (unsigned long)srcy *gu2_pitch + + (((unsigned long)srcx) << gu2_xshift); + dstoffset = ((unsigned long)dsty * gu2_pitch + + (((unsigned long)dstx) << gu2_xshift)) & 0xFFFFFF; + + /* MERGE PATTERN INFORMATION */ + /* This must be done after the x and y coordinates have been updated, */ + /* as the x and y pattern origins correspond to the first ROPed pixel. */ + + if (GFXpatternFlags) { + /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ + + dstoffset |= ((unsigned long)(dstx & 7)) << 26; + dstoffset |= ((unsigned long)(dsty & 7)) << 29; + } + + /* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */ + /* This is a quirk of the hardware. */ + + if (blt_mode & MGP_BM_NEG_XDIR) { + srcoffset += (1 << gu2_xshift) - 1; + dstoffset += (1 << gu2_xshift) - 1; + } + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + WRITE_GP32(MGP_SRC_OFFSET, srcoffset); + WRITE_GP32(MGP_DST_OFFSET, dstoffset); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_pitch | (gu2_pitch << 16)); + WRITE_GP16(MGP_BLT_MODE, blt_mode); +} + +/* +//---------------------------------------------------------------------------- +// SCREEN TO SCREEN TRANSPARENT BLT +// +// This routine should be used to perform a screen to screen BLT when a +// specified color should by transparent. The only supported ROP is SRCCOPY. +// +// SRCX screen X position to copy from +// SRCY screen Y position to copy from +// DSTX screen X position to copy to +// DSTY screen Y position to copy to +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// COLOR transparent color +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color) +#else +void +gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color) +#endif +{ + unsigned long rop32; + + /* SAVE ORIGINAL RASTER MODE SETTINGS */ + + rop32 = gu2_rop32; + + /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */ + /* Match GU1 implementation that only allows SRCCOPY for the ROP. */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_COLOR_FG, color); + WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF); + + /* SET GLOBAL RASTER SETTINGS */ + /* This is needed, as the screen-to-screen BLT */ + /* routine will overwrite the raster mode register. */ + + gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC; + + /* CALL NORMAL SCREEN TO SCREEN BLT ROUTINE */ + + gfx_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height); + + /* RESTORE GLOBAL RASTER SETTINGS */ + + gu2_rop32 = rop32; +} + +/* +//---------------------------------------------------------------------------- +// COLOR BITMAP TO SCREEN BLT +// +// This routine transfers color bitmap data to the screen. +// +// SRCX X offset within source bitmap +// SRCY Y offset within source bitmap +// DSTX screen X position to render data +// DSTY screen Y position to render data +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *DATA pointer to bitmap data +// PITCH pitch of bitmap data (bytes between scanlines) +// +// Transparency is handled by another routine. +//---------------------------------------------------------------------------- +*/ + +#if GFX_2DACCEL_DYNAMIC +void +gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch) +#else +void +gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch) +#endif +{ + unsigned long dstoffset, srcoffset, size, bytes; + unsigned long offset, temp_offset; + unsigned long dword_bytes, bytes_extra; + unsigned short blt_mode; + + blt_mode = gu2_blt_mode | MGP_BM_SRC_FB; + size = (((unsigned long)width) << 16) | 1; + + /* CALCULATE STARTING OFFSETS */ + + offset = (unsigned long)srcy *pitch + ((unsigned long)srcx << gu2_xshift); + + dstoffset = (unsigned long)dsty *gu2_pitch + + (((unsigned long)dstx) << gu2_xshift); + + /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ + + if (GFXpatternFlags) { + /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ + + dstoffset |= ((unsigned long)(dstx & 7)) << 26; + dstoffset |= ((unsigned long)(dsty & 7)) << 29; + } + + bytes = width << gu2_xshift; + dword_bytes = bytes & ~0x3L; + bytes_extra = bytes & 0x3L; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + /* The source offset is always 0 since we allow misaligned dword reads. */ + /* We must wait for BLT busy because the GP may be executing a screen */ + /* to screen BLT from the scratchpad area. */ + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_pitch); + + /* WRITE DATA ONE LINE AT A TIME */ + /* For speed reasons, data is written to an offscreen scratch area and then */ + /* BLTed using a screen to screen BLT. This is similar to the GX1 BLT buffers, but */ + /* slightly more efficient in that we can queue up data while the GP is rendering */ + /* a line. */ + + while (height--) { + temp_offset = offset; + srcoffset = gfx_gx2_scratch_base; + if (gu2_current_line) + srcoffset += 8192; + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_OFFSET, srcoffset); + WRITE_GP32(MGP_DST_OFFSET, dstoffset); + dstoffset += gu2_pitch; + dstoffset += 0x20000000; + + WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data, temp_offset); + if (bytes_extra) { + temp_offset += dword_bytes; + srcoffset += dword_bytes; + WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data, + temp_offset); + } + WRITE_GP16(MGP_BLT_MODE, blt_mode); + offset += pitch; + gu2_current_line = 1 - gu2_current_line; + } +} + +/* +//---------------------------------------------------------------------------- +// COLOR BITMAP TO SCREEN TRANSPARENT BLT +// +// This routine transfers color bitmap data to the screen with transparency. +// The transparent color is specified. The only supported ROP is SRCCOPY, +// meaning that transparency cannot be applied if the ROP requires +// destination data (this is a hardware restriction). +// +// SRCX X offset within source bitmap +// SRCY Y offset within source bitmap +// DSTX screen X position to render data +// DSTY screen Y position to render data +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *DATA pointer to bitmap data +// PITCH pitch of bitmap data (bytes between scanlines) +// COLOR transparent color +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch, + unsigned long color) +#else +void +gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, long pitch, + unsigned long color) +#endif +{ + unsigned long rop32; + + /* SAVE EXISTING RASTER MODE SETTINGS */ + + rop32 = gu2_rop32; + + /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */ + /* Match GU1 implementation that only allows SRCCOPY for the ROP. */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_COLOR_FG, color); + WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF); + + /* SET GLOBAL RASTER SETTINGS */ + /* This is needed, as the screen-to-screen BLT */ + /* routine will overwrite the raster mode register. */ + + gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC; + + /* CALL NORMAL COLOR BITMAP TO SCREEN BLT ROUTINE */ + + gfx_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height, + data, pitch); + + /* RESTORE RASTER SETTINGS */ + + gu2_rop32 = rop32; +} + +/* +//---------------------------------------------------------------------------- +// MONOCHROME BITMAP TO SCREEN BLT +// +// This routine transfers monochrome bitmap data to the screen. +// +// SRCX X offset within source bitmap +// SRCY Y offset within source bitmap +// DSTX screen X position to render data +// DSTY screen Y position to render data +// WIDTH width of rectangle, in pixels +// HEIGHT height of rectangle, in scanlines +// *DATA pointer to bitmap data +// PITCH pitch of bitmap data (bytes between scanlines) +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, short pitch) +#else +void +gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, short pitch) +#endif +{ + unsigned long dstoffset, size, bytes; + unsigned long offset, temp_offset, temp1 = 0, temp2 = 0; + unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; + unsigned long shift = 0; + + size = (((unsigned long)width) << 16) | height; + + /* CALCULATE STARTING OFFSETS */ + + offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3); + + dstoffset = (unsigned long)dsty *gu2_pitch + + (((unsigned long)dstx) << gu2_xshift); + + /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ + + if (GFXpatternFlags) { + /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ + + dstoffset |= ((unsigned long)(dstx & 7)) << 26; + dstoffset |= ((unsigned long)(dsty & 7)) << 29; + } + + bytes = ((srcx & 7) + width + 7) >> 3; + fifo_lines = bytes >> 5; + dwords_extra = (bytes & 0x0000001Cl) >> 2; + bytes_extra = bytes & 0x00000003l; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + /* The source offset is always 0 since we allow misaligned dword reads. */ + /* Need to wait for busy instead of pending, since hardware clears */ + /* the host data FIFO at the beginning of a BLT. */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26); + WRITE_GP32(MGP_DST_OFFSET, dstoffset); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_pitch); + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST | MGP_BM_SRC_MONO); + + /* WAIT FOR BLT TO BE LATCHED */ + + GU2_WAIT_PENDING; + + /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */ + + while (height--) { + temp_offset = offset; + + /* WRITE ALL FULL FIFO LINES */ + + for (i = 0; i < fifo_lines; i++) { + GU2_WAIT_HALF_EMPTY; + WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1); + temp_offset += 32; + } + + /* WRITE ALL FULL DWORDS */ + + GU2_WAIT_HALF_EMPTY; + if (dwords_extra) { + WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data, + temp_offset, temp1); + temp_offset += (dwords_extra << 2); + } + + /* WRITE REMAINING BYTES */ + + shift = 0; + if (bytes_extra) + WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, + temp_offset, temp1, temp2); + + offset += pitch; + } +} + +/*--------------------------------------------------------------------------- + * GFX_TEXT_BLT + * + * This routine is similar to the gfx_mono_bitmap_to_screen_blt routine + * but assumes that source data is byte-packed. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu2_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, + unsigned short height, unsigned char *data) +#else +void +gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, + unsigned short height, unsigned char *data) +#endif +{ + unsigned long size, bytes; + unsigned long dstoffset, temp1 = 0, temp2 = 0, temp_offset = 0; + unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; + unsigned long shift; + + size = (((unsigned long)width) << 16) | height; + + dstoffset = (unsigned long)dsty *gu2_pitch + + (((unsigned long)dstx) << gu2_xshift); + + /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ + + if (GFXpatternFlags) { + /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ + + dstoffset |= ((unsigned long)(dstx & 7)) << 26; + dstoffset |= ((unsigned long)(dsty & 7)) << 29; + } + + /* CALCULATE STARTING OFFSETS */ + + bytes = ((width + 7) >> 3) * height; + fifo_lines = bytes >> 5; + dwords_extra = (bytes & 0x0000001Cl) >> 2; + bytes_extra = bytes & 0x00000003l; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + WRITE_GP32(MGP_SRC_OFFSET, 0); + WRITE_GP32(MGP_DST_OFFSET, dstoffset); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_pitch); + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST | + MGP_BM_SRC_BP_MONO); + + /* WAIT FOR BLT TO BE LATCHED */ + + GU2_WAIT_PENDING; + + /* WRITE ALL FULL FIFO LINES */ + + for (i = 0; i < fifo_lines; i++) { + GU2_WAIT_HALF_EMPTY; + WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1); + temp_offset += 32; + } + + /* WRITE ALL FULL DWORDS */ + + if (dwords_extra || bytes_extra) { + GU2_WAIT_HALF_EMPTY; + if (dwords_extra) { + WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data, + temp_offset, temp1); + temp_offset += (dwords_extra << 2); + } + if (bytes_extra) { + shift = 0; + WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, + temp_offset, temp1, temp2); + } + } +} + +/* +//---------------------------------------------------------------------------- +// BRESENHAM LINE +// +// This routine draws a vector using the specified Bresenham parameters. +// Currently this file does not support a routine that accepts the two +// endpoints of a vector and calculates the Bresenham parameters. If it +// ever does, this routine is still required for vectors that have been +// clipped. +// +// X screen X position to start vector +// Y screen Y position to start vector +// LENGTH length of the vector, in pixels +// INITERR Bresenham initial error term +// AXIALERR Bresenham axial error term +// DIAGERR Bresenham diagonal error term +// FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC +//---------------------------------------------------------------------------- +*/ +#if GFX_2DACCEL_DYNAMIC +void +gu2_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +#else +void +gfx_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +#endif +{ + unsigned long offset; + unsigned long data1 = (((unsigned long)axialerr) << 16) | diagerr; + unsigned long data2 = (((unsigned long)length) << 16) | initerr; + unsigned short vector_mode = gu2_vector_mode | flags; + + /* CALCULATE STARTING OFFSET */ + + offset = (unsigned long)y *gu2_pitch + (((unsigned long)x) << gu2_xshift); + + /* CHECK NULL LENGTH */ + + if (!length) + return; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + WRITE_GP32(MGP_DST_OFFSET, offset); + WRITE_GP32(MGP_VEC_ERR, data1); + WRITE_GP32(MGP_VEC_LEN, data2); + WRITE_GP32(MGP_STRIDE, gu2_pitch); + WRITE_GP32(MGP_VECTOR_MODE, vector_mode); +} + +/*--------------------------------------------------------------------------- + * GFX_WAIT_UNTIL_IDLE + * + * This routine waits until the graphics engine is idle. This is required + * before allowing direct access to the frame buffer. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu2_wait_until_idle(void) +#else +void +gfx_wait_until_idle(void) +#endif +{ + while (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY) ; +} + +/*--------------------------------------------------------------------------- + * GFX_TEST_BLT_PENDING + * + * This routine returns 1 if a BLT is pending, meaning that a call to + * perform a rendering operation would stall. Otherwise it returns 0. + * It is used by Darwin during random testing to only start a BLT + * operation when it knows the Durango routines won't spin on graphics + * (so Darwin can continue to do frame buffer reads and writes). + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +int +gu2_test_blt_pending(void) +#else +int +gfx_test_blt_pending(void) +#endif +{ + if (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING) + return (1); + return (0); +} + +/*--------------------------------------------------------------------------- + * NEW ROUTINES FOR REDCLOUD + *--------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------- + * GFX2_SET_SOURCE_STRIDE + * + * This routine sets the stride to be used in successive screen to screen + * BLTs (used by gfx2_screen_to_screen_blt and gfx2_mono_expand_blt). + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_set_source_stride(unsigned short stride) +#else +void +gfx2_set_source_stride(unsigned short stride) +#endif +{ + /* SAVE STRIDE TO BE USED LATER */ + + gu2_src_pitch = (unsigned long)stride; +} + +/*--------------------------------------------------------------------------- + * GFX2_SET_DESTINATION_STRIDE + * + * This routine sets the stride used when rendering to the screen. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_set_destination_stride(unsigned short stride) +#else +void +gfx2_set_destination_stride(unsigned short stride) +#endif +{ + /* SAVE STRIDE TO BE USED LATER */ + + gu2_dst_pitch = (unsigned long)stride; +} + +/*--------------------------------------------------------------------------- + * GFX2_SET_PATTERN_ORIGIN + * + * This routine sets the origin within an 8x8 pattern. It is needed if + * using a monochrome or color pattern (not used for a solid pattern). + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_set_pattern_origin(int x, int y) +#else +void +gfx2_set_pattern_origin(int x, int y) +#endif +{ + /* STORE IN FORMAT THAT CAN BE COMBINED WITH THE DESTINATION OFFSET */ + + gu2_pattern_origin = (((unsigned long)(x & 7)) << 26) | + (((unsigned long)(y & 7)) << 29); +} + +/*--------------------------------------------------------------------------- + * GFX2_SET_SOURCE_TRANSPARENCY + * + * This routine sets the source transparency color and mask to be used + * in future rendering operations. If both the color and mask are set + * to zero (normally completely transparent), those values indicate that + * transparency should be disabled. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_set_source_transparency(unsigned long color, unsigned long mask) +#else +void +gfx2_set_source_transparency(unsigned long color, unsigned long mask) +#endif +{ + /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_COLOR_FG, color); + WRITE_GP32(MGP_SRC_COLOR_BG, mask); + + /* SET TRANSPARENCY FLAG */ + + GFXsourceFlags = (color || mask) ? MGP_RM_SRC_TRANS : 0; +} + +/*--------------------------------------------------------------------------- + * GFX2_SET_ALPHA_MODE + * + * This routine sets the alpha blending mode to be used in successive + * rendering operations. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_set_alpha_mode(int mode) +#else +void +gfx2_set_alpha_mode(int mode) +#endif +{ + /* SAVE ALPHA MODE FOR LATER */ + + gu2_alpha_mode = mode; +} + +/*--------------------------------------------------------------------------- + * GFX2_SET_ALPHA_VALUE + * + * This routine sets the alpha value to be used with certain alpha blending + * modes (ALPHA_MODE_BLEND). + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_set_alpha_value(unsigned char value) +#else +void +gfx2_set_alpha_value(unsigned char value) +#endif +{ + /* SAVE ALPHA VALUE TO BE USED LATER */ + + gu2_alpha_value = (unsigned long)value; + + /* SET GLOBAL FLAG */ + /* gfx2_* routines will use this flag to program alpha values */ + /* appropriately. Normal gfx_* routines will always write */ + /* the current ROP settings. In this way, the alpha mode */ + /* affects only second generation routines. */ + + gu2_alpha_active = 1; + + switch (gu2_alpha_mode) { + case ALPHA_MODE_BLEND: + + /* GENERATE 32-BIT VERSION OF RASTER MODE REGISTER */ + /* Pattern data is not involved in the operation. */ + + gu2_alpha32 = gu2_alpha_value | gu2_bpp; + + /* HANDLE SPECIAL CASES FOR ENDPOINTS */ + /* The 8-bit hardware alpha value is always */ + /* interpreted as a fraction. Consequently, there */ + /* is no way to use values of 255 or 0 to exclude */ + /* one of the inputs. */ + + switch (gu2_alpha_value) { + /* DESTINATION ONLY */ + /* Operation is alpha * A, where A is destination */ + /* and alpha is 1. */ + + case 0: + + gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 | + MGP_RM_ALPHA_TIMES_A | + MGP_RM_ALPHA_TO_RGB | MGP_RM_DEST_FROM_CHAN_A; + break; + + /* SOURCE ONLY */ + /* Operation is alpha * A, where A is source and */ + /* alpha is 1. */ + + case 255: + + gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 | + MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_TIMES_A; + break; + + /* DEFAULT */ + /* Operation is alpha * A + (1 - alpha) * B; */ + /* A is source, B is destination and alpha is the */ + /* programmed 8-bit value. */ + + default: + + gu2_alpha32 |= MGP_RM_SELECT_ALPHA_R | + MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_A_PLUS_BETA_B; + + } + + /* CHECK IF SOURCE INFORMATION SHOULD BE MERGED */ + /* Alpha value of 0 indicates destination only. */ + + if (gu2_alpha_value != 0) + gu2_alpha32 |= GFXsourceFlags; + + /* SET FLAG FOR DESTINATION DATA IF NECESSARY */ + /* Alpha value of 255 indicates no destination */ + + if (gu2_alpha_value != 255) { + gu2_alpha_blt_mode = MGP_BM_DST_REQ; + gu2_alpha_vec_mode = MGP_VM_DST_REQ; + } + + break; + } +} + +/*--------------------------------------------------------------------------- + * GFX2_PATTERN_FILL + * + * This routine is similar to the gfx_pattern_fill routine, but allows the + * use of an arbitrary destination stride. The rendering position is + * also specified as an offset instead of an (x,y) position. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height) +#else +void +gfx2_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height) +#endif +{ + unsigned long size; + + size = (((unsigned long)width) << 16) | height; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); + WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; +} + +/*--------------------------------------------------------------------------- + * GFX2_COLOR_PATTERN_FILL + * + * This routine is used to render a rectangle using the current raster + * operation and the specified color pattern. It allows an 8x8 color + * pattern to be rendered without multiple calls to the gfx_set_color_pattern + * and gfx_pattern_fill routines. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned long *pattern) +#else +void +gfx2_color_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned long *pattern) +#endif +{ + int pass; + unsigned long lines, size, patxorigin, patoffset; + + /* ONLY USE HW PATTERN ORIGIN FOR THE X DIRECTION */ + /* Y direction handled by referencing proper location in pattern data. */ + + patxorigin = (gu2_pattern_origin) & 0x1C000000; + + /* OVERRIDE PATTERN FLAGS IN ROP TO FORCE COLOR PATTERN */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, + (gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR); + + /* ATTEMPT TO OPTIMIZE */ + /* If possible, we can perform the pattern fill in only a few passes */ + /* This is performed by multiplying the pitch by an appropriate amount. */ + /* Consequently, if the multiplied pitch exceeds 16 bits, this */ + /* optimization is impossible. */ + + if ((gu2_dst_pitch << (gu2_xshift + 1)) <= 0xFFFF) { + /* HANDLE VARIOUS COLOR DEPTHS DIFFERENTLY */ + + switch (gu2_xshift) { + case 0: /* 8 BPP */ + + /* TWO PASSES FOR 8 BPP */ + /* Render every other line per pass by doubling the pitch. */ + + patoffset = (gu2_pattern_origin >> 28) & 0x0E; + for (pass = 0; pass < 2; pass++) { + /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); + lines = (height + 1 - pass) >> 1; + if (!lines) + break; + size = (((unsigned long)width) << 16) | lines; + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 1); + WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_DATA_0, BYTE_SWIZZLE(pattern[patoffset + 1])); + patoffset = (patoffset + 4) & 0x0E; + WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_0, BYTE_SWIZZLE(pattern[patoffset + 1])); + patoffset = (patoffset + 4) & 0x0E; + + /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ + /* Those registers are not pipelined. */ + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_2, BYTE_SWIZZLE(pattern[patoffset + 1])); + patoffset = (patoffset + 4) & 0x0E; + WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_4, BYTE_SWIZZLE(pattern[patoffset + 1])); + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; + + /* ADJUST FOR NEXT PASS */ + + dstoffset += gu2_dst_pitch; + patoffset = (patoffset + 6) & 0x0E; + } + break; + + case 1: /* 12, 15, OR 16 BPP */ + + /* FOUR PASSES FOR 16 BPP */ + /* Render every 4th line per pass by quadrupling the pitch. */ + + patoffset = (gu2_pattern_origin >> 27) & 0x1C; + for (pass = 0; pass < 4; pass++) { + /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); + lines = (height + 3 - pass) >> 2; + if (!lines) + break; + size = (((unsigned long)width) << 16) | lines; + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 2); + WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_0, WORD_SWIZZLE(pattern[patoffset + 1])); + WRITE_GP32(MGP_PAT_DATA_1, WORD_SWIZZLE(pattern[patoffset + 2])); + WRITE_GP32(MGP_PAT_DATA_0, WORD_SWIZZLE(pattern[patoffset + 3])); + patoffset = (patoffset + 16) & 0x1C; + + /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ + /* Those registers are not pipelined. */ + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_4, WORD_SWIZZLE(pattern[patoffset + 1])); + WRITE_GP32(MGP_PAT_COLOR_3, WORD_SWIZZLE(pattern[patoffset + 2])); + WRITE_GP32(MGP_PAT_COLOR_2, WORD_SWIZZLE(pattern[patoffset + 3])); + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; + + /* ADJUST FOR NEXT PASS */ + + dstoffset += gu2_dst_pitch; + patoffset = (patoffset + 20) & 0x1C; + } + break; + + case 2: /* 32 BPP */ + + /* EIGHT PASSES FOR 32 BPP */ + /* Render every 8th line per pass by setting pitch * 8. */ + + patoffset = (gu2_pattern_origin >> 26) & 0x38; + for (pass = 0; pass < 8; pass++) { + /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); + lines = (height + 7 - pass) >> 3; + if (!lines) + break; + size = (((unsigned long)width) << 16) | lines; + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 3); + WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]); + WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]); + WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]); + WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]); + + /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ + /* Those registers are not pipelined. */ + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]); + WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]); + WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]); + WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]); + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; + + /* ADJUST FOR NEXT PASS */ + + dstoffset += gu2_dst_pitch; + patoffset = (patoffset + 8) & 0x38; + } + break; + } + } + + else { + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); + + switch (gu2_xshift) { + case 0: /* 8 BPP - 4 LINES PER PASS */ + + patoffset = (gu2_pattern_origin >> 28) & 0x0E; + while (height) { + lines = height > 4 ? 4 : height; + + /* CAN WRITE SOME REGISTERS WHILE PENDING */ + + WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); + WRITE_GP32(MGP_WID_HEIGHT, + (((unsigned long)width) << 16) | lines); + WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_DATA_0, BYTE_SWIZZLE(pattern[patoffset + 1])); + patoffset = (patoffset + 2) & 0x0E; + WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_0, BYTE_SWIZZLE(pattern[patoffset + 1])); + patoffset = (patoffset + 2) & 0x0E; + + /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ + /* Those registers are not pipelined. */ + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_2, BYTE_SWIZZLE(pattern[patoffset + 1])); + patoffset = (patoffset + 2) & 0x0E; + WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_4, BYTE_SWIZZLE(pattern[patoffset + 1])); + patoffset = (patoffset + 2) & 0x0E; + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); + + /* ADJUST FOR NEXT PASS */ + + dstoffset += gu2_dst_pitch << 2; + height -= (unsigned short)lines; + } + break; + + case 1: /* 12, 15 AND 16 BPP - 2 LINES PER PASS */ + + patoffset = (gu2_pattern_origin >> 27) & 0x1C; + while (height) { + lines = height > 2 ? 2 : height; + + /* CAN WRITE SOME REGISTERS WHILE PENDING */ + + WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); + WRITE_GP32(MGP_WID_HEIGHT, + (((unsigned long)width) << 16) | lines); + WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_0, WORD_SWIZZLE(pattern[patoffset + 1])); + WRITE_GP32(MGP_PAT_DATA_1, WORD_SWIZZLE(pattern[patoffset + 2])); + WRITE_GP32(MGP_PAT_DATA_0, WORD_SWIZZLE(pattern[patoffset + 3])); + patoffset = (patoffset + 4) & 0x1C; + + /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ + /* Those registers are not pipelined. */ + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset])); + WRITE_GP32(MGP_PAT_COLOR_4, WORD_SWIZZLE(pattern[patoffset + 1])); + WRITE_GP32(MGP_PAT_COLOR_3, WORD_SWIZZLE(pattern[patoffset + 2])); + WRITE_GP32(MGP_PAT_COLOR_2, WORD_SWIZZLE(pattern[patoffset + 3])); + patoffset = (patoffset + 4) & 0x1C; + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); + + /* ADJUST FOR NEXT PASS */ + + dstoffset += gu2_dst_pitch << 1; + height -= (unsigned short)lines; + } + break; + + case 2: /* 32 BPP - 1 LINE PER PASS */ + + patoffset = (gu2_pattern_origin >> 26) & 0x38; + while (height) { + /* CAN WRITE SOME REGISTERS WHILE PENDING */ + + WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); + WRITE_GP32(MGP_WID_HEIGHT, (((unsigned long)width) << 16) | 1l); + WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]); + WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]); + WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]); + WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]); + + /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ + /* Those registers are not pipelined. */ + + GU2_WAIT_BUSY; + WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]); + WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]); + WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]); + WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]); + patoffset = (patoffset + 8) & 0x38; + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); + + /* ADJUST FOR NEXT PASS */ + + dstoffset += gu2_dst_pitch; + height--; + } + break; + } + + } + +} + +/*--------------------------------------------------------------------------- + * GFX2_SCREEN_TO_SCREEN_BLT + * + * This routine is similar to the gfx_screen_to_screen_blt routine but + * allows the use of arbitrary source and destination strides and alpha + * blending. It also allows the use of an arbitrary ROP with transparency. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset, + unsigned short width, unsigned short height, + int flags) +#else +void +gfx2_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset, + unsigned short width, unsigned short height, + int flags) +#endif +{ + unsigned long size, xbytes; + unsigned short blt_mode; + + size = (((unsigned long)width) << 16) | height; + + /* USE ALPHA SETTINGS, IF REQUESTED */ + + if (gu2_alpha_active) + blt_mode = gu2_alpha_blt_mode | MGP_BM_SRC_FB; + + else + blt_mode = gu2_blt_mode | MGP_BM_SRC_FB; + + /* CALCULATE THE DIRECTION OF THE BLT */ + /* Using offsets, so flags from the calling routine are needed. */ + + if (flags & 1) { + xbytes = (width - 1) << gu2_xshift; + srcoffset += xbytes; + dstoffset += xbytes; + blt_mode |= MGP_BM_NEG_XDIR; + } + if (flags & 2) { + srcoffset += (height - 1) * gu2_src_pitch; + dstoffset += (height - 1) * gu2_dst_pitch; + blt_mode |= MGP_BM_NEG_YDIR; + } + + /* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */ + /* This is a quirk of the hardware. */ + + if (blt_mode & MGP_BM_NEG_XDIR) { + srcoffset += (1 << gu2_xshift) - 1; + dstoffset += (1 << gu2_xshift) - 1; + } + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + + if (gu2_alpha_active) { + WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); + } else { + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + } + + WRITE_GP32(MGP_SRC_OFFSET, srcoffset); + WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16)); + WRITE_GP16(MGP_BLT_MODE, blt_mode | gu2_bm_throttle); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; +} + +/*--------------------------------------------------------------------------- + * GFX2_MONO_EXPAND_BLT + * + * This routine is similar to the gfx2_screen_to_screen_blt routine but + * expands monochrome data stored in graphics memory. + * WARNING: This routine assumes that the regions in graphics memory + * will not overlap, and therefore does not check the BLT direction. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx, + unsigned short srcy, unsigned long dstoffset, + unsigned short width, unsigned short height, + int byte_packed) +#else +void +gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx, + unsigned short srcy, unsigned long dstoffset, + unsigned short width, unsigned short height, + int byte_packed) +#endif +{ + unsigned long size, srcoffset; + unsigned short blt_mode; + + size = (((unsigned long)width) << 16) | height; + + /* CALCULATE SOURCE OFFSET */ + + srcoffset = srcbase + (unsigned long)srcy *gu2_src_pitch; + + srcoffset += srcx >> 3; + srcoffset |= ((unsigned long)srcx & 7) << 26; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + + if (gu2_alpha_active) { + blt_mode = gu2_alpha_blt_mode; + + WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); + } else { + blt_mode = gu2_blt_mode; + + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + } + + if (byte_packed) + blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_BP_MONO | gu2_bm_throttle; + else + blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_MONO | gu2_bm_throttle; + + WRITE_GP32(MGP_SRC_OFFSET, srcoffset); + WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16)); + WRITE_GP16(MGP_BLT_MODE, blt_mode); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; +} + +/*--------------------------------------------------------------------------- + * GFX2_COLOR_BITMAP_TO_SCREEN_BLT + * + * This routine is similar to the gfx_color_bitmap_to_screen_blt routine + * but allows the use of an arbitrary destination stride and alpha blending. + * It also allows the use of an arbitrary ROP with transparency. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data, + short pitch) +#else +void +gfx2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data, + short pitch) +#endif +{ + unsigned long size, bytes; + unsigned long offset, temp_offset; + unsigned long srcoffset, dword_bytes, bytes_extra; + unsigned short blt_mode; + + size = (((unsigned long)width) << 16) | 1; + + /* CALCULATE STARTING OFFSETS */ + + offset = (unsigned long)srcy *pitch + ((unsigned long)srcx << gu2_xshift); + + dstoffset |= gu2_pattern_origin; + + bytes = width << gu2_xshift; + dword_bytes = bytes & ~0x3L; + bytes_extra = bytes & 0x3L; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + /* The source offset is always 0 since we allow misaligned dword reads. */ + /* We must wait for BLT busy because the GP may be executing a screen */ + /* to screen BLT from the scratchpad area. */ + + GU2_WAIT_BUSY; + + if (gu2_alpha_active) { + blt_mode = gu2_alpha_blt_mode; + + WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); + } else { + blt_mode = gu2_blt_mode; + + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + } + blt_mode |= MGP_BM_SRC_FB | gu2_bm_throttle; + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; + + WRITE_GP32(MGP_WID_HEIGHT, size); + + /* WRITE DATA ONE LINE AT A TIME */ + /* For speed reasons, data is written to an offscreen scratch area and then */ + /* BLTed using a screen to screen BLT. This is similar to the GX1 BLT buffers, but */ + /* slightly more efficient in that we can queue up data while the GP is rendering */ + /* a line. */ + + while (height--) { + temp_offset = offset; + srcoffset = gfx_gx2_scratch_base; + if (gu2_current_line) + srcoffset += 8192; + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_OFFSET, srcoffset); + WRITE_GP32(MGP_DST_OFFSET, dstoffset); + dstoffset += gu2_dst_pitch; + dstoffset += 0x20000000; + + WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data, temp_offset); + if (bytes_extra) { + temp_offset += dword_bytes; + srcoffset += dword_bytes; + WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data, + temp_offset); + } + WRITE_GP16(MGP_BLT_MODE, blt_mode); + offset += pitch; + gu2_current_line = 1 - gu2_current_line; + } +} + +/*--------------------------------------------------------------------------- + * GFX2_TEXT_BLT + * + * This routine is similar to the gfx2_mono_bitmap_to_screen_blt routine + * but assumes that source data is byte-packed. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_text_blt(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data) +#else +void +gfx2_text_blt(unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data) +#endif +{ + unsigned long size, bytes; + unsigned long temp1 = 0, temp2 = 0, temp_offset = 0; + unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; + unsigned long shift; + unsigned short blt_mode; + + size = (((unsigned long)width) << 16) | height; + + /* CALCULATE STARTING OFFSETS */ + + bytes = ((width + 7) >> 3) * height; + fifo_lines = bytes >> 5; + dwords_extra = (bytes & 0x0000001Cl) >> 2; + bytes_extra = bytes & 0x00000003l; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + + GU2_WAIT_PENDING; + + if (gu2_alpha_active) { + blt_mode = gu2_alpha_blt_mode; + + WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); + } else { + blt_mode = gu2_blt_mode; + + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + } + + WRITE_GP32(MGP_SRC_OFFSET, 0); + WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); + WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST | + MGP_BM_SRC_BP_MONO | gu2_bm_throttle); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; + + /* WAIT FOR BLT TO BE LATCHED */ + + GU2_WAIT_PENDING; + + /* WRITE ALL FULL FIFO LINES */ + + for (i = 0; i < fifo_lines; i++) { + GU2_WAIT_HALF_EMPTY; + WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1); + temp_offset += 32; + } + + /* WRITE ALL FULL DWORDS */ + + if (dwords_extra || bytes_extra) { + GU2_WAIT_HALF_EMPTY; + if (dwords_extra) { + WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data, + temp_offset, temp1); + temp_offset += (dwords_extra << 2); + } + if (bytes_extra) { + shift = 0; + WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, + temp_offset, temp1, temp2); + } + } +} + +/*--------------------------------------------------------------------------- + * GFX2_MONO_BITMAP_TO_SCREEN_BLT + * + * This routine is similar to the gfx_mono_bitmap_to_screen_blt routine + * but allows the use of an arbitrary destination stride and alpha blending. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data, + short pitch) +#else +void +gfx2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned long dstoffset, unsigned short width, + unsigned short height, unsigned char *data, + short pitch) +#endif +{ + unsigned long size, bytes; + unsigned long offset, temp_offset, temp1 = 0, temp2 = 0; + unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; + unsigned long shift = 0; + unsigned short blt_mode; + + size = (((unsigned long)width) << 16) | height; + + /* CALCULATE STARTING OFFSETS */ + + offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3); + + bytes = ((srcx & 7) + width + 7) >> 3; + fifo_lines = bytes >> 5; + dwords_extra = (bytes & 0x0000001Cl) >> 2; + bytes_extra = bytes & 0x00000003l; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + + GU2_WAIT_PENDING; + + if (gu2_alpha_active) { + blt_mode = gu2_alpha_blt_mode; + + WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); + } else { + blt_mode = gu2_blt_mode; + + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + } + + WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26); + WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); + WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST | + MGP_BM_SRC_MONO | gu2_bm_throttle); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; + + /* WAIT FOR BLT TO BE LATCHED */ + + GU2_WAIT_PENDING; + + /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */ + + while (height--) { + temp_offset = offset; + + /* WRITE ALL FULL FIFO LINES */ + + for (i = 0; i < fifo_lines; i++) { + GU2_WAIT_HALF_EMPTY; + WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1); + temp_offset += 32; + } + + /* WRITE ALL FULL DWORDS */ + + GU2_WAIT_HALF_EMPTY; + if (dwords_extra) + WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data, + temp_offset, temp1); + temp_offset += (dwords_extra << 2); + + /* WRITE REMAINING BYTES */ + + shift = 0; + if (bytes_extra) + WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, + temp_offset, temp1, temp2); + + offset += pitch; + } +} + +/*--------------------------------------------------------------------------- + * GFX2_BRESENHAM_LINE + * + * This routine is similar to the gfx_bresenam_line routine but allows + * the use of an arbitrary destination stride. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_bresenham_line(unsigned long dstoffset, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +#else +void +gfx2_bresenham_line(unsigned long dstoffset, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +#endif +{ + unsigned long vector_mode = gu2_vector_mode | flags; + unsigned long data1 = (((unsigned long)axialerr) << 16) | diagerr; + unsigned long data2 = (((unsigned long)length) << 16) | initerr; + + /* CHECK NULL LENGTH */ + + if (!length) + return; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + + if (gu2_alpha_active) { + vector_mode = gu2_alpha_vec_mode | flags; + + WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); + } else + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + + WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); + WRITE_GP32(MGP_VEC_ERR, data1); + WRITE_GP32(MGP_VEC_LEN, data2); + WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); + WRITE_GP32(MGP_VECTOR_MODE, vector_mode | gu2_vm_throttle); + gu2_bm_throttle = 0; + gu2_vm_throttle = 0; +} + +/*--------------------------------------------------------------------------- + * GFX2_SYNC_TO_VBLANK + * + * This routine sets a flag to synchronize the next rendering routine to + * VBLANK. The flag is cleared by the rendering routine. + *--------------------------------------------------------------------------- + */ +#if GFX_2DACCEL_DYNAMIC +void +gu22_sync_to_vblank(void) +#else +void +gfx2_sync_to_vblank(void) +#endif +{ + /* SET FLAGS TO THROTTLE NEXT RENDERING ROUTINE */ + + gu2_bm_throttle = MGP_BM_THROTTLE; + gu2_vm_throttle = MGP_VM_THROTTLE; +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/saa7114.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/saa7114.c new file mode 100644 index 000000000..885e65f5b --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/saa7114.c @@ -0,0 +1,1050 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/saa7114.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: saa7114.c $ + * + * This file contains routines to control the Philips SAA7114 video decoder. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/*---------------------------*/ +/* TABLE OF DEFAULT VALUES */ +/*---------------------------*/ + +typedef struct tagGFX_SAA7114_INIT +{ + unsigned char index; + unsigned char value; +} +GFX_SAA7114_INIT; + +/* Task A is for VBI raw data and task B is for video */ + +GFX_SAA7114_INIT gfx_saa7114_init_values[] = { + {0x01, 0x08}, {0x02, 0xC0}, {0x03, 0x00}, {0x04, 0x90}, + {0x05, 0x90}, {0x06, 0xEB}, {0x07, 0xE0}, {0x08, 0x88}, + {0x09, 0x40}, {0x0A, 0x80}, {0x0B, 0x44}, {0x0C, 0x40}, + {0x0D, 0x00}, {0x0E, 0x89}, {0x0F, 0x2E}, {0x10, 0x0E}, + {0x11, 0x00}, {0x12, 0x05}, {0x13, 0x00}, {0x14, 0x08}, + {0x15, 0x11}, {0x16, 0xFE}, {0x17, 0x00}, {0x18, 0x40}, + {0x19, 0x80}, {0x30, 0xBC}, {0x31, 0xDF}, {0x32, 0x02}, + {0x34, 0xCD}, {0x35, 0xCC}, {0x36, 0x3A}, {0x38, 0x03}, + {0x39, 0x10}, {0x3A, 0x00}, {0x40, 0x00}, {0x41, 0xFF}, + {0x42, 0xFF}, {0x43, 0xFF}, {0x44, 0xFF}, {0x45, 0xFF}, + {0x46, 0xFF}, {0x47, 0xFF}, {0x48, 0xFF}, {0x49, 0xFF}, + {0x4A, 0xFF}, {0x4B, 0xFF}, {0x4C, 0xFF}, {0x4D, 0xFF}, + {0x4E, 0xFF}, {0x4F, 0xFF}, {0x50, 0xFF}, {0x51, 0xFF}, + {0x52, 0xFF}, {0x53, 0xFF}, {0x54, 0xFF}, {0x55, 0xFF}, + {0x56, 0xFF}, {0x57, 0xFF}, {0x58, 0x00}, {0x59, 0x47}, + {0x5A, 0x06}, {0x5B, 0x43}, {0x5D, 0x3E}, {0x5E, 0x00}, + {0x80, 0x30}, {0x83, 0x00}, {0x84, 0x60}, {0x85, 0x00}, + {0x86, 0xE5}, {0x87, 0x01}, {0x88, 0xF8}, + + /* VBI task */ + + {0x90, 0x01}, {0x91, 0xC8}, {0x92, 0x08}, {0x93, 0x84}, + {0x94, 0x10}, {0x95, 0x00}, {0x96, 0xD0}, {0x97, 0x02}, + {0x98, 0x05}, {0x99, 0x00}, {0x9A, 0x0B}, {0x9B, 0x00}, + {0x9C, 0xA0}, {0x9D, 0x05}, {0x9E, 0x0B}, {0x9F, 0x00}, + {0xA0, 0x01}, {0xA1, 0x00}, {0xA2, 0x00}, {0xA4, 0x80}, + {0xA5, 0x40}, {0xA6, 0x40}, {0xA8, 0x00}, {0xA9, 0x02}, + {0xAA, 0x00}, {0xAC, 0x00}, {0xAD, 0x01}, {0xAE, 0x00}, + {0xB0, 0x00}, {0xB1, 0x04}, {0xB2, 0x00}, {0xB3, 0x04}, + {0xB4, 0x00}, {0xB8, 0x00}, {0xB9, 0x00}, {0xBA, 0x00}, + {0xBB, 0x00}, {0xBC, 0x00}, {0xBD, 0x00}, {0xBE, 0x00}, + {0xBF, 0x00}, + + /* Video task */ + + {0xC0, 0x80}, {0xC1, 0x08}, {0xC2, 0x00}, {0xC3, 0x80}, + {0xC4, 0x10}, {0xC5, 0x00}, {0xC6, 0xD0}, {0xC7, 0x02}, + {0xC8, 0x11}, {0xC9, 0x00}, {0xCA, 0xF1}, {0xCB, 0x00}, + {0xCC, 0xD0}, {0xCD, 0x02}, {0xCE, 0xF1}, {0xCF, 0x00}, + {0xD0, 0x01}, {0xD1, 0x00}, {0xD2, 0x00}, {0xD4, 0x80}, + {0xD5, 0x40}, {0xD6, 0x40}, {0xD8, 0x00}, {0xD9, 0x04}, + {0xDA, 0x00}, {0xDC, 0x00}, {0xDD, 0x02}, {0xDE, 0x00}, + {0xE0, 0x00}, {0xE1, 0x04}, {0xE2, 0x00}, {0xE3, 0x04}, + {0xE4, 0x00}, {0xE8, 0x00}, {0xE9, 0x00}, {0xEA, 0x00}, + {0xEB, 0x00}, {0xEC, 0x00}, {0xED, 0x00}, {0xEE, 0x00}, + {0xEF, 0x00}, +}; + +#define GFX_NUM_SAA7114_INIT_VALUES sizeof(gfx_saa7114_init_values)/sizeof(GFX_SAA7114_INIT) + +/*-----------------------------------------------------*/ +/* TABLE OF FIR PREFILTER RECOMMENDED VALUES */ +/*-----------------------------------------------------*/ + +int optimize_for_aliasing = 0; + +typedef struct tagGFX_SAA7114_FIR_PREFILTER +{ + unsigned char prescaler; + unsigned char acl_low; + unsigned char prefilter_low; + unsigned char acl_high; + unsigned char prefilter_high; +} +GFX_SAA7114_FIR_PREFILTER; + +GFX_SAA7114_FIR_PREFILTER gfx_saa7114_fir_values[] = { + {0x01, 0x00, 0x00, 0x00, 0x00}, {0x02, 0x02, 0x5A, 0x01, 0x51}, + {0x03, 0x04, 0xAB, 0x03, 0xA2}, {0x04, 0x07, 0xA3, 0x04, 0xAB}, + {0x05, 0x08, 0xAC, 0x07, 0xA3}, {0x06, 0x08, 0xFC, 0x07, 0xF3}, + {0x07, 0x08, 0xFC, 0x07, 0xF3}, {0x08, 0x0F, 0xF4, 0x08, 0xFC}, + {0x09, 0x0F, 0xF4, 0x08, 0xFC}, {0x0A, 0x10, 0xFD, 0x08, 0xFC}, + {0x0B, 0x10, 0xFD, 0x08, 0xFC}, {0x0C, 0x10, 0xFD, 0x08, 0xFC}, + {0x0D, 0x10, 0xFD, 0x10, 0xFD}, {0x0E, 0x10, 0xFD, 0x10, 0xFD}, + {0x0F, 0x1F, 0xF5, 0x10, 0xFD}, {0x10, 0x20, 0xFE, 0x10, 0xFD}, + {0x11, 0x20, 0xFE, 0x10, 0xFD}, {0x12, 0x20, 0xFE, 0x10, 0xFD}, + {0x13, 0x20, 0xFE, 0x20, 0xFE}, {0x14, 0x20, 0xFE, 0x20, 0xFE}, + {0x15, 0x20, 0xFE, 0x20, 0xFE}, {0x16, 0x20, 0xFE, 0x20, 0xFE}, + {0x17, 0x20, 0xFE, 0x20, 0xFE}, {0x18, 0x20, 0xFE, 0x20, 0xFE}, + {0x19, 0x20, 0xFE, 0x20, 0xFE}, {0x1A, 0x20, 0xFE, 0x20, 0xFE}, + {0x1B, 0x20, 0xFE, 0x20, 0xFE}, {0x1C, 0x20, 0xFE, 0x20, 0xFE}, + {0x1D, 0x20, 0xFE, 0x20, 0xFE}, {0x1E, 0x20, 0xFE, 0x20, 0xFE}, + {0x1F, 0x20, 0xFE, 0x20, 0xFE}, {0x20, 0x3F, 0xFF, 0x20, 0xFE}, + {0x21, 0x3F, 0xFF, 0x20, 0xFE}, {0x22, 0x3F, 0xFF, 0x20, 0xFE}, + {0x23, 0x3F, 0xFF, 0x20, 0xFF} +}; + +int saa7114_set_decoder_defaults(void); +int saa7114_set_decoder_analog_input(unsigned char input); +int saa7114_set_decoder_brightness(unsigned char brightness); +int saa7114_set_decoder_contrast(unsigned char contrast); +int saa7114_set_decoder_hue(char hue); +int saa7114_set_decoder_saturation(unsigned char saturation); +int saa7114_set_decoder_input_offset(unsigned short x, unsigned short y); +int saa7114_set_decoder_input_size(unsigned short width, + unsigned short height); +int saa7114_set_decoder_output_size(unsigned short width, + unsigned short height); +int saa7114_set_decoder_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int saa7114_set_decoder_vbi_format(int start, int end, int format); +int saa7114_set_decoder_vbi_enable(int enable); +int saa7114_set_decoder_vbi_upscale(void); +int saa7114_set_decoder_TV_standard(TVStandardType TVStandard); +int saa7114_set_decoder_luminance_filter(unsigned char lufi); +int saa7114_decoder_software_reset(void); +int saa7114_decoder_detect_macrovision(void); +int saa7114_decoder_detect_video(void); + +/* READ ROUTINES IN GFX_DCDR.C */ + +unsigned char saa7114_get_decoder_brightness(void); +unsigned char saa7114_get_decoder_contrast(void); +char saa7114_get_decoder_hue(void); +unsigned char saa7114_get_decoder_saturation(void); +unsigned long saa7114_get_decoder_input_offset(void); +unsigned long saa7114_get_decoder_input_size(void); +unsigned long saa7114_get_decoder_output_size(void); +int saa7114_get_decoder_vbi_format(int line); +int saa7114_write_reg(unsigned char reg, unsigned char val); +int saa7114_read_reg(unsigned char reg, unsigned char *val); + +int +saa7114_write_reg(unsigned char reg, unsigned char val) +{ + return gfx_i2c_write(2, SAA7114_CHIPADDR, reg, 1, &val); +} + +int +saa7114_read_reg(unsigned char reg, unsigned char *val) +{ + return gfx_i2c_read(2, SAA7114_CHIPADDR, reg, 1, val); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_vbi_upscale + * + * This routine configures the video decoder task A to upscale raw VBI data + * horizontally to match a different system clock. + * The upscale is from 13.5 MHz (SAA7114) to 14.318 MHz (Bt835). + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_vbi_upscale(void) +#else +int +gfx_set_decoder_vbi_upscale(void) +#endif +{ + /* Set horizontal output length to 1528 (720 * 2 * 14.318 / 13.5) */ + saa7114_write_reg(SAA7114_TASK_A_HORZ_OUTPUT_LO, 0xF8); + saa7114_write_reg(SAA7114_TASK_A_HORZ_OUTPUT_HI, 0x05); + + /* Set horizontal luminance scaling increment to 484 (1024 * 13.5 / 28.636) */ + saa7114_write_reg(SAA7114_TASK_A_HSCALE_LUMA_LO, 0xE4); + saa7114_write_reg(SAA7114_TASK_A_HSCALE_LUMA_HI, 0x01); + + /* Set horizontal chrominance scaling increment to 242 */ + saa7114_write_reg(SAA7114_TASK_A_HSCALE_CHROMA_LO, 0xF2); + saa7114_write_reg(SAA7114_TASK_A_HSCALE_CHROMA_HI, 0x00); + + return GFX_STATUS_OK; +} + +/*----------------------------------------------------------------------------- + * gfx_decoder_software_reset + * + * This routine performs a software reset of the decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_decoder_software_reset(void) +#else +int +gfx_decoder_software_reset(void) +#endif +{ + saa7114_write_reg(0x88, 0xC0); + /* I2C-bus latency should be sufficient for resetting the internal state machine. */ + /* gfx_delay_milliseconds(10); */ + saa7114_write_reg(0x88, 0xF0); + return GFX_STATUS_OK; +} + +/*----------------------------------------------------------------------------- + * gfx_decoder_detect_macrovision + * + * This routine detects if macrovision exists in the input of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_decoder_detect_macrovision(void) +#else +int +gfx_decoder_detect_macrovision(void) +#endif +{ + unsigned char macrovision = 0xff; + + saa7114_read_reg(SAA7114_STATUS, ¯ovision); + return ((macrovision & 0x02) >> 1); +} + +/*----------------------------------------------------------------------------- + * gfx_decoder_detect_video + * + * This routine detects if video exists in the input of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_decoder_detect_video(void) +#else +int +gfx_decoder_detect_video(void) +#endif +{ + unsigned char video = 0xff; + + saa7114_read_reg(SAA7114_STATUS, &video); + return !((video & 0x40) >> 6); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_defaults + * + * This routine is called to set the initial register values of the + * video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_defaults(void) +#else +int +gfx_set_decoder_defaults(void) +#endif +{ + unsigned int i; + + /* LOOP THROUGH INDEX/DATA PAIRS IN THE TABLE */ + + for (i = 0; i < GFX_NUM_SAA7114_INIT_VALUES; i++) { + saa7114_write_reg(gfx_saa7114_init_values[i].index, + gfx_saa7114_init_values[i].value); + } + + gfx_decoder_software_reset(); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_analog_input + * + * This routine sets the analog input of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_analog_input(unsigned char input) +#else +int +gfx_set_decoder_analog_input(unsigned char input) +#endif +{ + saa7114_write_reg(SAA7114_ANALOG_INPUT_CTRL1, input); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_brightness + * + * This routine sets the brightness of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_brightness(unsigned char brightness) +#else +int +gfx_set_decoder_brightness(unsigned char brightness) +#endif +{ + saa7114_write_reg(SAA7114_BRIGHTNESS, brightness); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_contrast + * + * This routine sets the contrast of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_contrast(unsigned char contrast) +#else +int +gfx_set_decoder_contrast(unsigned char contrast) +#endif +{ + saa7114_write_reg(SAA7114_CONTRAST, (unsigned char)(contrast >> 1)); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_hue + * + * This routine sets the hue control of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_hue(char hue) +#else +int +gfx_set_decoder_hue(char hue) +#endif +{ + saa7114_write_reg(SAA7114_HUE, (unsigned char)hue); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_saturation + * + * This routine sets the saturation adjustment of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_saturation(unsigned char saturation) +#else +int +gfx_set_decoder_saturation(unsigned char saturation) +#endif +{ + saa7114_write_reg(SAA7114_SATURATION, (unsigned char)(saturation >> 1)); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_input_offset + * + * This routine sets the size of the decoder input window. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_input_offset(unsigned short x, unsigned short y) +#else +int +gfx_set_decoder_input_offset(unsigned short x, unsigned short y) +#endif +{ + /* SET THE INPUT WINDOW OFFSET */ + + saa7114_write_reg(SAA7114_HORZ_OFFSET_LO, (unsigned char)(x & 0x00FF)); + saa7114_write_reg(SAA7114_HORZ_OFFSET_HI, (unsigned char)(x >> 8)); + saa7114_write_reg(SAA7114_VERT_OFFSET_LO, (unsigned char)(y & 0x00FF)); + saa7114_write_reg(SAA7114_VERT_OFFSET_HI, (unsigned char)(y >> 8)); + + gfx_decoder_software_reset(); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_input_size + * + * This routine sets the size of the decoder input window. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_input_size(unsigned short width, unsigned short height) +#else +int +gfx_set_decoder_input_size(unsigned short width, unsigned short height) +#endif +{ + /* DIVIDE HEIGHT BY TWO FOR INTERLACING */ + + height = (height + 1) >> 1; + + /* SET THE INPUT WINDOW SIZE */ + + saa7114_write_reg(SAA7114_HORZ_INPUT_LO, (unsigned char)(width & 0x00FF)); + saa7114_write_reg(SAA7114_HORZ_INPUT_HI, (unsigned char)(width >> 8)); + saa7114_write_reg(SAA7114_VERT_INPUT_LO, (unsigned char)(height & 0x00FF)); + saa7114_write_reg(SAA7114_VERT_INPUT_HI, (unsigned char)(height >> 8)); + + gfx_decoder_software_reset(); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_output_size + * + * This routine sets the size of the decoder output window. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_output_size(unsigned short width, unsigned short height) +#else +int +gfx_set_decoder_output_size(unsigned short width, unsigned short height) +#endif +{ + /* ROUND WIDTH UP TO EVEN NUMBER TO PREVENT DECODER BECOMING STUCK */ + + width = ((width + 1) >> 1) << 1; + + /* DIVIDE HEIGHT BY TWO FOR INTERLACING */ + + height = (height + 1) >> 1; + + /* SET THE OUTPUT WINDOW SIZE */ + + saa7114_write_reg(SAA7114_HORZ_OUTPUT_LO, (unsigned char)(width & 0x00FF)); + saa7114_write_reg(SAA7114_HORZ_OUTPUT_HI, (unsigned char)(width >> 8)); + saa7114_write_reg(SAA7114_VERT_OUTPUT_LO, + (unsigned char)(height & 0x00FF)); + saa7114_write_reg(SAA7114_VERT_OUTPUT_HI, (unsigned char)(height >> 8)); + + gfx_decoder_software_reset(); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_scale + * + * This routine sets the scaling of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#else +int +gfx_set_decoder_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#endif +{ + unsigned char prescale = 0; + int scale = 0; + + /* SET THE HORIZONTAL PRESCALE */ + /* Downscale from 1 to 1/63 source size. */ + + if (dstw) + prescale = (unsigned char)(srcw / dstw); + if (!prescale) + prescale = 1; + if (prescale > 63) + return (1); + saa7114_write_reg(SAA7114_HORZ_PRESCALER, prescale); + + /* USE FIR PREFILTER FUNCTIONALITY (OPTIMISATION) */ + + if (prescale < 36) { + if (optimize_for_aliasing) { + saa7114_write_reg(SAA7114_HORZ_ACL, + gfx_saa7114_fir_values[prescale - 1].acl_low); + saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER, + gfx_saa7114_fir_values[prescale - + 1].prefilter_low); + } else { + saa7114_write_reg(SAA7114_HORZ_ACL, + gfx_saa7114_fir_values[prescale - 1].acl_high); + saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER, + gfx_saa7114_fir_values[prescale - + 1].prefilter_high); + } + } else { + /* SAME SETTINGS FOR RATIO 1/35 DOWNTO 1/63 */ + if (optimize_for_aliasing) { + saa7114_write_reg(SAA7114_HORZ_ACL, + gfx_saa7114_fir_values[34].acl_low); + saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER, + gfx_saa7114_fir_values[34].prefilter_low); + } else { + saa7114_write_reg(SAA7114_HORZ_ACL, + gfx_saa7114_fir_values[34].acl_high); + saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER, + gfx_saa7114_fir_values[34].prefilter_high); + } + } + + /* SET THE HORIZONTAL SCALING */ + + if (!dstw) + return (1); + scale = ((1024 * srcw * 1000) / (dstw * prescale)) / 1000; + if ((scale > 8191) || (scale < 300)) + return (1); + saa7114_write_reg(SAA7114_HSCALE_LUMA_LO, (unsigned char)(scale & 0x00FF)); + saa7114_write_reg(SAA7114_HSCALE_LUMA_HI, (unsigned char)(scale >> 8)); + scale >>= 1; + saa7114_write_reg(SAA7114_HSCALE_CHROMA_LO, + (unsigned char)(scale & 0x00FF)); + saa7114_write_reg(SAA7114_HSCALE_CHROMA_HI, (unsigned char)(scale >> 8)); + + /* SET THE VERTICAL SCALING (INTERPOLATION MODE) */ + + if (!dsth) + return (1); + + /* ROUND DESTINATION HEIGHT UP TO EVEN NUMBER TO PREVENT DECODER BECOMING STUCK */ + + dsth = ((dsth + 1) >> 1) << 1; + + scale = (int)((1024 * srch) / dsth); + saa7114_write_reg(SAA7114_VSCALE_LUMA_LO, (unsigned char)(scale & 0x00FF)); + saa7114_write_reg(SAA7114_VSCALE_LUMA_HI, (unsigned char)(scale >> 8)); + saa7114_write_reg(SAA7114_VSCALE_CHROMA_LO, + (unsigned char)(scale & 0x00FF)); + saa7114_write_reg(SAA7114_VSCALE_CHROMA_HI, (unsigned char)(scale >> 8)); + + if (dsth >= (srch >> 1)) { + /* USE INTERPOLATION MODE FOR SCALE FACTOR ABOVE 0.5 */ + + saa7114_write_reg(SAA7114_VSCALE_CONTROL, 0x00); + + /* SET VERTICAL PHASE REGISTER FOR CORRECT SCALED INTERLACED OUTPUT (OPTIMISATION) */ + /* THE OPTIMISATION IS BASED ON OFIDC = 0 (REG 90h[6] = 0 ) */ + saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS0, SAA7114_VSCALE_PHO); + saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS1, SAA7114_VSCALE_PHO); + saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS2, + (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - + 16)); + saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS3, + (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - + 16)); + + saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS0, SAA7114_VSCALE_PHO); + saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS1, SAA7114_VSCALE_PHO); + saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS2, + (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - + 16)); + saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS3, + (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - + 16)); + + /* RESTORE CONTRAST AND SATURATION FOR INTERPOLATION MODE */ + + saa7114_write_reg(SAA7114_FILTER_CONTRAST, (unsigned char)0x40); + saa7114_write_reg(SAA7114_FILTER_SATURATION, (unsigned char)0x40); + } else { + /* USE ACCUMULATION MODE FOR DOWNSCALING BY MORE THAN 2x */ + + saa7114_write_reg(SAA7114_VSCALE_CONTROL, 0x01); + + /* SET VERTICAL PHASE OFFSETS OFF (OPTIMISATION) */ + saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS0, 0x00); + saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS1, 0x00); + saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS2, 0x00); + saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS3, 0x00); + + saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS0, 0x00); + saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS1, 0x00); + saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS2, 0x00); + saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS3, 0x00); + + /* ADJUST CONTRAST AND SATURATION FOR ACCUMULATION MODE */ + + if (srch) + scale = (64 * dsth) / srch; + saa7114_write_reg(SAA7114_FILTER_CONTRAST, (unsigned char)scale); + saa7114_write_reg(SAA7114_FILTER_SATURATION, (unsigned char)scale); + } + + gfx_decoder_software_reset(); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_vbi_format + * + * This routine programs the decoder to produce the specified format of VBI + * data for the specified lines. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_vbi_format(int start, int end, int format) +#else +int +gfx_set_decoder_vbi_format(int start, int end, int format) +#endif +{ + int i; + unsigned char data; + + for (i = start; i <= end; i++) { + switch (format) { + case VBI_FORMAT_VIDEO: + data = 0xFF; + break; /* Active video */ + case VBI_FORMAT_RAW: + data = 0x77; + break; /* Raw VBI data */ + case VBI_FORMAT_CC: + data = 0x55; + break; /* US CC */ + case VBI_FORMAT_NABTS: + data = 0xCC; + break; /* US NABTS */ + default: + return GFX_STATUS_BAD_PARAMETER; + } + saa7114_write_reg((unsigned char)(0x3F + i), data); + } + return GFX_STATUS_OK; +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_vbi_enable + * + * This routine enables or disables VBI transfer in the decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_vbi_enable(int enable) +#else +int +gfx_set_decoder_vbi_enable(int enable) +#endif +{ + unsigned char data; + + saa7114_read_reg(SAA7114_IPORT_CONTROL, &data); + if (enable) + data |= 0x80; + else + data &= ~0x80; + saa7114_write_reg(SAA7114_IPORT_CONTROL, data); + return GFX_STATUS_OK; +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_TV_standard + * + * This routine configures the decoder for the required TV standard. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_TV_standard(TVStandardType TVStandard) +#else +int +gfx_set_decoder_TV_standard(TVStandardType TVStandard) +#endif +{ + switch (TVStandard) { + case TV_STANDARD_NTSC: + saa7114_write_reg(0x0E, 0x89); + saa7114_write_reg(0x5A, 0x06); + break; + case TV_STANDARD_PAL: + saa7114_write_reg(0x0E, 0x81); + saa7114_write_reg(0x5A, 0x03); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + gfx_decoder_software_reset(); + return GFX_STATUS_OK; +} + +/*----------------------------------------------------------------------------- + * gfx_set_decoder_luminance_filter + * + * This routine sets the hue control of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_set_decoder_luminance_filter(unsigned char lufi) +#else +int +gfx_set_decoder_luminance_filter(unsigned char lufi) +#endif +{ + unsigned char data; + + saa7114_read_reg(SAA7114_LUMINANCE_CONTROL, &data); + saa7114_write_reg(SAA7114_LUMINANCE_CONTROL, + (unsigned char)((data & ~0x0F) | (lufi & 0x0F))); + return (0); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_brightness + * + * This routine returns the current brightness of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +unsigned char +saa7114_get_decoder_brightness(void) +#else +unsigned char +gfx_get_decoder_brightness(void) +#endif +{ + unsigned char brightness = 0; + + saa7114_read_reg(SAA7114_BRIGHTNESS, &brightness); + return (brightness); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_contrast + * + * This routine returns the current contrast of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +unsigned char +saa7114_get_decoder_contrast(void) +#else +unsigned char +gfx_get_decoder_contrast(void) +#endif +{ + unsigned char contrast = 0; + + saa7114_read_reg(SAA7114_CONTRAST, &contrast); + contrast <<= 1; + return (contrast); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_hue + * + * This routine returns the current hue of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +char +saa7114_get_decoder_hue(void) +#else +char +gfx_get_decoder_hue(void) +#endif +{ + unsigned char hue = 0; + + saa7114_read_reg(SAA7114_HUE, &hue); + return ((char)hue); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_saturation + * + * This routine returns the current saturation of the video decoder. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +unsigned char +saa7114_get_decoder_saturation(void) +#else +unsigned char +gfx_get_decoder_saturation(void) +#endif +{ + unsigned char saturation = 0; + + saa7114_read_reg(SAA7114_SATURATION, &saturation); + saturation <<= 1; + return (saturation); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_input_offset + * + * This routine returns the offset into the input window. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +unsigned long +saa7114_get_decoder_input_offset(void) +#else +unsigned long +gfx_get_decoder_input_offset(void) +#endif +{ + unsigned long value = 0; + unsigned char data; + + saa7114_read_reg(SAA7114_HORZ_OFFSET_LO, &data); + value = (unsigned long)data; + saa7114_read_reg(SAA7114_HORZ_OFFSET_HI, &data); + value |= ((unsigned long)data) << 8; + saa7114_read_reg(SAA7114_VERT_OFFSET_LO, &data); + value |= ((unsigned long)data) << 16; + saa7114_read_reg(SAA7114_VERT_OFFSET_HI, &data); + value |= ((unsigned long)data) << 24; + return (value); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_input_size + * + * This routine returns the current size of the input window + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +unsigned long +saa7114_get_decoder_input_size(void) +#else +unsigned long +gfx_get_decoder_input_size(void) +#endif +{ + unsigned long value = 0; + unsigned char data; + + saa7114_read_reg(SAA7114_HORZ_INPUT_LO, &data); + value = (unsigned long)data; + saa7114_read_reg(SAA7114_HORZ_INPUT_HI, &data); + value |= ((unsigned long)data) << 8; + saa7114_read_reg(SAA7114_VERT_INPUT_LO, &data); + value |= ((unsigned long)data) << 17; + saa7114_read_reg(SAA7114_VERT_INPUT_HI, &data); + value |= ((unsigned long)data) << 25; + return (value); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_output_size + * + * This routine returns the current size of the output window. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +unsigned long +saa7114_get_decoder_output_size(void) +#else +unsigned long +gfx_get_decoder_output_size(void) +#endif +{ + unsigned long value = 0; + unsigned char data; + + saa7114_read_reg(SAA7114_HORZ_OUTPUT_LO, &data); + value = (unsigned long)data; + saa7114_read_reg(SAA7114_HORZ_OUTPUT_HI, &data); + value |= ((unsigned long)data) << 8; + saa7114_read_reg(SAA7114_VERT_OUTPUT_LO, &data); + value |= ((unsigned long)data) << 17; + saa7114_read_reg(SAA7114_VERT_OUTPUT_HI, &data); + value |= ((unsigned long)data) << 25; + return (value); +} + +/*----------------------------------------------------------------------------- + * gfx_get_decoder_vbi_format + * + * This routine returns the current format of VBI data for the specified line. + *----------------------------------------------------------------------------- + */ +#if GFX_DECODER_DYNAMIC +int +saa7114_get_decoder_vbi_format(int line) +#else +int +gfx_get_decoder_vbi_format(int line) +#endif +{ + unsigned char format = 0, data; + + saa7114_read_reg((unsigned char)(0x3F + line), &data); + switch (data) { + case 0xFF: + format = VBI_FORMAT_VIDEO; + break; /* Active video */ + case 0x77: + format = VBI_FORMAT_RAW; + break; /* Raw VBI data */ + case 0x55: + format = VBI_FORMAT_CC; + break; /* US CC */ + case 0xCC: + format = VBI_FORMAT_NABTS; + break; /* US NABTS */ + } + return (format); +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_1200.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_1200.c new file mode 100644 index 000000000..512b28e14 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_1200.c @@ -0,0 +1,1113 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_1200.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: tv_1200.c $ + * + * This file contains routines to control the SC1200 TVOUT and TV encoder. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +int sc1200_set_tv_format(TVStandardType format, GfxOnTVType resolution); +int sc1200_set_tv_output(int output); +int sc1200_set_tv_enable(int enable); +int sc1200_set_tv_flicker_filter(int ff); +int sc1200_set_tv_sub_carrier_reset(int screset); +int sc1200_set_tv_vphase(int vphase); +int sc1200_set_tv_YC_delay(int delay); +int sc1200_set_tvenc_reset_interval(int interval); +int sc1200_set_tv_cc_enable(int enable); +int sc1200_set_tv_cc_data(unsigned char data1, unsigned char data2); +int sc1200_set_tv_display(int width, int height); +int sc1200_test_tvout_odd_field(void); +int sc1200_test_tvenc_odd_field(void); +int sc1200_set_tv_field_status_invert(int enable); +int sc1200_get_tv_vphase(void); +int sc1200_get_tv_enable(unsigned int *p_on); +int sc1200_get_tv_output(void); +int sc1200_get_tv_mode_count(TVStandardType format); +int sc1200_get_tv_display_mode(int *width, int *height, int *bpp, int *hz); +int sc1200_get_tv_display_mode_frequency(unsigned short width, + unsigned short height, + TVStandardType format, + int *frequency); +int sc1200_is_tv_display_mode_supported(unsigned short width, + unsigned short height, + TVStandardType format); + +int sc1200_get_tv_standard(unsigned long *p_standard); +int sc1200_get_available_tv_standards(unsigned long *p_standards); +int sc1200_set_tv_standard(unsigned long standard); +int sc1200_get_tv_vga_mode(unsigned long *p_vga_mode); +int sc1200_get_available_tv_vga_modes(unsigned long *p_vga_modes); +int sc1200_set_tv_vga_mode(unsigned long vga_mode); +int sc1200_get_tvout_mode(unsigned long *p_tvout_mode); +int sc1200_set_tvout_mode(unsigned long tvout_mode); +int sc1200_get_sharpness(int *p_sharpness); +int sc1200_set_sharpness(int sharpness); +int sc1200_get_flicker_filter(int *p_flicker); +int sc1200_set_flicker_filter(int flicker); +int sc1200_get_overscan(int *p_x, int *p_y); +int sc1200_set_overscan(int x, int y); +int sc1200_get_position(int *p_x, int *p_y); +int sc1200_set_position(int x, int y); +int sc1200_get_color(int *p_color); +int sc1200_set_color(int color); +int sc1200_get_brightness(int *p_brightness); +int sc1200_set_brightness(int brightness); +int sc1200_get_contrast(int *p_contrast); +int sc1200_set_contrast(int constrast); +int sc1200_get_yc_filter(unsigned int *p_yc_filter); +int sc1200_set_yc_filter(unsigned int yc_filter); +int sc1200_get_aps_trigger_bits(unsigned int *p_trigger_bits); +int sc1200_set_aps_trigger_bits(unsigned int trigger_bits); +unsigned char cc_add_parity_bit(unsigned char data); + +/*----------------------------------------------------------------------------- + * gfx_set_tv_format + * + * This routine sets the TV encoder registers to the specified format + * and resolution. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_format(TVStandardType format, GfxOnTVType resolution) +#else +int +gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution) +#endif +{ + unsigned long ctrl2, mode; + + /* Save TV output mode */ + ctrl2 = + READ_VID32(SC1200_TVENC_TIM_CTRL_2) & (SC1200_TVENC_OUTPUT_YCBCR | + SC1200_TVENC_CFS_MASK); + /* Save flicker filter setting */ + mode = READ_VID32(SC1200_TVOUT_HORZ_SCALING) & + SC1200_TVOUT_FLICKER_FILTER_MASK; + + switch (format) { + case TV_STANDARD_NTSC: + /* Horizontal Sync Start is 848 */ + /* Horizontal Sync End is 856 */ + WRITE_VID32(SC1200_TVOUT_HORZ_SYNC, 0x03580350); + /* Vertical Sync Start is 0 */ + /* Vertical Sync End is 1 */ + /* Vertical Display Start Skew is 1 */ + /* Vertical Display End Skew is 1 */ + WRITE_VID32(SC1200_TVOUT_VERT_SYNC, 0x05001000); + /* Disable vertical down scaling, take all lines */ + if (gfx_chip_revision <= SC1200_REV_B3) + WRITE_VID32(SC1200_TVOUT_VERT_DOWNSCALE, 0xffffffff); + /* Enable video timing */ + /* Reset sub carrier every two frames */ + /* Disable BLANK */ + /* Enable color burst */ + /* Add the IRE offset */ + /* NTSC color encoding */ + /* Video generator timing is 525 lines / 60Hz */ + /* Horizontal and Vertical counters are initialized to HPHASE & VPHASE */ + /* VPHASE is 2, HPHASE is 0x50 */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 0xa2a01050); + /* Increase horizontal blanking interval */ + /* Low Water Mark for Y is 0x1F */ + /* Low Water Mark for Cb is 0xF */ + /* HUE is 0 */ + /* SCPHASE is 0xF9 */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, 0x9ff000f9 | ctrl2); + /* Subcarrier Frequency is 3.579545 MHz */ + WRITE_VID32(SC1200_TVENC_SUB_FREQ, 0x21f07c1f); + /* VSTART is 18, HSTART is 113 */ + WRITE_VID32(SC1200_TVENC_DISP_POS, 0x00120071); + /* Display size: HEIGHT is 239, WIDTH is 719 */ + WRITE_VID32(SC1200_TVENC_DISP_SIZE, 0x00ef02cf); + switch (resolution) { + case GFX_ON_TV_SQUARE_PIXELS: + if (gfx_chip_revision <= SC1200_REV_B3) { + /* Horizontal Display start is 116 */ + /* Total number of pixels per line is 857 */ + WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x00740359); + /* HSYNC generated in the TV Encoder module */ + /* Interval between resets of TV Encoder is once every odd field */ + /* Enable Horizontal interpolation */ + /* Enable Horizontal up scaling 9/8 */ + /* Disable Horizontal downscale */ + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020700 | mode); + /* Horizontal display end is 919, i.e. 720 active pixels */ + /* Total number of display lines per field is 240 */ + WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039700f0); + } else { /* Use new scaler available in Rev. C */ + /* Horizontal Display start is 111 */ + /* Total number of pixels per line is 857 */ + WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x006f0359); + /* HSYNC generated in the TV Encoder module */ + /* Interval between resets of TV Encoder is once every odd field */ + /* Enable Horizontal interpolation */ + /* Disable Horizontal up scaling 9/8 */ + /* Disable Horizontal downscale */ + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode); + /* Set Horizontal upscaling to 64/58 (~ 11/10) */ + WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x3A000000); + /* Horizontal display end is 900, i.e. 706 active pixels */ + /* Total number of display lines per field is 240 */ + WRITE_VID32(SC1200_TVOUT_LINE_END, 0x038400f0); + } + break; + case GFX_ON_TV_NO_SCALING: + /* Horizontal Display start is 116 */ + /* Total number of pixels per line is 857 */ + WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x00740359); + /* HSYNC generated in the TV Encoder module */ + /* Interval between resets of TV Encoder is once every odd field */ + /* Enable Horizontal interpolation */ + /* Disable Horizontal up scaling 9/8 */ + /* Disable Horizontal downscale */ + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode); + /* Disable Horizontal scaling (set to 64/64) */ + if (gfx_chip_revision >= SC1200_REV_C1) + WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x40000000); + /* Horizontal display end is 919, i.e. 720 active pixels */ + /* Total number of display lines per field is 240 */ + WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039700f0); + break; + default: + return (GFX_STATUS_BAD_PARAMETER); + } + break; + case TV_STANDARD_PAL: + /* Horizontal Sync Start is 854 */ + /* Horizontal Sync End is 862 */ + WRITE_VID32(SC1200_TVOUT_HORZ_SYNC, 0x035e0356); + /* Vertical Sync Start is 0 */ + /* Vertical Sync End is 1 */ + /* Vertical Display Start Skew is 1 */ + /* Vertical Display End Skew is 1 */ + WRITE_VID32(SC1200_TVOUT_VERT_SYNC, 0x05001000); + /* Disable vertical down scaling, take all lines */ + if (gfx_chip_revision <= SC1200_REV_B3) + WRITE_VID32(SC1200_TVOUT_VERT_DOWNSCALE, 0xffffffff); + /* Enable video timing */ + /* Never reset sub carrier (should be every 4 frames but doesn't work with genlock) */ + /* Disable BLANK */ + /* Enable color burst */ + /* Do not add the IRE offset */ + /* NTSC color encoding */ + /* Video generator timing is 625 lines / 50Hz */ + /* Horizontal and Vertical counters are initialized to HPHASE & VPHASE */ + /* VPHASE is 2, HPHASE is 50 */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 0xB1201050); + /* Increase horizontal blanking interval */ + /* Low Water Mark for Y is 0x1F */ + /* Low Water Mark for Cb is 0xF */ + /* HUE is 0 */ + /* SCPHASE is 0xD9 */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, 0x9ff000d9 | ctrl2); + /* Subcarrier Frequency is 4.43361875 MHz */ + WRITE_VID32(SC1200_TVENC_SUB_FREQ, 0x2a098acb); + /* VSTART is 22, HSTART is 123 */ + WRITE_VID32(SC1200_TVENC_DISP_POS, 0x0016007b); + /* Display size: HEIGHT is 287, WIDTH is 719 */ + WRITE_VID32(SC1200_TVENC_DISP_SIZE, 0x011f02cf); + switch (resolution) { + case GFX_ON_TV_NO_SCALING: + /* Horizontal Display start is 124 */ + /* Total number of pixels per line is 863 */ + WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x007c035f); + /* HSYNC generated in the TV Encoder module */ + /* Interval between resets of TV Encoder is once every odd field */ + /* Enable Horizontal interpolation */ + /* Disable Horizontal up scaling 9/8 */ + /* Disable Horizontal downscale */ + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode); + /* Disable Horizontal scaling (set to 64/64) */ + if (gfx_chip_revision >= SC1200_REV_C1) + WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x40000000); + /* Horizontal display end is 924, i.e. 720 active pixels */ + /* Total number of display lines per field is 288 */ + WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039c0120); + break; + case GFX_ON_TV_SQUARE_PIXELS: + /* Horizontal Display start is 122 */ + /* Total number of pixels per line is 863 */ + WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x007a035f); + if (gfx_chip_revision <= SC1200_REV_B3) { + /* HSYNC generated in the TV Encoder module */ + /* Interval between resets of TV Encoder is once every odd field */ + /* Enable Horizontal interpolation */ + /* Disable Horizontal up scaling 9/8 */ + /* Horizontal downscale m/(m+1), m = 11, (i.e. 11/12 - closest possible to 54/59) */ + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x1002040b | mode); + /* Horizontal display end is 906, i.e. 704 active pixels */ + /* Total number of display lines per field is 288 */ + WRITE_VID32(SC1200_TVOUT_LINE_END, 0x038a0120); + } else { + /* HSYNC generated in the TV Encoder module */ + /* Interval between resets of TV Encoder is once every odd field */ + /* Enable Horizontal interpolation */ + /* Disable Horizontal up scaling 9/8 */ + /* Disable Horizontal downscale */ + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode); + /* Set Horizontal down scaling to 64/70 (closest possible to 54/59) */ + WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x46000000); + /* Horizontal display end is 904, i.e. 702 active pixels */ + /* Total number of display lines per field is 288 */ + WRITE_VID32(SC1200_TVOUT_LINE_END, 0x03880120); + } + break; + default: + return (GFX_STATUS_BAD_PARAMETER); + } + break; + default: + return (GFX_STATUS_BAD_PARAMETER); + } + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_output + * + * This routine sets the TV encoder registers to the specified output type. + * Supported output types are : S-VIDEO, Composite, YUV and SCART. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_output(int output) +#else +int +gfx_set_tv_output(int output) +#endif +{ + unsigned long ctrl2, ctrl3; + + ctrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2); + ctrl3 = READ_VID32(SC1200_TVENC_TIM_CTRL_3); + ctrl2 &= ~(SC1200_TVENC_OUTPUT_YCBCR | SC1200_TVENC_CFS_MASK); + ctrl3 &= ~(SC1200_TVENC_CM | SC1200_TVENC_SYNCMODE_MASK | SC1200_TVENC_CS); + switch (output) { + case TV_OUTPUT_COMPOSITE: + /* Analog outputs provide Y, C and CVBS */ + /* Chrominance Lowpass filter is 1.3MHz (for composite video output) */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_CVBS); + WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, ctrl3); + break; + case TV_OUTPUT_S_VIDEO: + /* Analog outputs provide Y, C and CVBS */ + /* Chrominance Lowpass filter is 1.8MHz (for S-video output) */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_SVIDEO); + WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, ctrl3); + break; + case TV_OUTPUT_YUV: + /* Analog outputs provide Y, Cb and Cr */ + /* A 7.5 IRE setup is applied to the output */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, + ctrl2 | SC1200_TVENC_OUTPUT_YCBCR | + SC1200_TVENC_CFS_BYPASS); + WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, + ctrl3 | SC1200_TVENC_CM | SC1200_TVENC_CS); + break; + case TV_OUTPUT_SCART: + /* Analog outputs provide SCART (RGB and CVBS) */ + /* Sync is added to green signal */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_CVBS); + WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, + ctrl3 | SC1200_TVENC_CM | SC1200_TVENC_SYNC_ON_GREEN); + break; + default: + return (GFX_STATUS_BAD_PARAMETER); + } + + /* Adjusts the internal voltage reference */ + ctrl2 = READ_VID32(SC1200_TVENC_DAC_CONTROL); + ctrl2 &= ~SC1200_TVENC_TRIM_MASK; + + /* Bypass for issue #926 : Inadequate chroma level of S-Video output */ + if ((gfx_chip_revision == SC1200_REV_B3) && (output == TV_OUTPUT_S_VIDEO)) + ctrl2 |= 0x7; + else + ctrl2 |= 0x5; + + WRITE_VID32(SC1200_TVENC_DAC_CONTROL, ctrl2); + + /* Disable 4:2:2 to 4:4:4 converter interpolation */ + WRITE_VID32(SC1200_TVOUT_DEBUG, SC1200_TVOUT_CONVERTER_INTERPOLATION); + + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_enable + * + * This routine enables or disables the TV output. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_enable(int enable) +#else +int +gfx_set_tv_enable(int enable) +#endif +{ + unsigned long value_tim, value_dac; + + value_tim = READ_VID32(SC1200_TVENC_TIM_CTRL_1); + value_dac = READ_VID32(SC1200_TVENC_DAC_CONTROL); + + if (enable) { + value_tim |= SC1200_TVENC_VIDEO_TIMING_ENABLE; + value_dac &= ~SC1200_TVENC_POWER_DOWN; + /* ENABLE GRAPHICS DISPLAY LOGIC IN VIDEO PROCESSOR */ + gfx_set_screen_enable(1); + } else { + value_tim &= ~SC1200_TVENC_VIDEO_TIMING_ENABLE; + value_dac |= SC1200_TVENC_POWER_DOWN; + /* Do not disable the graphics display logic because it might be needed for CRT */ + } + + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, value_tim); + WRITE_VID32(SC1200_TVENC_DAC_CONTROL, value_dac); + + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_flicker_filter + * + * This routine configures the TV out flicker filter. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_flicker_filter(int ff) +#else +int +gfx_set_tv_flicker_filter(int ff) +#endif +{ + unsigned long mode; + + mode = READ_VID32(SC1200_TVOUT_HORZ_SCALING); + mode &= ~SC1200_TVOUT_FLICKER_FILTER_MASK; + switch (ff) { + case TV_FLICKER_FILTER_NONE: + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, + mode | SC1200_TVOUT_FLICKER_FILTER_DISABLED); + break; + case TV_FLICKER_FILTER_NORMAL: + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, + mode | SC1200_TVOUT_FLICKER_FILTER_FOURTH_HALF_FOURTH); + break; + case TV_FLICKER_FILTER_INTERLACED: + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, + mode | SC1200_TVOUT_FLICKER_FILTER_HALF_ONE_HALF); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_sub_carrier_reset + * + * This routine configures the TV encoder sub carrier reset interval. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_sub_carrier_reset(int screset) +#else +int +gfx_set_tv_sub_carrier_reset(int screset) +#endif +{ + unsigned long mode; + + mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1); + mode &= ~SC1200_TVENC_SUB_CARRIER_RESET_MASK; + switch (screset) { + case TV_SUB_CARRIER_RESET_NEVER: + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, + mode | SC1200_TVENC_SUB_CARRIER_RESET_NEVER); + break; + case TV_SUB_CARRIER_RESET_EVERY_TWO_LINES: + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, + mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_LINES); + break; + case TV_SUB_CARRIER_RESET_EVERY_TWO_FRAMES: + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, + mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_FRAMES); + break; + case TV_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES: + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, + mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_vphase + * + * This routine sets the tv encoder VPHASE value. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_vphase(int vphase) +#else +int +gfx_set_tv_vphase(int vphase) +#endif +{ + unsigned long mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1); + + mode &= ~SC1200_TVENC_VPHASE_MASK; + mode |= (vphase << SC1200_TVENC_VPHASE_POS) & SC1200_TVENC_VPHASE_MASK; + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, mode); + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_YC_delay + * + * This routine configures the TV out Y/C delay. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_YC_delay(int delay) +#else +int +gfx_set_tv_YC_delay(int delay) +#endif +{ + unsigned long mode; + + /* This feature is implemented in Rev C1 */ + if (gfx_chip_revision < SC1200_REV_C1) + return (GFX_STATUS_OK); + + mode = READ_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE); + mode &= ~SC1200_TVOUT_YC_DELAY_MASK; + switch (delay) { + case TV_YC_DELAY_NONE: + WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, + mode | SC1200_TVOUT_YC_DELAY_NONE); + break; + case TV_Y_DELAY_ONE_PIXEL: + WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, + mode | SC1200_TVOUT_Y_DELAY_ONE_PIXEL); + break; + case TV_C_DELAY_ONE_PIXEL: + WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, + mode | SC1200_TVOUT_C_DELAY_ONE_PIXEL); + break; + case TV_C_DELAY_TWO_PIXELS: + WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, + mode | SC1200_TVOUT_C_DELAY_TWO_PIXELS); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tvenc_reset_interval + * + * This routine sets the interval between external resets of the TV encoder + * timing generator by the TV out. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tvenc_reset_interval(int interval) +#else +int +gfx_set_tvenc_reset_interval(int interval) +#endif +{ + unsigned long value; + + value = READ_VID32(SC1200_TVOUT_HORZ_SCALING); + value &= ~SC1200_TVENC_EXTERNAL_RESET_INTERVAL_MASK; + switch (interval) { + case TVENC_RESET_EVERY_ODD_FIELD: + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, + value | SC1200_TVENC_EXTERNAL_RESET_EVERY_ODD_FIELD); + break; + case TVENC_RESET_EVERY_EVEN_FIELD: + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, + value | SC1200_TVENC_EXTERNAL_RESET_EVERY_EVEN_FIELD); + break; + case TVENC_RESET_NEXT_ODD_FIELD: + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, + value | SC1200_TVENC_EXTERNAL_RESET_NEXT_ODD_FIELD); + break; + case TVENC_RESET_NEXT_EVEN_FIELD: + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, + value | SC1200_TVENC_EXTERNAL_RESET_NEXT_EVEN_FIELD); + break; + case TVENC_RESET_EVERY_FIELD: + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, + value | SC1200_TVENC_EXTERNAL_RESET_EVERY_FIELD); + break; + case TVENC_RESET_EVERY_X_ODD_FIELDS: + case TVENC_RESET_EVERY_X_EVEN_FIELDS: + return GFX_STATUS_UNSUPPORTED; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_enable + * + * This routine enables or disables the use of the hardware CC registers + * in the TV encoder. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_cc_enable(int enable) +#else +int +gfx_set_tv_cc_enable(int enable) +#endif +{ + unsigned long value; + + value = READ_VID32(SC1200_TVENC_CC_CONTROL); + value &= ~(0x0005F); + if (enable) + value |= 0x51; + WRITE_VID32(SC1200_TVENC_CC_CONTROL, value); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_tv_display + * + * This routine sets the timings in the display controller to support a + * TV resolution. + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_display(int width, int height) +#else +int +gfx_set_tv_display(int width, int height) +#endif +{ + DISPLAYMODE *pMode; + unsigned int i; + + for (i = 0; i < NUM_TV_MODES; i++) { + pMode = &TVTimings[i]; + if ((unsigned)width == pMode->hactive + && (unsigned)height == pMode->vactive) + break; + } + + if (i == NUM_TV_MODES) + return 0; + + gfx_set_display_timings(gfx_get_display_bpp(), + (unsigned short)pMode->flags, pMode->hactive, + pMode->hblankstart, pMode->hsyncstart, + pMode->hsyncend, pMode->hblankend, pMode->htotal, + pMode->vactive, pMode->vblankstart, + pMode->vsyncstart, pMode->vsyncend, + pMode->vblankend, pMode->vtotal, pMode->frequency); + + return 1; +} + +/*----------------------------------------------------------------------------- + * cc_add_parity_bit + * + * This routine adds the (odd) parity bit to the data character. + *----------------------------------------------------------------------------- + */ +unsigned char +cc_add_parity_bit(unsigned char data) +{ + int i, num = 0; + unsigned char d = data; + + for (i = 0; i < 7; i++) { + if (d & 0x1) + num++; + d >>= 1; + } + if (num & 0x1) + return (data & ~0x80); + else + return (data | 0x80); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_data + * + * This routine writes the two specified characters to the CC data register + * of the TV encoder. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_cc_data(unsigned char data1, unsigned char data2) +#else +int +gfx_set_tv_cc_data(unsigned char data1, unsigned char data2) +#endif +{ + unsigned long value; + + value = cc_add_parity_bit(data1) | (cc_add_parity_bit(data2) << 8); + WRITE_VID32(SC1200_TVENC_CC_DATA, value); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_test_tvout_odd_field + * + * This routine returns 1 if the current TVout field is odd. Otherwise returns 0. + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_test_tvout_odd_field(void) +#else +int +gfx_test_tvout_odd_field(void) +#endif +{ + unsigned long debug = READ_VID32(SC1200_TVOUT_DEBUG); + + WRITE_VID32(SC1200_TVOUT_DEBUG, debug | SC1200_TVOUT_FIELD_STATUS_TV); + if (READ_VID32(SC1200_TVOUT_DEBUG) & SC1200_TVOUT_FIELD_STATUS_EVEN) + return (0); + else + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_test_tvenc_odd_field + * + * This routine returns 1 if the current TV encoder field is odd. Otherwise returns 0. + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_test_tvenc_odd_field(void) +#else +int +gfx_test_tvenc_odd_field(void) +#endif +{ + unsigned long debug = READ_VID32(SC1200_TVOUT_DEBUG); + + WRITE_VID32(SC1200_TVOUT_DEBUG, debug & ~SC1200_TVOUT_FIELD_STATUS_TV); + if (READ_VID32(SC1200_TVOUT_DEBUG) & SC1200_TVOUT_FIELD_STATUS_EVEN) + return (0); + else + return (1); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_field_status_invert + * + * This routines determines whether the tvout/tvencoder field status bit is + * inverted (enable = 1) or not (enable = 0). + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_set_tv_field_status_invert(int enable) +#else +int +gfx_set_tv_field_status_invert(int enable) +#endif +{ + unsigned long value; + + value = READ_VID32(SC1200_TVOUT_DEBUG); + + if (enable) { + value |= SC1200_TVOUT_FIELD_STATUS_INVERT; + } else { + value &= ~(SC1200_TVOUT_FIELD_STATUS_INVERT); + } + + WRITE_VID32(SC1200_TVOUT_DEBUG, value); + + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_vphase + * + * This routine returns the tv encoder vertical phase. + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_get_tv_vphase(void) +#else +int +gfx_get_tv_vphase(void) +#endif +{ + unsigned long mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1); + + return (int)((mode & SC1200_TVENC_VPHASE_MASK) >> SC1200_TVENC_VPHASE_POS); +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_enable + * + * This routine returns the current tv enable status + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_get_tv_enable(unsigned int *p_on) +#else +int +gfx_get_tv_enable(unsigned int *p_on) +#endif +{ + unsigned long control = READ_VID32(SC1200_TVENC_DAC_CONTROL); + + *p_on = (unsigned int)(!(control & SC1200_TVENC_POWER_DOWN)); + + return GFX_STATUS_OK; +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_output + * + * This routine returns the current programmed TV output type. It does not + * detect invalid configurations. + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_get_tv_output(void) +#else +int +gfx_get_tv_output(void) +#endif +{ + unsigned long ctrl2, ctrl3; + int format = 0; + + ctrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2); + ctrl3 = READ_VID32(SC1200_TVENC_TIM_CTRL_3); + + if ((ctrl2 & SC1200_TVENC_CFS_MASK) == SC1200_TVENC_CFS_SVIDEO) + format = TV_OUTPUT_S_VIDEO; + else if (ctrl2 & SC1200_TVENC_OUTPUT_YCBCR) + format = TV_OUTPUT_YUV; + else if ((ctrl2 & SC1200_TVENC_CFS_MASK) == SC1200_TVENC_CFS_CVBS) { + if (ctrl3 & SC1200_TVENC_CM) + format = TV_OUTPUT_SCART; + else + format = TV_OUTPUT_COMPOSITE; + } + + return format; +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_mode_count + * + * This routine returns the number of valid TV out resolutions. + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_get_tv_mode_count(TVStandardType format) +#else +int +gfx_get_tv_mode_count(TVStandardType format) +#endif +{ + unsigned int mode, count = 0; + unsigned long flag; + + switch (format) { + case TV_STANDARD_NTSC: + flag = GFX_MODE_TV_NTSC; + break; + case TV_STANDARD_PAL: + flag = GFX_MODE_TV_PAL; + break; + default: + return 0; + } + + for (mode = 0; mode < NUM_TV_MODES; mode++) { + if (TVTimings[mode].flags & flag) + count++; + } + + return count; +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_display_mode + * + * This routine returns the current TV display parameters. + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_get_tv_display_mode(int *width, int *height, int *bpp, int *hz) +#else +int +gfx_get_tv_display_mode(int *width, int *height, int *bpp, int *hz) +#endif +{ + unsigned long frequency; + unsigned long mode, flags; + + *width = gfx_get_hactive(); + *height = gfx_get_vactive(); + *bpp = gfx_get_display_bpp(); + frequency = gfx_get_clock_frequency(); + + for (mode = 0; mode < NUM_TV_MODES; mode++) { + if (TVTimings[mode].hactive == (unsigned short)(*width) && + TVTimings[mode].vactive == (unsigned short)(*height) && + TVTimings[mode].frequency == frequency) { + flags = TVTimings[mode].flags; + + if (flags & GFX_MODE_TV_NTSC) + *hz = 60; + else if (flags & GFX_MODE_TV_PAL) + *hz = 50; + else + *hz = 0; + return (1); + } + } + + return -1; +} + +/*--------------------------------------------------------------------------- + * gfx_get_tv_display_mode_frequency + * + * This routine returns the PLL frequency of a given TV mode. + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_get_tv_display_mode_frequency(unsigned short width, + unsigned short height, + TVStandardType format, int *frequency) +#else +int +gfx_get_tv_display_mode_frequency(unsigned short width, unsigned short height, + TVStandardType format, int *frequency) +#endif +{ + unsigned long mode, flag; + int retval = -1; + + *frequency = 0; + + switch (format) { + case TV_STANDARD_NTSC: + flag = GFX_MODE_TV_NTSC; + break; + case TV_STANDARD_PAL: + flag = GFX_MODE_TV_PAL; + break; + default: + return -1; + } + + for (mode = 0; mode < NUM_TV_MODES; mode++) { + if ((TVTimings[mode].hactive == width) && + (TVTimings[mode].vactive == height) && + (TVTimings[mode].flags & flag)) { + *frequency = TVTimings[mode].frequency; + retval = 1; + } + } + return retval; +} + +/*--------------------------------------------------------------------------- + * gfx_is_tv_display_mode_supported + * + * Returns >= 0 if the mode is available, -1 if the mode could not be found + *--------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +sc1200_is_tv_display_mode_supported(unsigned short width, + unsigned short height, + TVStandardType format) +#else +int +gfx_is_tv_display_mode_supported(unsigned short width, unsigned short height, + TVStandardType format) +#endif +{ + unsigned long mode, flag; + + switch (format) { + case TV_STANDARD_NTSC: + flag = GFX_MODE_TV_NTSC; + break; + case TV_STANDARD_PAL: + flag = GFX_MODE_TV_PAL; + break; + default: + return -1; + } + + for (mode = 0; mode < NUM_TV_MODES; mode++) { + if (TVTimings[mode].hactive == width && + TVTimings[mode].vactive == height && + (TVTimings[mode].flags & flag)) { + return ((int)mode); + } + } + + return -1; +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.c new file mode 100644 index 000000000..b14bc1683 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.c @@ -0,0 +1,3562 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: tv_fs450.c $ + * + * This file contains routines to control the FS450 tvout encoder. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#define FS450_DIRECTREG 0 + +#include "tv_fs450.h" + +/*========================================================================== +* +* Macros +* +*========================================================================== +*/ + +#undef fsmax +#undef fsmin +#define fsmax(a, b) ((a) > (b) ? (a) : (b)) +#define fsmin(a, b) ((a) < (b) ? (a) : (b)) + +#undef range_limit +#define range_limit(val,min_val,max_val) (fsmax((min_val),fsmin((val),(max_val)))) + +/*========================================================================== +* +* Registers +* +*========================================================================== +*/ + +#define MAX_REGISTERS 32 +#define MAX_BITS 32 + +#define READ 1 +#define WRITE 2 +#define READ_WRITE (READ | WRITE) + +typedef struct +{ + char *name; + unsigned long offset; + unsigned char bit_length; + unsigned char valid_bits; + unsigned char read_write; + char *bitfield_names[MAX_BITS]; +} +S_REGISTER_DESCRIP; + +typedef struct +{ + int source; + char *name; + S_REGISTER_DESCRIP registers[MAX_REGISTERS]; +} +S_SET_DESCRIP; + +const S_SET_DESCRIP *houston_regs(void); +const S_SET_DESCRIP *encoder_regs(void); +const S_SET_DESCRIP *macrovision_regs(void); +const S_SET_DESCRIP *gcc_regs(void); + +/*========================================================================== +* +* Houston Register Addresses & Bit Definitions +* +*========================================================================== +*/ + +#define HOUSTON_IHO 0x00 /*Input Horizontal Offset */ +#define HOUSTON_IVO 0x02 /*Input Vertical Offset */ +#define HOUSTON_IHA 0x04 /*Input Horizontal Active Width */ +#define HOUSTON_VSC 0x06 /*Vertical Scaling Coeficient */ +#define HOUSTON_HSC 0x08 /*Horizontal Scaling Coeficient */ +#define HOUSTON_BYP 0x0A /*Bypass Register */ +#define HOUSTON_CR 0x0C /*Control Register */ +#define HOUSTON_SP 0x0E /*Status */ +#define HOUSTON_NCONL 0x10 /*NCO numerator low word */ +#define HOUSTON_NCONH 0x12 /*NCO numerator high word */ +#define HOUSTON_NCODL 0x14 /*NCO denominator low word */ +#define HOUSTON_NCODH 0x16 /*NCO denominator high word */ +#define HOUSTON_APO 0x18 /**/ +#define HOUSTON_ALO 0x1A /**/ +#define HOUSTON_AFO 0x1C /**/ +#define HOUSTON_HSOUTWID 0x1E /**/ +#define HOUSTON_HSOUTST 0x20 /**/ +#define HOUSTON_HSOUTEND 0x22 /**/ +#define HOUSTON_SHP 0x24 /*Sharpness */ +#define HOUSTON_FLK 0x26 /*Flicker Filter */ +#define HOUSTON_BCONTL 0x28 /**/ +#define HOUSTON_BCONTH 0x2A /**/ +#define HOUSTON_BDONE 0x2C /**/ +#define HOUSTON_BDIAGL 0x2E /**/ +#define HOUSTON_BDIAGH 0x30 /**/ +#define HOUSTON_REV 0x32 /**/ +#define HOUSTON_MISC 0x34 /**/ +#define HOUSTON_FFO 0x36 /**/ +#define HOUSTON_FFO_LAT 0x38 /**/ +#define HOUSTON_VSOUTWID 0x3A +#define HOUSTON_VSOUTST 0x3C +#define HOUSTON_VSOUTEND 0x3E +/*// BYP Register Bits*/ +#define BYP_RGB_BYPASS 0x0001 +#define BYP_HDS_BYPASS 0x0002 +#define BYP_HDS_TBYPASS 0x0004 +#define BYP_CAC_BYPASS 0x0008 +#define BYP_R2V_SBYPASS 0x0010 +#define BYP_R2V_BYPASS 0x0020 +#define BYP_VDS_BYPASS 0x0040 +#define BYP_FFT_BYPASS 0x0080 +#define BYP_FIF_BYPASS 0x0100 +#define BYP_FIF_TBYPASS 0x0200 +#define BYP_HUS_BYPASS 0x0400 +#define BYP_HUS_TBYPASS 0x0800 +#define BYP_CCR_BYPASS 0x1000 +#define BYP_PLL_BYPASS 0x2000 +#define BYP_NCO_BYPASS 0x4000 +#define BYP_ENC_BYPASS 0x8000 +/*// CR Register Bits*/ +#define CR_RESET 0x0001 +#define CR_CLKOFF 0x0002 +#define CR_NCO_EN 0x0004 +#define CR_COMPOFF 0x0008 +#define CR_YCOFF 0x0010 +#define CR_LP_EN 0x0020 +#define CR_CACQ_CLR 0x0040 +#define CR_FFO_CLR 0x0080 +#define CR_656_PAL_NTSC 0x0100 +#define CR_656_STD_VMI 0x0200 +#define CR_OFMT 0x0400 +#define CR_UIM_CLK 0x0800 +#define CR_UIM_DEC 0x1000 +#define CR_BIPGEN_EN1 0x2000 +#define CR_UIM_MOD0 0x4000 +#define CR_UIM_MOD1 0x8000 +/*// Status Register Bits*/ +#define SP_CACQ_ST 0x0001 +#define SP_FFO_ST 0x0002 +#define SP_REVID_MASK 0x7FFC +#define SP_MV_EN 0x8000 +/*// BDONE Register Bits*/ +#define BDONE_BIST_DONE_A 0x0001 +#define BDONE_BIST_DONE_B 0x0002 +#define BDONE_BIST_DONE_C 0x0004 +#define BDONE_BIST_DONE_D 0x0008 +#define BDONE_BIST_DONE_E 0x0010 +#define BDONE_BIST_DONE_F 0x0020 +#define BDONE_BIST_DONE_G 0x0040 +/*// BDIAGL Register Bits*/ +#define BDIAGL_BIST_DIAG_A 0x000F +#define BDIAGL_BIST_DIAG_B 0x00F0 +#define BDIAGL_BIST_DIAG_C 0x0F00 +#define BDIAGL_BIST_DIAG_D 0xF000 +/*// BDIAGH Register Bits*/ +#define BDIAGH_BIST_DIAG_E 0x000F +#define BDIAGH_BIST_DIAG_F 0x000F +#define BDIAGH_BIST_DIAG_G 0x000F +/*// MISC Register Bits*/ +#define MISC_TV_SHORT_FLD 0x0001 +#define MISC_ENC_TEST 0x0002 +#define MISC_DAC_TEST 0x0004 +#define MISC_MV_SOFT_EN 0x0008 +#define MISC_NCO_LOAD0 0x0010 +#define MISC_NCO_LOAD1 0x0020 +#define MISC_VGACKDIV 0x0200 +#define MISC_BRIDGE_SYNC 0x0400 +#define MISC_GTLIO_PD 0x8000 +/*========================================================================== +* +* Encoder Registers & Bit Definitions +* +*========================================================================== +*/ +#define ENC_CHROMA_FREQ 0x40 +#define ENC_CHROMA_PHASE 0x44 +#define ENC_REG05 0x45 +#define ENC_REG06 0x46 +#define ENC_REG07 0x47 +#define ENC_HSYNC_WIDTH 0x48 +#define ENC_BURST_WIDTH 0x49 +#define ENC_BACK_PORCH 0x4A +#define ENC_CB_BURST_LEVEL 0x4B +#define ENC_CR_BURST_LEVEL 0x4C +#define ENC_SLAVE_MODE 0x4D +#define ENC_BLACK_LEVEL 0x4e +#define ENC_BLANK_LEVEL 0x50 +#define ENC_NUM_LINES 0x57 +#define ENC_WHITE_LEVEL 0x5e +#define ENC_CB_GAIN 0x60 +#define ENC_CR_GAIN 0x62 +#define ENC_TINT 0x65 +#define ENC_BREEZE_WAY 0x69 +#define ENC_FRONT_PORCH 0x6C +#define ENC_ACTIVELINE 0x71 +#define ENC_FIRST_LINE 0x73 +#define ENC_REG34 0x74 +#define ENC_SYNC_LEVEL 0x75 +#define ENC_VBI_BLANK_LEVEL 0x7C +#define ENC_RESET 0x7e +#define ENC_NOTCH_FILTER 0x8d +/*========================================================================== +* +* Macrovision Registers & Bit Definitions +* +*========================================================================== +*/ +#define MV_N0 0x59 +#define MV_N1 0x52 +#define MV_N2 0x7b +#define MV_N3 0x53 +#define MV_N4 0x79 +#define MV_N5 0x5d +#define MV_N6 0x7a +#define MV_N7 0x64 +#define MV_N8 0x54 +#define MV_N9 0x55 +#define MV_N10 0x56 +#define MV_N11 0x6d +#define MV_N12 0x6f +#define MV_N13 0x5a +#define MV_N14 0x5b +#define MV_N15 0x5c +#define MV_N16 0x63 +#define MV_N17 0x66 +#define MV_N18 0x68 +#define MV_N19 0x67 +#define MV_N20 0x61 +#define MV_N21 0x6a +#define MV_N22 0x76 +#define MV_AGC_PULSE_LEVEL 0x77 +#define MV_BP_PULSE_LEVEL 0x78 +/*========================================================================== +* +* The TRACE macro can be used to display debug information. It can display +* one or more parameters in a formatted string like printf. No code will be +* generated for a release build. Use double parentheses for compatibility +* with C #define statements. Newline characters are not added +* automatically. Usage example: +* +* TRACE(("Number is %d, Name is %s.\n",iNumber,lpszName)) +* +*========================================================================== +*/ +/*//#ifdef _DEBUG*/ +/*//void trace(const char *p_fmt,...);*/ +/*//#define TRACE(parameters) {trace parameters;}*/ +/*//#else*/ +#define TRACE(parameters) {} +/*//#endif*/ +/****/ +/*// GCC timing structure.*/ +/****/ + typedef struct _S_TIMING_SPECS +{ + int vga_width; + int vga_lines; + int tv_width; + int tv_lines; + int h_total; + int h_sync; + int v_total; + int v_sync; +} +S_TIMING_SPECS; + +/****/ +/*// Revision of Houston chip*/ +/****/ +#define HOUSTON_REV_A 0 +#define HOUSTON_REV_B 1 +static int houston_Rev(void); + +/*========================================================================== +* +* Functions +* +*========================================================================== +*/ + +static int houston_init(void); + +static unsigned char PLAL_FS450_i2c_address(void); +static int PLAL_FS450_UIM_mode(void); +static int PLAL_ReadRegister(S_REG_INFO * p_reg); +static int PLAL_WriteRegister(const S_REG_INFO * p_reg); +static int PLAL_IsTVOn(void); +static int PLAL_EnableVga(void); +static int PLAL_PrepForTVout(void); +static int PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs); +static int PLAL_FinalEnableTVout(unsigned long vga_mode); + +/****/ +/*Direct Memory Access Functions*/ +/****/ +/*NOTE: Cx5530 is assumed hardcoded at 0x10000 offset*/ +/*from MediaGX base. F4Bar is bogus as described in the*/ +/*Cx5530 datasheet (actually points to GX frame buffer).*/ +/****/ +static int +DMAL_ReadUInt32(unsigned long phys_addr, unsigned long *p_data) +{ + *p_data = READ_REG32(phys_addr); + return 0; +} + +static int +DMAL_WriteUInt32(unsigned long phys_addr, unsigned long data) +{ + WRITE_REG32(phys_addr, data); + return 0; +} + +/****/ +/*Houston register access functions.*/ +/****/ +static int +houston_ReadReg(unsigned int reg, unsigned long *p_value, unsigned int bytes) +{ + return gfx_i2c_read(1, PLAL_FS450_i2c_address(), (unsigned char)reg, + (unsigned char)bytes, (unsigned char *)p_value); +} + +static int +houston_WriteReg(unsigned int reg, unsigned long value, unsigned int bytes) +{ + return gfx_i2c_write(1, PLAL_FS450_i2c_address(), (unsigned char)reg, + (unsigned char)bytes, (unsigned char *)&value); +} + +/****/ +/*TV configuration functions.*/ +/****/ +static int config_init(void); +static const S_TIMING_SPECS *p_specs(void); +static void config_power(int on); +static void config_vga_mode(unsigned long vga_mode); +static void config_tv_std(unsigned long tv_std, unsigned int trigger_bits); +static void conget_tv_std(unsigned long *p_tv_std); +static unsigned long supported_standards(void); +static void config_tvout_mode(unsigned long tvout_mode); +static void conget_tvout_mode(unsigned long *p_tvout_mode); +static void config_overscan_xy(unsigned long tv_std, unsigned long vga_mode, + int overscan_x, int overscan_y, int pos_x, + int pos_y); +static void config_nco(unsigned long tv_std, unsigned long vga_mode); +static void config_sharpness(int sharpness); +static void conget_sharpness(int *p_sharpness); +static void config_flicker(int flicker); +static void conget_flicker(int *p_flicker); +static void config_color(int color); +static void conget_color(int *p_color); +static void config_brightness_contrast(unsigned long tv_std, + unsigned int trigger_bits, + int brightness, int contrast); +static void conget_brightness_contrast(unsigned long tv_std, + unsigned int trigger_bits, + int *p_brightness, int *p_contrast); +static void config_yc_filter(unsigned long tv_std, int luma_filter, + int chroma_filter); +static void conget_yc_filter(int *p_luma_filter, int *p_chroma_filter); +static void config_macrovision(unsigned long tv_std, + unsigned int cp_trigger_bits); +static void conget_macrovision(unsigned long tv_std, + unsigned int *p_cp_trigger_bits); + +/****/ +/*Device settings.*/ +/****/ +typedef struct _S_DEVICE_SETTINGS +{ + int tv_on; + unsigned long vga_mode; + unsigned long tv_std; + unsigned long tvout_mode; + int overscan_x; + int overscan_y; + int position_x; + int position_y; + int sharpness; + int flicker; + int color; + int brightness; + int contrast; + unsigned char yc_filter; + unsigned int aps_trigger_bits; + int last_overscan_y; +} +S_DEVICE_SETTINGS; + +static S_DEVICE_SETTINGS d; + +/*//==========================================================================*/ +/****/ +/*TV Setup Parameters*/ +/****/ +/*//==========================================================================*/ + +static const struct +{ + unsigned long chroma_freq[5]; + unsigned short chroma_phase[5]; + unsigned short cphase_rst[5]; + unsigned short color[5]; + unsigned short cr_burst_level[5]; + unsigned short cb_burst_level[5]; + unsigned short sys625_50[5]; + unsigned short vsync5[5]; + unsigned short pal_mode[5]; + unsigned short hsync_width[5]; + unsigned short burst_width[5]; + unsigned short back_porch[5]; + unsigned short front_porch[5]; + unsigned short breeze_way[5]; + unsigned short activeline[5]; + unsigned short blank_level[5]; + unsigned short vbi_blank_level[5]; + unsigned short black_level[5]; + unsigned short white_level[5]; + unsigned short hamp_offset[5]; + unsigned short sync_level[5]; + unsigned short tv_lines[5]; + unsigned short tv_width[5]; + unsigned short tv_active_lines[5]; + unsigned short tv_active_width[5]; + unsigned char notch_filter[5]; + unsigned short houston_cr[5]; + unsigned short houston_ncodl[5]; + unsigned short houston_ncodh[5]; +} +tvsetup = +{ + /* ntsc, pal, ntsc-eij, pal-m, pal-n */ + { + 0x1f7cf021, 0xcb8a092a, 0x1f7cf021, 0xe3efe621, 0xcb8a092a} + , /*chroma_freq */ + { + 0, 0, 0, 0, 0} + , /*chroma_phase */ + { + 2, 0, 2, 0, 0} + , /*cphase_rst */ + { + 54, 43, 54, 43, 43} + , /*color */ + { + 0, 31, 0, 29, 29} + , /*cr_burst_level */ + { + 59, 44, 59, 41, 41} + , /*cb_burst_level */ + { + 0, 1, 0, 0, 1} + , /*sys625_50 */ + { + 0, 1, 0, 0, 0} + , /*vsync5 */ + { + 0, 1, 0, 1, 1} + , /*pal_mode */ + { + 0x7a, 0x7a, 0x7a, 0x7a, 0x7a} + , /*hsync_width */ + { + 0x40, 0x3c, 0x40, 0x40, 0x3c} + , /*burst_width */ + { + 0x80, 0x9a, 0x80, 0x80, 0x9a} + , /*back_porch */ + { + 0x24, 0x1e, 0x24, 0x24, 0x1e} + , /*front_porch */ + { + 0x19, 0x1a, 0x19, 0x12, 0x1a} + , /*breeze_way */ + { + 0xb4, 0xb4, 0xb4, 0xb4, 0xb4} + , /*active_line */ + { + 240, 251, 240, 240, 240} + , /*blank_level */ + { + 240, 251, 240, 240, 240} + , /*vbi_blank_level */ + { + 284, 252, 240, 252, 252} + , /*black_level */ + { + 823, 821, 823, 821, 821} + , /*white_level */ + { + 60, 48, 60, 48, 48} + , /*hamp_offset */ + { + 0x08, 0x08, 0x08, 0x08, 0x08} + , /*sync_level */ + { + 525, 625, 525, 525, 625} + , /*tv_lines */ + { + 858, 864, 858, 858, 864} + , /*tv_width */ + { + 487, 576, 487, 487, 576} + , /*tv_active_lines */ + { + 800, 800, 800, 800, 800} + , /*tv_active_width */ + { + 0x1a, 0x1d, 0x1a, 0x1d, 0x1d} + , /*notch filter enabled */ + { + 0x0000, 0x0100, 0x0000, 0x0000, 0x0100} + , /*houston cr pal */ + { + 0x7e48, 0xf580, 0x7e48, 0x7e48, 0xf580} + , /*houston ncodl */ + { + 0x001b, 0x0020, 0x001b, 0x001b, 0x0020} /*houston ncodh */ +}; + +/****/ +/*MediaGX default underscan and centered position setups.*/ +/****/ +#define SCANTABLE_ENTRIES 5 +struct _scantable +{ + unsigned long mode; + unsigned short v_total[5]; + unsigned short v_sync[5]; + unsigned short iha[5]; + signed short iho[5]; + signed short hsc[5]; +}; + +static struct _scantable scantable[SCANTABLE_ENTRIES] = { + { + GFX_VGA_MODE_640X480, + {617, 624, 617, 624, 624}, /*v_total */ + {69, 88, 69, 88, 88}, /*v_sync */ + {720, 720, 720, 720, 720}, /*iha */ + {0, 0, 0, 0, 0}, /*iho */ + {-12, 0, -6, 0, 0} /*hsc */ + }, + { + GFX_VGA_MODE_800X600, + {740, 740, 740, 740, 740}, /*v_total */ + {90, 88, 90, 88, 88}, /*v_sync */ + {720, 720, 508, 720, 720}, /*iha */ + {-8, 11, -8, -8, 11}, /*iho */ + {-27, -27, -27, -27, -27} /*hsc */ + }, + { + GFX_VGA_MODE_720X487, + {525, 720, 525, 720, 720}, /*v_total */ + {23, 230, 23, 230, 230}, /*v_sync */ + {720, 720, 720, 720, 720}, /*iha */ + {0xa2, 0xa2, 0xa2, 0xa2, 0xa2}, /*iho */ + {0, 0, 0, 0, 0} /*hsc */ + }, + { + GFX_VGA_MODE_720X576, + {720, 625, 720, 625, 625}, /*v_total */ + {129, 25, 129, 25, 25}, /*v_sync */ + {720, 720, 720, 720, 720}, /*iha */ + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, /*iho */ + {0, 0, 0, 0, 0} /*hsc */ + }, + { + GFX_VGA_MODE_1024X768, + {933, 942, 933, 806, 806}, /*v_total */ + {121, 112, 121, 88, 88}, /*v_sync */ + {600, 600, 600, 600, 600}, /*iha */ + {0x3c, 0x23, 0x3c, 0x65, 0x65}, /*iho */ + {35, 26, 35, 26, 26} /*hsc */ + }, +}; + +/****/ +/*Houston fifo configuration constants.*/ +/****/ +struct _ffolat +{ + int v_total; + unsigned short ffolat; +}; + +struct _ffolativo +{ + int v_total; + unsigned short ivo; + unsigned short ffolat; +}; + +/*h_total=832, ivo=40, tv_width=858, tv_lines=525, vga_lines=480*/ +#define SIZE6X4NTSC 66 +static struct _ffolat ffo6x4ntsc[SIZE6X4NTSC + 1] = { + {541, 0x40}, {545, 0x40}, {549, 0x40}, {553, 0x40}, + {557, 0x58}, {561, 0x40}, {565, 0x40}, {569, 0x40}, + {573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40}, + {589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40}, + {605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48}, + {621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40}, + {637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56}, + {653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40}, + {669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40}, + {685, 0x40}, {689, 0x40}, {693, 0x40}, {697, 0x40}, + {701, 0x40}, {705, 0x40}, {709, 0x40}, {713, 0x40}, + {717, 0x40}, {721, 0x40}, {725, 0x40}, {729, 0x40}, + {733, 0x40}, {737, 0x40}, {741, 0x40}, {745, 0x40}, + {749, 0x40}, {753, 0x40}, {757, 0x40}, {761, 0x40}, + {765, 0x40}, {769, 0x40}, {773, 0x40}, {777, 0x40}, + {781, 0x40}, {785, 0x40}, {789, 0x40}, {793, 0x40}, + {797, 0x30}, {801, 0x40}, + {-1, 0} +}; + +#define SIZE6X4PAL 45 +static struct _ffolat ffo6x4pal[SIZE6X4PAL + 1] = { + {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60}, + {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60}, + {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60}, + {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60}, + {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60}, + {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60}, + {721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60}, + {737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60}, + {753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60}, + {769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60}, + {785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60}, + {801, 0x60}, + {-1, 0} +}; + +#define SIZE7X4NTSC 40 +static struct _ffolat ffo7x4ntsc[SIZE7X4NTSC + 1] = { + {525, 0x52}, {529, 0x52}, {533, 0x52}, {537, 0x52}, + {541, 0x52}, {545, 0x40}, {549, 0x40}, {553, 0x40}, + {557, 0x58}, {561, 0x40}, {565, 0x58}, {569, 0x40}, + {573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40}, + {589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40}, + {605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48}, + {621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40}, + {637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56}, + {653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40}, + {669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40}, + {-1, 0} +}; + +#define SIZE7X4PAL 24 +static struct _ffolat ffo7x4pal[SIZE7X4PAL + 1] = { + {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60}, + {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60}, + {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60}, + {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60}, + {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60}, + {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60}, + {-1, 0} +}; + +#define SIZE7X5NTSC 54 +static struct _ffolat ffo7x5ntsc[SIZE7X5NTSC + 1] = { + {590, 0x40}, {594, 0x48}, {598, 0x40}, {602, 0x40}, + {606, 0x40}, {610, 0x40}, {614, 0x5b}, {618, 0x48}, + {622, 0x60}, {626, 0x48}, {630, 0x48}, {634, 0x40}, + {638, 0x5e}, {642, 0x40}, {646, 0x50}, {650, 0x56}, + {654, 0x58}, {658, 0x6c}, {662, 0x40}, {666, 0x40}, + {670, 0x40}, {674, 0x40}, {678, 0x40}, {682, 0x40}, + {686, 0x40}, {690, 0x40}, {694, 0x40}, {698, 0x40}, + {702, 0x40}, {706, 0x40}, {710, 0x40}, {714, 0x40}, + {718, 0x40}, {722, 0x40}, {726, 0x40}, {730, 0x40}, + {734, 0x40}, {738, 0x40}, {742, 0x40}, {746, 0x40}, + {750, 0x40}, {754, 0x40}, {758, 0x40}, {762, 0x40}, + {766, 0x40}, {770, 0x40}, {774, 0x40}, {778, 0x40}, + {782, 0x40}, {786, 0x40}, {790, 0x40}, {794, 0x40}, + {798, 0x30}, {802, 0x40}, + {-1, 0} +}; + +#define SIZE7X5PAL 45 +static struct _ffolat ffo7x5pal[SIZE7X5PAL + 1] = { + {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60}, + {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60}, + {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60}, + {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60}, + {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60}, + {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60}, + {721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60}, + {737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60}, + {753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60}, + {769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60}, + {785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60}, + {801, 0x60}, + {-1, 0} +}; + +/*h_total=1056, vga_lines=600*/ +#define SIZE8X6NTSC 37 +static struct _ffolat ffo8x6ntsc[SIZE8X6NTSC + 1] = { + {620, 0x40}, /*v_total_min >= vsync+10 >= vga_lines+10 = 610 */ + {625, 0x58}, {630, 0x40}, {635, 0x40}, {640, 0x40}, + {645, 0x46}, {650, 0x46}, {655, 0x4f}, {660, 0x4c}, + {665, 0x4a}, {670, 0x50}, {675, 0x2f}, {680, 0x48}, + {685, 0x38}, {690, 0x31}, {695, 0x40}, {700, 0x21}, + {705, 0x25}, {710, 0x40}, {715, 0x48}, {720, 0x50}, + {725, 0x30}, {730, 0x50}, {735, 0x50}, {740, 0x50}, + {745, 0x40}, {750, 0x38}, {755, 0x50}, {760, 0x50}, + {765, 0x40}, {770, 0x38}, {775, 0x40}, {780, 0x40}, + {785, 0x40}, {790, 0x38}, {795, 0x50}, {800, 0x50}, + {-1, 0} +}; + +/*h_total=1056, vga_lines=600*/ +#define SIZE8X6PAL 36 +static struct _ffolat ffo8x6pal[SIZE8X6PAL + 1] = { + {625, 0x80}, {630, 0x80}, {635, 0x5a}, {640, 0x55}, + {645, 0x48}, {650, 0x65}, {655, 0x65}, {660, 0x50}, + {665, 0x80}, {670, 0x70}, {675, 0x56}, {680, 0x80}, + {685, 0x58}, {690, 0x31}, {695, 0x80}, {700, 0x60}, + {705, 0x45}, {710, 0x4a}, {715, 0x50}, {720, 0x50}, + {725, 0x50}, {730, 0x45}, {735, 0x50}, {740, 0x50}, + {745, 0x50}, {750, 0x50}, {755, 0x50}, {760, 0x50}, + {765, 0x50}, {770, 0x50}, {775, 0x50}, {780, 0x50}, + {785, 0x50}, {790, 0x50}, {795, 0x50}, {800, 0x50}, + {-1, 0} +}; + +/*h_total=1344, vga_lines=768*/ +#define SIZE10X7NTSC 45 +static struct _ffolativo ffo10x7ntsc[SIZE10X7NTSC] = { + {783, 0x4d, 0x40}, + {789, 0x47, 0x14}, + {795, 0x47, 0x7f}, + {801, 0x47, 0x53}, + {807, 0x47, 0x11}, + {813, 0x47, 0x78}, + {819, 0x47, 0x54}, + {825, 0x47, 0x40}, + {831, 0x47, 0x0f}, + {837, 0x4d, 0x40}, + {843, 0x47, 0x5a}, + {849, 0x4d, 0x40}, + {855, 0x47, 0x4b}, + {861, 0x4d, 0x40}, + {867, 0x47, 0x4b}, + {873, 0x4d, 0x40}, + {879, 0x47, 0x07}, + {885, 0x48, 0x20}, + {891, 0x47, 0x82}, + {897, 0x47, 0x60}, + {903, 0x47, 0x7f}, + {909, 0x4d, 0x40}, + {915, 0x48, 0x40}, + {921, 0x4c, 0x40}, + {927, 0x49, 0x40}, + {933, 0x48, 0x40}, + {939, 0x4a, 0x40}, + {945, 0x46, 0x40}, + {951, 0x4a, 0x40}, + {957, 0x4a, 0x40}, + {963, 0x4b, 0x40}, + {969, 0x4b, 0x40}, + {975, 0x48, 0x40}, + {981, 0x47, 0x40}, + {987, 0x47, 0x40}, + {993, 0x47, 0x40}, + {999, 0x48, 0x40}, + {1005, 0x48, 0x40}, + {1011, 0x47, 0x40}, + {1017, 0x47, 0x40}, + {1023, 0x48, 0x40}, + {1029, 0x48, 0x40}, + {1035, 0x46, 0x40}, + {1041, 0x47, 0x40}, + {1047, 0x47, 0x40} +}; + +/*h_total=1344, vga_lines=768*/ +#define SIZE10X7PAL 46 +static struct _ffolativo ffo10x7pal[SIZE10X7PAL] = { + {781, 0x49, 0x40}, + {787, 0x46, 0x40}, + {793, 0x48, 0x40}, + {799, 0x46, 0x40}, + {805, 0x49, 0x40}, + {811, 0x47, 0x40}, + {817, 0x46, 0x40}, + {823, 0x46, 0x56}, + {829, 0x46, 0x2d}, + {835, 0x46, 0x40}, + {841, 0x46, 0x2d}, + {847, 0x46, 0x3f}, + {853, 0x46, 0x10}, + {859, 0x46, 0x86}, + {865, 0x46, 0xc9}, + {871, 0x46, 0x83}, + {877, 0x46, 0xa8}, + {883, 0x46, 0x81}, + {889, 0x46, 0xa5}, + {895, 0x46, 0xa9}, + {901, 0x46, 0x81}, + {907, 0x46, 0xa4}, + {913, 0x46, 0xa5}, + {919, 0x46, 0x7f}, + {925, 0x46, 0xa2}, + {931, 0x46, 0x9d}, + {937, 0x46, 0xc1}, + {943, 0x46, 0x96}, + {949, 0x46, 0xb7}, + {955, 0x46, 0xb1}, + {961, 0x46, 0x8a}, + {967, 0x46, 0xa9}, + {973, 0x46, 0xa0}, + {979, 0x46, 0x40}, + {985, 0x46, 0x97}, + {991, 0x46, 0xb5}, + {997, 0x46, 0xaa}, + {1003, 0x46, 0x83}, + {1009, 0x46, 0x9f}, + {1015, 0x47, 0x40}, + {1021, 0x46, 0xad}, + {1027, 0x46, 0x87}, + {1033, 0x46, 0xa2}, + {1039, 0x47, 0x40}, + {1045, 0x46, 0xac}, + {1051, 0x46, 0x86} +}; + +/*//==========================================================================*/ +/****/ +/*FS450 API Functions.*/ +/****/ +/*//==========================================================================*/ + +/****/ +/*Initialize device settings*/ +/****/ +static void +initialize_houston_static_registers(void) +{ + houston_WriteReg(HOUSTON_BYP, 0, 2); + houston_WriteReg(HOUSTON_APO, 0, 2); + houston_WriteReg(HOUSTON_ALO, 0, 2); + houston_WriteReg(HOUSTON_AFO, 0, 2); + houston_WriteReg(HOUSTON_BCONTL, 0, 2); + houston_WriteReg(HOUSTON_BCONTH, 0, 2); + houston_WriteReg(HOUSTON_BDONE, 0, 2); + houston_WriteReg(HOUSTON_BDIAGL, 0, 2); + houston_WriteReg(HOUSTON_BDIAGH, 0, 2); + houston_WriteReg(HOUSTON_MISC, 0, 2); +} + +int +FS450_init(void) +{ + int err; + + TRACE(("FS450_Init()\n")) + + err = houston_init(); + if (err) + return err; + + initialize_houston_static_registers(); + +#if 1 + d.tv_on = PLAL_IsTVOn()? 1 : 0; +#else + d.tv_on = 0; +#endif + +#if 1 + /*get the current tv standard */ + conget_tv_std(&d.tv_std); +#else + /*default to VP_TV_STANDARD_NTSC_M */ + d.tv_std = VP_TV_STANDARD_NTSC_M; + config_tv_std(d.tv_std); +#endif + + d.vga_mode = 0; + +#if 0 + /*get the current tvout mode */ + conget_tvout_mode(&d.tvout_mode); +#else + /*default to VP_TVOUT_MODE_CVBS_YC */ + d.tvout_mode = GFX_TVOUT_MODE_CVBS_YC; +#endif + +#if 0 + /*get the current sharpness */ + conget_sharpness(d.sharpness); +#else + /*default to 1000 out of 1000 */ + d.sharpness = 1000; + config_sharpness(d.sharpness); +#endif + +#if 0 + /*get the current flicker */ + conget_flicker(d.flicker); +#else + /*default to 800 out of 1000 */ + d.flicker = 800; + config_flicker(d.flicker); +#endif + +#if 0 + /*get the current size and position */ +#else + /*default to zeros */ + d.overscan_x = 0; + d.overscan_y = 0; + d.position_x = 0; + d.position_y = 0; +#endif + +#if 0 + /*get the current color */ + conget_color(d.color); +#else + d.color = 50; + /*//d.color = tvsetup.color[k]; */ + config_color(d.color); +#endif + +#if 0 + /*get the current brightness and contrast */ + conget_brightness_contrast(d.tv_std, d.aps_trigger_bits, d.brightness, + d.contrast); +#else + /*default */ + d.brightness = 50; + d.contrast = 60; + config_brightness_contrast(d.tv_std, d.aps_trigger_bits, d.brightness, + d.contrast); +#endif + +#if 1 + /*get the current yc filtering */ + { + int luma_filter, chroma_filter; + + conget_yc_filter(&luma_filter, &chroma_filter); + d.yc_filter = 0; + if (luma_filter) + d.yc_filter |= GFX_LUMA_FILTER; + if (chroma_filter) + d.yc_filter |= GFX_CHROMA_FILTER; + } +#else + /*default */ + d.yc_filter = GFX_LUMA_FILTER + GFX_CHROMA_FILTER; +#endif + +#if 0 + /*get the current cp settings */ + conget_macrovision(d.tv_std, &d.aps_trigger_bits); +#else + d.aps_trigger_bits = 0; + config_macrovision(d.tv_std, d.aps_trigger_bits); +#endif + + d.last_overscan_y = -10000; + + return 0; +} + +void +FS450_cleanup(void) +{ +} + +/*//==========================================================================*/ +/****/ +/*// Required configuration calls to write new settings to the device*/ + +#define REQ_TV_STANDARD_BIT 0x0002 +#define REQ_VGA_MODE_BIT 0x0004 +#define REQ_TVOUT_MODE_BIT 0x0008 +#define REQ_SHARPNESS_BIT 0x0010 +#define REQ_FLICKER_BIT 0x0020 +#define REQ_OVERSCAN_POSITION_BIT 0x0040 +#define REQ_COLOR_BIT 0x0080 +#define REQ_BRIGHTNESS_CONTRAST_BIT 0x0100 +#define REQ_YC_FILTER_BIT 0x0200 +#define REQ_MACROVISION_BIT 0x0400 +#define REQ_NCO_BIT 0x1000 + +#define REQ_TV_STANDARD (REQ_TV_STANDARD_BIT | REQ_OVERSCAN_POSITION | REQ_BRIGHTNESS_CONTRAST | REQ_MACROVISION_BIT | REQ_YC_FILTER) +#define REQ_VGA_MODE (REQ_VGA_MODE_BIT | REQ_OVERSCAN_POSITION) +#define REQ_TVOUT_MODE (REQ_TVOUT_MODE_BIT) +#define REQ_SHARPNESS (REQ_SHARPNESS_BIT) +#define REQ_FLICKER (REQ_FLICKER_BIT) +#define REQ_OVERSCAN_POSITION (REQ_OVERSCAN_POSITION_BIT | REQ_NCO) +#define REQ_COLOR (REQ_COLOR_BIT) +#define REQ_BRIGHTNESS_CONTRAST (REQ_BRIGHTNESS_CONTRAST_BIT) +#define REQ_YC_FILTER (REQ_YC_FILTER_BIT) +#define REQ_MACROVISION (REQ_TV_STANDARD_BIT | REQ_BRIGHTNESS_CONTRAST_BIT | REQ_MACROVISION_BIT) +#define REQ_NCO (REQ_NCO_BIT) +#define REQ_ENCODER (REQ_TV_STANDARD | REQ_COLOR | REQ_BRIGHTNESS_CONTRAST | REQ_YC_FILTER) + +static int +write_config(int req) +{ + unsigned long reg, reg_encoder_reset = 0; + int reset; + + /*if we're changing the nco, and the vertical scaling has changed... */ + reset = ((REQ_NCO_BIT & req) && (d.overscan_y != d.last_overscan_y)); + if (reset) { + /*put the encoder into reset while making changes */ + houston_ReadReg(ENC_RESET, ®, 1); + houston_WriteReg(ENC_RESET, reg | 0x01, 1); + reg_encoder_reset = reg & 0x01; + } + + if (REQ_TV_STANDARD_BIT & req) + config_tv_std(d.tv_std, d.aps_trigger_bits); + + if (REQ_VGA_MODE_BIT & req) + config_vga_mode(d.vga_mode); + + if (REQ_TVOUT_MODE_BIT & req) + config_tvout_mode(d.tvout_mode); + + if (REQ_OVERSCAN_POSITION_BIT & req) { + config_overscan_xy(d.tv_std, + d.vga_mode, + d.overscan_x, + d.overscan_y, d.position_x, d.position_y); + + /*h_timing and v_timing and syncs. */ + if (PLAL_IsTVOn()) + PLAL_SetTVTimingRegisters(p_specs()); + } + + if (REQ_NCO_BIT & req) + config_nco(d.tv_std, d.vga_mode); + + if (REQ_SHARPNESS_BIT & req) + config_sharpness(d.sharpness); + + if (REQ_FLICKER_BIT & req) + config_flicker(d.flicker); + + if (REQ_COLOR_BIT & req) + config_color(d.color); + + if (REQ_BRIGHTNESS_CONTRAST_BIT & req) { + config_brightness_contrast(d.tv_std, + d.aps_trigger_bits, + d.brightness, d.contrast); + } + + if (REQ_YC_FILTER_BIT & req) { + config_yc_filter(d.tv_std, + (d.yc_filter & GFX_LUMA_FILTER), + (d.yc_filter & GFX_CHROMA_FILTER)); + } + + if (REQ_MACROVISION_BIT & req) + config_macrovision(d.tv_std, d.aps_trigger_bits); + + /*if we decided to put the encoder into reset, put it back */ + if (reset) { + houston_ReadReg(ENC_RESET, ®, 1); + houston_WriteReg(ENC_RESET, reg_encoder_reset | (reg & ~0x01), 1); + + d.last_overscan_y = d.overscan_y; + } + return 0; +} + +/*==========================================================================*/ +/****/ +/*// TV On*/ + +#if GFX_TV_DYNAMIC +int +fs450_get_tv_enable(unsigned int *p_on) +#else +int +gfx_get_tv_enable(unsigned int *p_on) +#endif +{ + if (!p_on) + return ERR_INVALID_PARAMETER; + + *p_on = d.tv_on; + + return 0; +} + +/*//int FS450_set_tv_on(unsigned int on)*/ +#if GFX_TV_DYNAMIC +int +fs450_set_tv_enable(int on) +#else +int +gfx_set_tv_enable(int on) +#endif +{ + unsigned long reg; + + /*if not mode change, just return */ + if ((d.tv_on && on) || (!d.tv_on && !on)) + return 0; + + /*if turning off... */ + if (!on) { + /*reenable vga. */ + PLAL_EnableVga(); + + /*power down houston */ + config_power(0); + + d.tv_on = 0; + + return 0; + } + + /*turning on... */ + + /*power up houston */ + config_power(1); + + /*assert encoder reset. */ + houston_WriteReg(ENC_RESET, 0x01, 1); + + /*initial platform preparation */ + PLAL_PrepForTVout(); + + /*configure encoder and nco. */ + write_config(REQ_VGA_MODE | + REQ_TV_STANDARD | + REQ_TVOUT_MODE | + REQ_OVERSCAN_POSITION | REQ_YC_FILTER | REQ_MACROVISION); + + /*set LP_EN and UIM */ + houston_ReadReg(HOUSTON_CR, ®, 2); + reg |= CR_LP_EN; + reg &= ~(CR_UIM_MOD0 | CR_UIM_MOD1); + reg |= (PLAL_FS450_UIM_mode() << 14); + houston_WriteReg(HOUSTON_CR, reg, 2); + + /*set platform timing registers */ + PLAL_SetTVTimingRegisters(p_specs()); + + PLAL_FinalEnableTVout(d.vga_mode); + + /*sync bridge */ + { + int retry_count = 0; + + /*sync 50 times */ + while (retry_count++ < 50) { + /*sync bridge. */ + houston_ReadReg(HOUSTON_MISC, ®, 2); + reg |= MISC_BRIDGE_SYNC; + houston_WriteReg(HOUSTON_MISC, reg, 2); + reg &= ~MISC_BRIDGE_SYNC; + houston_WriteReg(HOUSTON_MISC, reg, 2); + } + } + + /*deassert encoder reset. */ + houston_WriteReg(ENC_RESET, 0x00, 1); + + d.tv_on = 1; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_tv_defaults(int format) +#else +int +gfx_set_tv_defaults(int format) +#endif +{ + return 0; +} + +/*==========================================================================*/ +/****/ +/*// TV standard*/ + +#if GFX_TV_DYNAMIC +int +fs450_get_tv_standard(unsigned long *p_standard) +#else +int +gfx_get_tv_standard(unsigned long *p_standard) +#endif +{ + if (!p_standard) + return ERR_INVALID_PARAMETER; + + *p_standard = d.tv_std; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_get_available_tv_standards(unsigned long *p_standards) +#else +int +gfx_get_available_tv_standards(unsigned long *p_standards) +#endif +{ + if (!p_standards) + return ERR_INVALID_PARAMETER; + + *p_standards = supported_standards(); + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_tv_standard(unsigned long standard) +#else +int +gfx_set_tv_standard(unsigned long standard) +#endif +{ + /*verify supported standard. */ + if (!(standard & supported_standards())) + return ERR_INVALID_PARAMETER; + + /*disallow if tv is on */ + if (d.tv_on) + return ERR_CANNOT_CHANGE_WHILE_TV_ON; + + d.tv_std = standard; +/*// d.color = tvsetup.color[k];*/ + + return write_config(REQ_TV_STANDARD); +} + +/*==========================================================================*/ +/****/ +/*// vga mode as known by the driver*/ +#if GFX_TV_DYNAMIC +int +fs450_get_tv_vga_mode(unsigned long *p_vga_mode) +#else +int +gfx_get_tv_vga_mode(unsigned long *p_vga_mode) +#endif +{ + if (!p_vga_mode) + return ERR_INVALID_PARAMETER; + + *p_vga_mode = d.vga_mode; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_get_available_tv_vga_modes(unsigned long *p_vga_modes) +#else +int +gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes) +#endif +{ + if (!p_vga_modes) + return ERR_INVALID_PARAMETER; + + *p_vga_modes = + GFX_VGA_MODE_640X480 | + GFX_VGA_MODE_720X487 | GFX_VGA_MODE_720X576 | GFX_VGA_MODE_800X600; + if (houston_Rev() >= HOUSTON_REV_B) + *p_vga_modes |= GFX_VGA_MODE_1024X768; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_tv_vga_mode(unsigned long vga_mode) +#else +int +gfx_set_tv_vga_mode(unsigned long vga_mode) +#endif +{ + /*reject if not a single valid VGA mode */ + switch (vga_mode) { + default: + return ERR_INVALID_PARAMETER; + + case GFX_VGA_MODE_640X480: + case GFX_VGA_MODE_720X487: + case GFX_VGA_MODE_720X576: + case GFX_VGA_MODE_800X600: + break; + + case GFX_VGA_MODE_1024X768: + if (houston_Rev() >= HOUSTON_REV_B) + break; + return ERR_INVALID_PARAMETER; + } + + /*if the mode has changed... */ + if (vga_mode != d.vga_mode) { + d.vga_mode = vga_mode; + + return write_config(REQ_VGA_MODE); + } + + return 0; +} + +/*==========================================================================*/ +/****/ +/*// tvout mode*/ + +#if GFX_TV_DYNAMIC +int +fs450_get_tvout_mode(unsigned long *p_tvout_mode) +#else +int +gfx_get_tvout_mode(unsigned long *p_tvout_mode) +#endif +{ + if (!p_tvout_mode) + return ERR_INVALID_PARAMETER; + + *p_tvout_mode = d.tvout_mode; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_tvout_mode(unsigned long tvout_mode) +#else +int +gfx_set_tvout_mode(unsigned long tvout_mode) +#endif +{ + d.tvout_mode = tvout_mode; + + return write_config(REQ_TVOUT_MODE); +} + +/*==========================================================================*/ +/****/ +/*// Sharpness*/ + +#if GFX_TV_DYNAMIC +int +fs450_get_sharpness(int *p_sharpness) +#else +int +gfx_get_sharpness(int *p_sharpness) +#endif +{ + if (!p_sharpness) + return ERR_INVALID_PARAMETER; + + *p_sharpness = d.sharpness; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_sharpness(int sharpness) +#else +int +gfx_set_sharpness(int sharpness) +#endif +{ + d.sharpness = range_limit(sharpness, 0, 1000); + + return write_config(REQ_SHARPNESS); +} + +/*==========================================================================*/ +/****/ +/*flicker filter control.*/ + +#if GFX_TV_DYNAMIC +int +fs450_get_flicker_filter(int *p_flicker) +#else +int +gfx_get_flicker_filter(int *p_flicker) +#endif +{ + if (!p_flicker) + return ERR_INVALID_PARAMETER; + + *p_flicker = d.flicker; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_flicker_filter(int flicker) +#else +int +gfx_set_flicker_filter(int flicker) +#endif +{ + d.flicker = range_limit(flicker, 0, 1000); + + return write_config(REQ_FLICKER); +} + +/*==========================================================================*/ +/****/ +/*// Overscan and Position*/ + +#if GFX_TV_DYNAMIC +int +fs450_get_overscan(int *p_x, int *p_y) +#else +int +gfx_get_overscan(int *p_x, int *p_y) +#endif +{ + if (!p_x || !p_y) + return ERR_INVALID_PARAMETER; + + *p_x = d.overscan_x; + *p_y = d.overscan_y; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_overscan(int x, int y) +#else +int +gfx_set_overscan(int x, int y) +#endif +{ + d.overscan_x = range_limit(x, -1000, 1000); + d.overscan_y = range_limit(y, -1000, 1000); + + return write_config(REQ_OVERSCAN_POSITION); +} + +#if GFX_TV_DYNAMIC +int +fs450_get_position(int *p_x, int *p_y) +#else +int +gfx_get_position(int *p_x, int *p_y) +#endif +{ + if (!p_x || !p_y) + return ERR_INVALID_PARAMETER; + + *p_x = d.position_x; + *p_y = d.position_y; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_position(int x, int y) +#else +int +gfx_set_position(int x, int y) +#endif +{ + d.position_x = range_limit(x, -1000, 1000); + d.position_y = range_limit(y, -1000, 1000); + + return write_config(REQ_OVERSCAN_POSITION); +} + +/*==========================================================================*/ +/****/ +/*// Color, Brightness, and Contrast*/ + +#if GFX_TV_DYNAMIC +int +fs450_get_color(int *p_color) +#else +int +gfx_get_color(int *p_color) +#endif +{ + if (!p_color) + return ERR_INVALID_PARAMETER; + + *p_color = d.color; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_color(int color) +#else +int +gfx_set_color(int color) +#endif +{ + d.color = range_limit(color, 0, 100); + + return write_config(REQ_COLOR); +} + +#if GFX_TV_DYNAMIC +int +fs450_get_brightness(int *p_brightness) +#else +int +gfx_get_brightness(int *p_brightness) +#endif +{ + if (!p_brightness) + return ERR_INVALID_PARAMETER; + + *p_brightness = d.brightness; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_brightness(int brightness) +#else +int +gfx_set_brightness(int brightness) +#endif +{ + d.brightness = range_limit(brightness, 0, 100); + + return write_config(REQ_BRIGHTNESS_CONTRAST); +} + +#if GFX_TV_DYNAMIC +int +fs450_get_contrast(int *p_contrast) +#else +int +gfx_get_contrast(int *p_contrast) +#endif +{ + if (!p_contrast) + return ERR_INVALID_PARAMETER; + + *p_contrast = d.contrast; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_contrast(int constrast) +#else +int +gfx_set_contrast(int constrast) +#endif +{ + d.contrast = range_limit(constrast, 0, 100); + + return write_config(REQ_BRIGHTNESS_CONTRAST); +} + +/*==========================================================================*/ +/****/ +/*// YC filters*/ + +#if GFX_TV_DYNAMIC +int +fs450_get_yc_filter(unsigned int *p_yc_filter) +#else +int +gfx_get_yc_filter(unsigned int *p_yc_filter) +#endif +{ + if (!p_yc_filter) + return ERR_INVALID_PARAMETER; + + if (houston_Rev() < HOUSTON_REV_B) + return ERR_NOT_SUPPORTED; + + *p_yc_filter = d.yc_filter; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_yc_filter(unsigned int yc_filter) +#else +int +gfx_set_yc_filter(unsigned int yc_filter) +#endif +{ + if (houston_Rev() < HOUSTON_REV_B) + return ERR_NOT_SUPPORTED; + + /*luma filter. */ + if (yc_filter & GFX_LUMA_FILTER) + d.yc_filter |= GFX_LUMA_FILTER; + else + d.yc_filter &= ~GFX_LUMA_FILTER; + + /*chroma filter. */ + if (yc_filter & GFX_CHROMA_FILTER) + d.yc_filter |= GFX_CHROMA_FILTER; + else + d.yc_filter &= ~GFX_CHROMA_FILTER; + + return write_config(REQ_YC_FILTER); +} + +#if GFX_TV_DYNAMIC +int +fs450_get_aps_trigger_bits(unsigned int *p_trigger_bits) +#else +int +gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits) +#endif +{ + if (!p_trigger_bits) + return ERR_INVALID_PARAMETER; + + *p_trigger_bits = d.aps_trigger_bits; + + return 0; +} + +#if GFX_TV_DYNAMIC +int +fs450_set_aps_trigger_bits(unsigned int trigger_bits) +#else +int +gfx_set_aps_trigger_bits(unsigned int trigger_bits) +#endif +{ + d.aps_trigger_bits = trigger_bits; + + return write_config(REQ_MACROVISION); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_format + * + * This routine sets the TV encoder registers to the specified format + * and resolution. + * Currently only NTSC 640x480 is supported. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs450_set_tv_format(TVStandardType format, GfxOnTVType resolution) +#else +int +gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_output + * + * This routine sets the TV encoder registers to the specified output type. + * Supported output types are : S-VIDEO and Composite. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs450_set_tv_output(int output) +#else +int +gfx_set_tv_output(int output) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_enable + * + * This routine enables or disables the use of the hardware CC registers + * in the TV encoder. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs450_set_tv_cc_enable(int enable) +#else +int +gfx_set_tv_cc_enable(int enable) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_data + * + * This routine writes the two specified characters to the CC data register + * of the TV encoder. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs450_set_tv_cc_data(unsigned char data1, unsigned char data2) +#else +int +gfx_set_tv_cc_data(unsigned char data1, unsigned char data2) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +#ifdef FS450_DIRECTREG + +/*//==========================================================================*/ +/****/ +/*// Direct Read and Write registers*/ + +int +FS450_ReadRegister(S_REG_INFO * p_reg) +{ + unsigned long tmp; + + if (PLAL_ReadRegister(p_reg)) + return 0; + + if (SOURCE_HOUSTON == p_reg->source) { + switch (p_reg->size) { + case 1: + case 2: + { + houston_ReadReg((int)p_reg->offset, &tmp, (int)p_reg->size); + p_reg->value = tmp; + } + return 0; + + case 4: + { + houston_ReadReg((unsigned int)p_reg->offset, &tmp, 2); + p_reg->value = (tmp << 16); + houston_ReadReg((unsigned int)(p_reg->offset + 2), &tmp, 2); + p_reg->value |= tmp; + } + return 0; + } + } + + return ERR_INVALID_PARAMETER; +} + +int +FS450_WriteRegister(S_REG_INFO * p_reg) +{ + if (PLAL_WriteRegister(p_reg)) + return 0; + + if (SOURCE_HOUSTON == p_reg->source) { + houston_WriteReg((unsigned int)p_reg->offset, p_reg->value, + p_reg->size); + + return 0; + } + + return ERR_INVALID_PARAMETER; +} + +#endif + +/****/ +/*Houston initialization function.*/ +/****/ +static int g_houston_rev = -1; + +static int +houston_init(void) +{ + /*//int errc; */ + unsigned long write, read; + + TRACE(("houston_init()\n")) + + /*initialize I2C */ + /*errc = I2C_init(); + * if (errc) + * return errc; + */ + /*Before we begin, we must enable power to the TFT */ + read = READ_VID32(CS5530_DISPLAY_CONFIG); + read |= CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN; + WRITE_VID32(CS5530_DISPLAY_CONFIG, read); + + /*simple w/r test. */ + write = 0x0055; + read = 0; + + houston_WriteReg(HOUSTON_IHO, write, 2); + houston_ReadReg(HOUSTON_IHO, &read, 2); + if (read != write) { + houston_WriteReg(HOUSTON_IHO, write, 2); + houston_ReadReg(HOUSTON_IHO, &read, 2); + if (read != write) { + /*chip is not there, do something appropriate? */ + TRACE(("wrote HOUSTON_IHO=0x0055, read 0x%04x\n", read)) + return ERR_DEVICE_NOT_FOUND; + } + } + + /*read chip revision. */ + houston_ReadReg(HOUSTON_REV, &read, 2); + g_houston_rev = (int)read; + + /*ok. */ + return 0; +} + +static int +houston_Rev(void) +{ + return g_houston_rev; +} + +static S_TIMING_SPECS g_specs; + +static const S_TIMING_SPECS * +p_specs(void) +{ + return &g_specs; +} + +/*//==========================================================================*/ +/****/ +/*FS450 configuration functions.*/ +/****/ +/*//==========================================================================*/ +static int +config_init(void) +{ + int err; + + TRACE(("config_init()\n")) + + err = houston_init(); + if (err) + return err; + + return 0; +} + +/*==========================================================================*/ +/****/ +/*convert word to encoder 10 bit value.*/ + +static unsigned short +w10bit2z(unsigned short w) +{ + return (w >> 2) | ((w & 0x03) << 8); +} + +static unsigned short +z2w10bit(unsigned short z) +{ + return (0x03 & (z >> 8)) | ((0xFF & z) << 2); +} + +/*==========================================================================*/ +/****/ +/*// TV Standards*/ + +static const struct +{ + unsigned long standard; + int tvsetup_index; +} +g_tv_standards[] = +{ + { + GFX_TV_STANDARD_NTSC_M, 0} + , { + GFX_TV_STANDARD_NTSC_M_J, 2} + , { + GFX_TV_STANDARD_PAL_B, 1} + , { + GFX_TV_STANDARD_PAL_D, 1} + , { + GFX_TV_STANDARD_PAL_H, 1} + , { + GFX_TV_STANDARD_PAL_I, 1} + , { + GFX_TV_STANDARD_PAL_M, 3} + , { + GFX_TV_STANDARD_PAL_N, 4} + , { + GFX_TV_STANDARD_PAL_G, 1} +,}; + +static int +map_tvstd_to_index(unsigned long tv_std) +{ + unsigned int i; + + for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) { + if (tv_std == g_tv_standards[i].standard) + return g_tv_standards[i].tvsetup_index; + } + + return -1; +} + +static unsigned long +supported_standards(void) +{ + unsigned long standards = 0; + unsigned int i; + + for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) { + if (g_tv_standards[i].tvsetup_index >= 0) + standards |= g_tv_standards[i].standard; + } + + return standards; +} + +/*==========================================================================*/ + +static void +config_power(int on) +{ + unsigned long reg; + + if (houston_Rev() < HOUSTON_REV_B) { + /*no power down supported, but still turn of clock in off mode */ + if (on) { + houston_ReadReg(HOUSTON_CR, ®, 2); + reg &= ~(CR_CLKOFF | CR_RESET); + houston_WriteReg(HOUSTON_CR, reg, 2); + reg |= CR_RESET; + houston_WriteReg(HOUSTON_CR, reg, 2); + reg &= ~CR_RESET; + houston_WriteReg(HOUSTON_CR, reg, 2); + } else { + houston_ReadReg(HOUSTON_CR, ®, 2); + reg |= CR_CLKOFF; + houston_WriteReg(HOUSTON_CR, reg, 2); + } + + return; + } + + if (on) { + /*!CLKOFF, !COMPOFF, !YCOFF */ + /*and reset Houston */ + houston_ReadReg(HOUSTON_CR, ®, 2); + reg &= ~(CR_CLKOFF | CR_RESET | CR_COMPOFF | CR_YCOFF); + houston_WriteReg(HOUSTON_CR, reg, 2); + reg |= CR_RESET; + houston_WriteReg(HOUSTON_CR, reg, 2); + reg &= ~CR_RESET; + houston_WriteReg(HOUSTON_CR, reg, 2); + + /*!GTLIO_PD */ + houston_ReadReg(HOUSTON_MISC, ®, 2); + reg &= ~MISC_GTLIO_PD; + houston_WriteReg(HOUSTON_MISC, reg, 2); + } else { + /*CLKOFF, COMPOFF, YCOFF */ + houston_ReadReg(HOUSTON_CR, ®, 2); + reg |= (CR_CLKOFF | CR_COMPOFF | CR_YCOFF); + houston_WriteReg(HOUSTON_CR, reg, 2); + + /*GTLIO_PD */ + houston_ReadReg(HOUSTON_MISC, ®, 2); + reg |= MISC_GTLIO_PD; + houston_WriteReg(HOUSTON_MISC, reg, 2); + } +} + +/*==========================================================================*/ +/****/ +/*// VGA mode*/ + +static void +config_vga_mode(unsigned long vga_mode) +{ + /*h_total must be evenly divisible by 32? */ + + static struct + { + unsigned long mode; + int width; + int lines; + int h_total; + } + vgaparams[] = + { + { + GFX_VGA_MODE_640X480, 640, 480, 1056} + , { + GFX_VGA_MODE_720X487, 720, 487, 1056} + , { + GFX_VGA_MODE_720X576, 720, 576, 1056} + , { + GFX_VGA_MODE_800X600, 800, 600, 1056} + , { + GFX_VGA_MODE_1024X768, 1024, 768, 1344} + ,}; + + unsigned long cr, misc, byp; + unsigned int i; + + g_specs.vga_width = 0; + g_specs.vga_lines = 0; + g_specs.h_total = 0; + + for (i = 0; i < sizeof(vgaparams) / sizeof(*vgaparams); i++) { + if (vga_mode == vgaparams[i].mode) { + g_specs.vga_width = vgaparams[i].width; + g_specs.vga_lines = vgaparams[i].lines; + g_specs.h_total = vgaparams[i].h_total; + break; + } + } + if (!g_specs.h_total) + return; + + /*clock mux decimator and vga dual. */ + houston_ReadReg(HOUSTON_CR, &cr, 2); + houston_ReadReg(HOUSTON_MISC, &misc, 2); + houston_ReadReg(HOUSTON_BYP, &byp, 2); + + if (vga_mode == GFX_VGA_MODE_1024X768) { + /*XGA*/ cr |= CR_UIM_DEC; + misc |= MISC_VGACKDIV; + byp |= (BYP_HDS_BYPASS | BYP_CAC_BYPASS); + } else { + /*VGA,SVGA */ + cr &= ~CR_UIM_DEC; + misc &= ~MISC_VGACKDIV; + byp &= ~(BYP_HDS_BYPASS | BYP_CAC_BYPASS); + } + + houston_WriteReg(HOUSTON_CR, cr, 2); + houston_WriteReg(HOUSTON_MISC, misc, 2); + houston_WriteReg(HOUSTON_BYP, byp, 2); +} + +/*==========================================================================*/ +/****/ +/*// Write settings for TV standard to device*/ + +static void +config_tv_std(unsigned long tv_std, unsigned int trigger_bits) +{ + int k; + unsigned short reg34; + unsigned long cr, w; + unsigned long l; + + /*verify supported standard. */ + k = map_tvstd_to_index(tv_std); + if (k < 0) + return; + + /*store tv width and lines */ + g_specs.tv_width = tvsetup.tv_width[k]; + g_specs.tv_lines = tvsetup.tv_lines[k]; + + /*houston CR register. */ + houston_ReadReg(HOUSTON_CR, &cr, 2); + cr &= ~CR_656_PAL_NTSC; + cr |= tvsetup.houston_cr[k]; + houston_WriteReg(HOUSTON_CR, cr, 2); + + /*setup the encoder. */ + l = tvsetup.chroma_freq[k]; + houston_WriteReg(ENC_CHROMA_FREQ, (int)(l & 0x00ff), 1); + houston_WriteReg(ENC_CHROMA_FREQ + 1, (int)((l >> 8) & 0x00ff), 1); + houston_WriteReg(ENC_CHROMA_FREQ + 2, (int)((l >> 16) & 0x00ff), 1); + houston_WriteReg(ENC_CHROMA_FREQ + 3, (int)((l >> 24) & 0x00ff), 1); + + houston_WriteReg(ENC_CHROMA_PHASE, tvsetup.chroma_phase[k], 1); + houston_WriteReg(ENC_REG05, 0x00, 1); /*reg 0x05 */ + houston_WriteReg(ENC_REG06, 0x89, 1); /*reg 0x06 */ + houston_WriteReg(ENC_REG07, 0x00, 1); /*reg 0x07 */ + houston_WriteReg(ENC_HSYNC_WIDTH, tvsetup.hsync_width[k], 1); + houston_WriteReg(ENC_BURST_WIDTH, tvsetup.burst_width[k], 1); + houston_WriteReg(ENC_BACK_PORCH, tvsetup.back_porch[k], 1); + houston_WriteReg(ENC_CB_BURST_LEVEL, tvsetup.cb_burst_level[k], 1); + houston_WriteReg(ENC_CR_BURST_LEVEL, tvsetup.cr_burst_level[k], 1); + houston_WriteReg(ENC_SLAVE_MODE, 0x01, 1); /*slave mode */ + if (trigger_bits == 0) + w = w10bit2z(tvsetup.blank_level[k]); /*blank level */ + else + w = w10bit2z((unsigned short)(tvsetup.blank_level[k] - + tvsetup.hamp_offset[k])); + houston_WriteReg(ENC_BLANK_LEVEL, w & 0x00ff, 1); + houston_WriteReg(ENC_BLANK_LEVEL + 1, w >> 8, 1); + w = w10bit2z(tvsetup.tv_lines[k]); /*num_lines */ + houston_WriteReg(ENC_NUM_LINES, w & 0x00ff, 1); + houston_WriteReg(ENC_NUM_LINES + 1, w >> 8, 1); + + houston_WriteReg(ENC_TINT, 0x00, 1); /*tint */ + houston_WriteReg(ENC_BREEZE_WAY, tvsetup.breeze_way[k], 1); + houston_WriteReg(ENC_FRONT_PORCH, tvsetup.front_porch[k], 1); + houston_WriteReg(ENC_ACTIVELINE, tvsetup.activeline[k], 1); + houston_WriteReg(ENC_FIRST_LINE, 0x15, 1); /*firstvideoline */ + reg34 = + 0x80 | + (tvsetup.pal_mode[k] << 6) | + (tvsetup.sys625_50[k] << 3) | + (tvsetup.cphase_rst[k] << 1) | (tvsetup.vsync5[k]); + houston_WriteReg(ENC_REG34, reg34, 1); /*reg 0x34 */ + houston_WriteReg(ENC_SYNC_LEVEL, tvsetup.sync_level[k], 1); + if (trigger_bits == 0) + w = w10bit2z(tvsetup.vbi_blank_level[k]); /*blank level */ + else + w = w10bit2z((unsigned short)(tvsetup.vbi_blank_level[k] - 1)); + houston_WriteReg(ENC_VBI_BLANK_LEVEL, w & 0x00ff, 1); + houston_WriteReg(ENC_VBI_BLANK_LEVEL + 1, w >> 8, 1); +} + +static void +conget_tv_std(unsigned long *p_tv_standard) +{ + unsigned long cr; + + if (!p_tv_standard) + return; + + /*just pick between NTSC and PAL */ + houston_ReadReg(HOUSTON_CR, &cr, 2); + if (CR_656_PAL_NTSC & cr) + *p_tv_standard = GFX_TV_STANDARD_PAL_B; + else + *p_tv_standard = GFX_TV_STANDARD_NTSC_M; +} + +/*==========================================================================*/ +/****/ +/*// TVout mode*/ + +static void +config_tvout_mode(unsigned long tvout_mode) +{ + unsigned long cr; + + houston_ReadReg(HOUSTON_CR, &cr, 2); + + /*all dacs off */ + cr |= (CR_COMPOFF | CR_YCOFF); + /*not rgb */ + cr &= ~CR_OFMT; + + /*turn on requested output */ + if (GFX_TVOUT_MODE_CVBS & tvout_mode) + cr &= ~CR_COMPOFF; + if (GFX_TVOUT_MODE_YC & tvout_mode) + cr &= ~CR_YCOFF; + if (GFX_TVOUT_MODE_RGB & tvout_mode) { + cr &= ~(CR_COMPOFF | CR_YCOFF); + cr |= CR_OFMT; + } + + houston_WriteReg(HOUSTON_CR, cr, 2); +} + +static void +conget_tvout_mode(unsigned long *p_tvout_mode) +{ + unsigned long cr; + + if (!p_tvout_mode) + return; + + houston_ReadReg(HOUSTON_CR, &cr, 2); + + if (CR_OFMT & cr) + *p_tvout_mode = GFX_TVOUT_MODE_RGB; + else { + *p_tvout_mode = 0; + if (!(CR_YCOFF & cr)) + *p_tvout_mode |= GFX_TVOUT_MODE_YC; + if (!(CR_COMPOFF & cr)) + *p_tvout_mode |= GFX_TVOUT_MODE_CVBS; + } +} + +/*==========================================================================*/ +/****/ +/*// Size & Position*/ + +#define IS_NTSC(tv_std) (tv_std & ( \ + GFX_TV_STANDARD_NTSC_M | \ + GFX_TV_STANDARD_NTSC_M_J | \ + GFX_TV_STANDARD_PAL_M)) +#define IS_PAL(tv_std) (tv_std & ( \ + GFX_TV_STANDARD_PAL_B | \ + GFX_TV_STANDARD_PAL_D | \ + GFX_TV_STANDARD_PAL_H | \ + GFX_TV_STANDARD_PAL_I | \ + GFX_TV_STANDARD_PAL_N | \ + GFX_TV_STANDARD_PAL_G)) + +/*return fifo delay setting for mode, std, and total lines.*/ + +static void +get_ffolat_ivo(unsigned long vga_mode, + unsigned long tv_std, + long i, unsigned short *ffolat, unsigned short *ivo) +{ + switch (vga_mode) { + case GFX_VGA_MODE_640X480: + if (IS_NTSC(tv_std)) { + if (i > SIZE6X4NTSC - 1) + i = SIZE6X4NTSC - 1; + *ffolat = ffo6x4ntsc[i].ffolat; + *ivo = 0x20; + } else { + if (i > SIZE6X4PAL - 1) + i = SIZE6X4PAL - 1; + *ffolat = ffo6x4pal[i].ffolat; + *ivo = 0x28; + } + break; + + case GFX_VGA_MODE_800X600: + if (IS_NTSC(tv_std)) { + if (i > SIZE8X6NTSC - 1) + i = SIZE8X6NTSC - 1; + *ffolat = ffo8x6ntsc[i].ffolat; + *ivo = 0x3a; + } else { + if (i > SIZE8X6PAL - 1) + i = SIZE8X6PAL - 1; + *ffolat = ffo8x6pal[i].ffolat; + *ivo = 0x39; + } + break; + + case GFX_VGA_MODE_720X487: + *ffolat = 0x40; /*//FFO7x4; */ + *ivo = 0x1a; + break; + + case GFX_VGA_MODE_720X576: + *ffolat = 0x40; /*//FFO7x5; */ + *ivo = 0x1a; + break; + + case GFX_VGA_MODE_1024X768: + default: + if (IS_NTSC(tv_std)) { + if (i > SIZE10X7NTSC - 1) + i = SIZE10X7NTSC - 1; + *ffolat = ffo10x7ntsc[i].ffolat; + *ivo = ffo10x7ntsc[i].ivo; + } else { + if (i > SIZE10X7PAL - 1) + i = SIZE10X7PAL - 1; + *ffolat = ffo10x7pal[i].ffolat; + *ivo = ffo10x7pal[i].ivo; + } + break; + } +} + +/*get vertical line min and max for mode and std.*/ + +static void +get_vtotal_min_max(unsigned long vga_mode, + unsigned long tv_std, + int *v_total_min, int *v_total_max, int *v_step) +{ + int k = map_tvstd_to_index(tv_std); + + switch (vga_mode) { + case GFX_VGA_MODE_640X480: + if (IS_NTSC(tv_std)) { + *v_total_min = ffo6x4ntsc[0].v_total; + *v_total_max = ffo6x4ntsc[SIZE6X4NTSC - 1].v_total; + } else { + *v_total_min = ffo6x4pal[0].v_total; + *v_total_max = ffo6x4pal[SIZE6X4PAL - 1].v_total; + } + *v_step = 4; + break; + + case GFX_VGA_MODE_800X600: + if (IS_NTSC(tv_std)) { + *v_total_min = ffo8x6ntsc[0].v_total; + *v_total_max = ffo8x6ntsc[SIZE8X6NTSC - 1].v_total; + } else { + *v_total_min = ffo8x6pal[0].v_total; + *v_total_max = ffo8x6pal[SIZE8X6PAL - 1].v_total; + } + *v_step = 5; + break; + + case GFX_VGA_MODE_720X487: + case GFX_VGA_MODE_720X576: + *v_total_min = tvsetup.tv_lines[k]; + *v_total_max = tvsetup.tv_lines[k]; + *v_step = 4; + break; + + case GFX_VGA_MODE_1024X768: + if (IS_NTSC(tv_std)) { + *v_total_min = ffo10x7ntsc[0].v_total; + *v_total_max = ffo10x7ntsc[SIZE10X7NTSC - 1].v_total; + } else { + *v_total_min = ffo10x7pal[0].v_total; + *v_total_max = ffo10x7pal[SIZE10X7PAL - 1].v_total; + } + *v_step = 6; + break; + } +} + +static void +config_overscan_xy(unsigned long tv_std, + unsigned long vga_mode, + int overscan_x, int overscan_y, int pos_x, int pos_y) +{ + unsigned int vga_index; + unsigned long reg; + double vsc; + int k; + unsigned short ffolat, ivo; + int base_v_total, range, v_offset; + int v_total_min, v_total_max, v_step; + float r, f; + int vga_pixels, pre_pixels; + float hscale, hscale_min, hscale_max; + int hsc; + int iho, iho_max, ihw; + + /*tv_std is valid. */ + k = map_tvstd_to_index(tv_std); + + /*store tv width and lines */ + g_specs.tv_width = tvsetup.tv_width[k]; + g_specs.tv_lines = tvsetup.tv_lines[k]; + + /*determine vga mode index */ + for (vga_index = 0; vga_index < SCANTABLE_ENTRIES; vga_index++) { + if (scantable[vga_index].mode == vga_mode) + break; + } + if (vga_index >= SCANTABLE_ENTRIES) + return; + + /****/ + /*vertical scaling (v_total setup). */ + /****/ + /*calculate vertical range. */ + get_vtotal_min_max(vga_mode, tv_std, &v_total_min, &v_total_max, &v_step); + TRACE(("v_total min=%d, max=%d\n", v_total_min, v_total_max)) + base_v_total = scantable[vga_index].v_total[k]; + range = fsmax(base_v_total - v_total_min, v_total_max - base_v_total); + TRACE(("v_total range = %d\n", range)) + + /*map +/-1000 overscan y into +/-range. */ + v_offset = (int)((((float)overscan_y * range) / 1000.f) + .5f); + TRACE(("v_offset = %d\n", v_offset)) + + /*range limit v_total. */ + g_specs.v_total = + range_limit(base_v_total + v_offset, v_total_min, v_total_max); + + /*round to calibrated value. */ + v_offset = (g_specs.v_total - v_total_min + (v_step / 2)) / v_step; + g_specs.v_total = v_total_min + v_offset * v_step; + TRACE(("desired v_total=%d\n", g_specs.v_total)) + + /****/ + /*vertical positioning (vsync setup). */ + /****/ + get_ffolat_ivo(vga_mode, tv_std, v_offset, &ffolat, &ivo); + houston_WriteReg(HOUSTON_IVO, ivo, 2); + + /*scale base sync offset by scaling ratio. */ + r = (float)g_specs.v_total / (float)base_v_total; + v_offset = (int)(r * (float)scantable[vga_index].v_sync[k]); + + /*scale ivo. */ + f = (float)ivo; + v_offset -= (int)(f - f / r); + + /*compensate for center screen. */ + f = (float)tvsetup.tv_active_lines[k] / 2.f; + v_offset += (int)(f * r - f); + + /*calculate vsync. */ + g_specs.v_sync = g_specs.v_total - v_offset + pos_y; + TRACE(("desired v_total=%d, desired v_sync=%d\n", g_specs.v_total, + g_specs.v_sync)) + if (g_specs.v_sync < g_specs.vga_lines + 10) { + TRACE(("vsync too low\n")) + /*//d.v_total += d.vga_lines+10-d.v_sync; */ + g_specs.v_sync = g_specs.vga_lines + 10; + } else if (g_specs.v_sync > g_specs.v_total - 10) { + TRACE(("vsync too high\n")) + g_specs.v_sync = g_specs.v_total - 10; + } + TRACE(("v_total=%d v_sync=%d\n", g_specs.v_total, g_specs.v_sync)) + + /*FFOLAT. */ + houston_WriteReg(HOUSTON_FFO_LAT, ffolat, 2); + + /*VSC. */ + vsc = (65536.0f * + (1.0f - (double)g_specs.tv_lines / (double)g_specs.v_total)) + 0.5f; + reg = ((unsigned long)-vsc) & 0xffff; + TRACE(("vsc=%04x, tv_lines=%d, v_total=%d\n", reg, g_specs.tv_lines, + g_specs.v_total)) + houston_WriteReg(HOUSTON_VSC, (int)reg, 2); + + /****/ + /*horizontal scaling. */ + /****/ + + /*vga pixels is vga width, except in 1024x768, where it's half that. */ + vga_pixels = g_specs.vga_width; + if (1024 == vga_pixels) + vga_pixels /= 2; + + /*maximum scaling coefficient is tv_width / vga_pixels */ + /*minimum is about 1/2, but that is quite small. arbitrarily set minimum at 75% maximum. */ + hscale_max = (720.0f / vga_pixels); + hscale_min = fsmax((0.75f * hscale_max), (1.0f - (63.0f / 128.0f))); + TRACE(("hscale_min = %u.%u, hscale_max = %u.%u\n", + (int)hscale_min, + (int)((hscale_min - (int)hscale_min) * 1000), + (int)hscale_max, (int)((hscale_max - (int)hscale_max) * 1000))) + + /*map overscan_x into min to max. */ + hscale = + hscale_min + ((overscan_x + 1000.0f) / 2000.0f) * (hscale_max - + hscale_min); + TRACE(("hscale = %u.%u\n", (int)hscale, + (int)((hscale - (int)hscale) * 1000))) + + /*determine hsc where hscale = (1 + hsc/128) */ + if (hscale >= 1.0f) + hsc = (int)(128.f * (hscale - 1.0f) + .5f); + else + hsc = (int)(128.f * (hscale - 1.0f) - .5f); + TRACE(("hsc = %d\n", hsc)) + if (hsc >= 0) + houston_WriteReg(HOUSTON_HSC, hsc << 8, 2); + else + houston_WriteReg(HOUSTON_HSC, hsc & 0xFF, 2); + + /*recalculate hscale for future formulas */ + hscale = 1.0f + (hsc / 128.0f); + TRACE(("recalculated hscale = %u.%u\n", (int)hscale, + (int)((hscale - (int)hscale) * 1000))) + + /****/ + /*horizontal offset. */ + /****/ + /*place hsync 40 before halfway from vga_width to htotal */ + /*but not less than vga_width + 10 */ + g_specs.h_sync = + fsmax((g_specs.h_total + g_specs.vga_width) / 2 - 40, + g_specs.vga_width + 10); + /*also, make it even */ + g_specs.h_sync &= ~1; + TRACE(("hsync = %u\n", g_specs.h_sync)) + + /*iho range is 0 to iho_max. */ + /*iho_max is 2 * iho_center. */ + /*iho_center is pre_pixels - (tvwidth / hscale - vga pixels) / 2. */ + /*pre_pixels = (htotal - hsync) * (vga_pixels / vga_width) */ + /*note that the range is inverted also, because it specifies the number of pixels */ + /*to skip, or subtract. iho=0 maps to farthest right. */ + /*map -pos_x = +/-1000 into (0 to iho_max) */ + pre_pixels = + (int)((long)(g_specs.h_total - g_specs.h_sync) * vga_pixels / + g_specs.vga_width); + iho_max = (2 * pre_pixels) - ((int)(720.0f / hscale + 0.5f) - vga_pixels); + TRACE(("iho_max = %u\n", iho_max)) + iho = + (int)range_limit(((long)(1000 - pos_x) * iho_max / 2000) + + scantable[vga_index].iho[k], 0, iho_max); + TRACE(("iho = %u\n", iho)) + houston_WriteReg(HOUSTON_IHO, iho, 2); + + /****/ + /*input horizontal width. */ + /****/ + + /*input horizontal width is vga pixels + pre_pixels - iho */ + /*additionally, ihw cannot exceed tv width / hscale */ + /*and if hsc is negative, (ihw)(-hsc/128) cannot exceed ~250. */ + /*and ihw should be even. */ + ihw = fsmin(vga_pixels + pre_pixels - iho, (int)(720.0f / hscale)); + if (hsc < 0) + ihw = (int)fsmin(ihw, 253L * 128 / (-hsc)); + ihw &= ~1; + TRACE(("ihw = %u\n", ihw)) + houston_WriteReg(HOUSTON_IHA, ihw, 2); + + f = (((float)g_specs.h_total * g_specs.v_total) * 27.f) / + ((float)g_specs.tv_width * g_specs.tv_lines); + + TRACE(("freq=%u.%uMHz\n", (int)f, (int)((f - (int)f) * 1000))) +} + +/*==========================================================================*/ +/****/ +/*configure houston nco.*/ + +static void +config_nco(unsigned long tv_std, unsigned long vga_mode) +{ + unsigned long cr, misc; + unsigned long reg; + int k = map_tvstd_to_index(tv_std); + + /*read and store CR. */ + houston_ReadReg(HOUSTON_CR, &cr, 2); + + /*make sure NCO_EN (enable latch) bit is clear */ + cr &= ~CR_NCO_EN; + houston_WriteReg(HOUSTON_CR, cr, 2); + + /*clear NCO_LOADX. */ + houston_ReadReg(HOUSTON_MISC, &misc, 2); + misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0); + houston_WriteReg(HOUSTON_MISC, misc, 2); + + if (vga_mode == GFX_VGA_MODE_1024X768) { + /*setup for M and N load (Nco_load=1). */ + misc |= (MISC_NCO_LOAD0); + houston_WriteReg(HOUSTON_MISC, misc, 2); + + /*M and N. */ + houston_WriteReg(HOUSTON_NCONL, 1024 - 2, 2); + houston_WriteReg(HOUSTON_NCODL, 128 - 1, 2); + + /*latch M/N in. */ + cr |= CR_NCO_EN; + houston_WriteReg(HOUSTON_CR, cr, 2); + cr &= ~CR_NCO_EN; + houston_WriteReg(HOUSTON_CR, cr, 2); + + /*setup ncon and ncod load (Nco_load=0). */ + misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0); + houston_WriteReg(HOUSTON_MISC, misc, 2); + + /*NCON. */ + reg = ((unsigned long)g_specs.v_total * g_specs.h_total) / 2; + houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2); + houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2); + + /*NCOD. */ + houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2); + houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2); + } else { + /*setup for M and N load (Nco_load=2). */ + misc |= (MISC_NCO_LOAD1); + houston_WriteReg(HOUSTON_MISC, misc, 2); + + /*NCON. */ + reg = (unsigned long)g_specs.v_total * g_specs.h_total; + houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2); + houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2); + + /*NCOD. */ + houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2); + houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2); + + TRACE(("NCON = %lu (0x%08lx), NCOD = %lu (0x%08lx)\n", + reg, + reg, + ((unsigned long)tvsetup.houston_ncodh[k] << 16) + + tvsetup.houston_ncodl[k], + ((unsigned long)tvsetup.houston_ncodh[k] << 16) + + tvsetup.houston_ncodl[k])) + } + + /*latch M/N and NCON/NCOD in. */ + cr |= CR_NCO_EN; + houston_WriteReg(HOUSTON_CR, cr, 2); + cr &= ~CR_NCO_EN; + houston_WriteReg(HOUSTON_CR, cr, 2); +} + +/*==========================================================================*/ +/****/ +/*// Write sharpness settings to device*/ + +static void +config_sharpness(int sharpness) +{ + unsigned int shp; + + /*map 0-1000 to 0-20. */ + shp = (unsigned int)(0.5f + ((float)sharpness * 20.0f / 1000.0f)); + shp = range_limit(shp, 0, 20); + + houston_WriteReg(HOUSTON_SHP, shp, 2); +} + +static void +conget_sharpness(int *p_sharpness) +{ + unsigned long shp; + + if (!p_sharpness) + return; + + houston_ReadReg(HOUSTON_SHP, &shp, 2); + + /*map 0-20 to 0-1000. */ + *p_sharpness = (int)(0.5f + ((float)shp * 1000.0f / 20.0f)); +} + +/*==========================================================================*/ +/****/ +/*// Write flicker settings to device*/ + +static void +config_flicker(int flicker) +{ + unsigned int flk; + + /*map 0-1000 to 0-16. */ + flk = (unsigned int)(0.5f + ((float)flicker * 16.0f / 1000.0f)); + flk = range_limit(flk, 0, 16); + + houston_WriteReg(HOUSTON_FLK, flk, 2); +} + +static void +conget_flicker(int *p_flicker) +{ + unsigned long flk; + + if (!p_flicker) + return; + + houston_ReadReg(HOUSTON_FLK, &flk, 2); + + /*map 0-16 to 0-1000. */ + *p_flicker = (int)(0.5f + ((float)flk * 1000.0f / 16.0f)); +} + +/*==========================================================================*/ +/****/ +/*// Write color settings to device*/ + +static void +config_color(int color) +{ + unsigned long clr; + + /*map 0-100 to 0-255. */ + /*montreal production test needs 169 to be mappable, so */ + /*use .8 rounding factor, 169=(int)(66.*2.55+.8). */ + clr = (unsigned long)(0.8f + ((float)color * 255.0f / 100.0f)); + clr = range_limit(clr, 0, 255); + + houston_WriteReg(ENC_CR_GAIN, clr, 1); + houston_WriteReg(ENC_CB_GAIN, clr, 1); +} + +static void +conget_color(int *p_color) +{ + unsigned long cr_gain; + + if (!p_color) + return; + + /*just get CR GAIN, CB GAIN should match. */ + houston_ReadReg(ENC_CR_GAIN, &cr_gain, 1); + + /*map 0-255 to 0-100. */ + *p_color = (int)(0.5f + ((float)cr_gain * 100.0f / 255.0f)); +} + +/*==========================================================================*/ +/****/ +/*// Write brightness and contrast settings to device*/ + +#define NTSC_BLANK_LEVEL 240 + +static const int min_black_level = NTSC_BLANK_LEVEL + 1; +static const int max_white_level = 1023; + +static void +config_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits, + int brightness, int contrast) +{ + int brightness_off; + float contrast_mult; + int black, white; + unsigned short w; + int k = map_tvstd_to_index(tv_std); + + /*0-100 maps to +/-220. */ + brightness_off = (int)(0.5f + ((float)brightness * 440.0f / 100.0f)) - 220; + + /*0-100 maps to .75-1.25. */ + contrast_mult = ((float)contrast * 0.5f / 100.0f) + 0.75f; + + black = tvsetup.black_level[k]; + if (trigger_bits != 0) + black -= tvsetup.hamp_offset[k]; + + white = tvsetup.white_level[k]; + if (trigger_bits != 0) + white -= tvsetup.hamp_offset[k]; + + black = (int)((float)(black + brightness_off) * contrast_mult); + white = (int)((float)(white + brightness_off) * contrast_mult); + if (black < min_black_level) + black = min_black_level; + if (white > max_white_level) + white = max_white_level; + + w = w10bit2z((unsigned short)black); + houston_WriteReg(ENC_BLACK_LEVEL, w & 0x00ff, 1); + houston_WriteReg(ENC_BLACK_LEVEL + 1, w >> 8, 1); + w = w10bit2z((unsigned short)white); + houston_WriteReg(ENC_WHITE_LEVEL, w & 0x00ff, 1); + houston_WriteReg(ENC_WHITE_LEVEL + 1, w >> 8, 1); +} + +static void +conget_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits, + int *p_brightness, int *p_contrast) +{ + int brightness_off; + float contrast_mult; + unsigned short black, white; + unsigned long zh, zl; + int k; + + if (!p_brightness || !p_contrast) + return; + + k = map_tvstd_to_index(tv_std); + + houston_ReadReg(ENC_BLACK_LEVEL, &zl, 1); + houston_ReadReg(ENC_BLACK_LEVEL + 1, &zh, 1); + black = z2w10bit((unsigned short)(zl + (zh << 8))); + if (trigger_bits != 0) + black += tvsetup.hamp_offset[k]; + houston_ReadReg(ENC_WHITE_LEVEL, &zl, 1); + houston_ReadReg(ENC_WHITE_LEVEL + 1, &zh, 1); + white = z2w10bit((unsigned short)(zl + (zh << 8))); + if (trigger_bits != 0) + white += tvsetup.hamp_offset[k]; + + /*this reverse computation does not account for clipping, but should */ + /*provide somewhat reasonable numbers */ + contrast_mult = + ((float)white - (float)black) / ((float)tvsetup.white_level[k] - + (float)tvsetup.black_level[k]); + brightness_off = + (int)(((float)black / contrast_mult) - tvsetup.black_level[k]); + + /*+/-220 maps to 0-100. */ + *p_brightness = + range_limit((int) + (0.5f + + ((float)(brightness_off + 220) * 100.0f / 440.0f)), 0, + 100); + + /*.75-1.25 maps to 0-100. */ + *p_contrast = + range_limit((int) + (0.5f + + ((float)(contrast_mult - 0.75f) * 100.0f / 0.5f)), 0, + 100); +} + +/*==========================================================================*/ +/****/ +/*configure luma/chroma filters.*/ + +static void +config_yc_filter(unsigned long tv_std, int luma_filter, int chroma_filter) +{ + unsigned long reg, reg07, reg34; + + if (houston_Rev() < HOUSTON_REV_B) + return; + + /*luma filter. */ + if (luma_filter) + reg = tvsetup.notch_filter[map_tvstd_to_index(tv_std)]; + else + reg = 0; + houston_WriteReg(ENC_NOTCH_FILTER, reg, 1); + + /*chroma filter. */ + houston_ReadReg(ENC_REG07, ®07, 1); + houston_ReadReg(ENC_REG34, ®34, 1); + if (chroma_filter) { + reg07 &= ~0x08; + reg34 &= ~0x20; + } else { + reg07 |= 0x08; + reg34 |= 0x20; + } + houston_WriteReg(ENC_REG07, reg07, 1); + houston_WriteReg(ENC_REG34, reg34, 1); +} + +static void +conget_yc_filter(int *p_luma_filter, int *p_chroma_filter) +{ + unsigned long reg, reg07, reg34; + + if (!p_luma_filter || !p_chroma_filter) + return; + + if (houston_Rev() < HOUSTON_REV_B) { + *p_luma_filter = 0; + *p_chroma_filter = 0; + return; + } + + /*luma filter. */ + houston_ReadReg(ENC_NOTCH_FILTER, ®, 1); + *p_luma_filter = (reg ? 1 : 0); + + /*chroma filter. */ + houston_ReadReg(ENC_REG07, ®07, 1); + houston_ReadReg(ENC_REG34, ®34, 1); + *p_chroma_filter = !((0x08 & reg07) || (0x20 & reg34)); +} + +/*==========================================================================*/ +/****/ +/*// Macrovision*/ + +static void +config_macrovision(unsigned long tv_std, unsigned int trigger_bits) +{ +/****/ +/*Constants to index into mvsetup columns.*/ +/****/ +#define nNTSC_APS00 0 /*ntsc mv off. */ +#define nNTSC_APS01 1 /*ntsc AGC only. */ +#define nNTSC_APS10 2 /*ntsc AGC + 2-line CS. */ +#define nNTSC_APS11 3 /*ntsc AGC + 4-line CS. */ +#define nPAL_APS00 4 /*pal mv off. */ +#define nPAL_APSXX 5 /*pal mv on. */ +#define nMVModes 6 + +/****/ +/*Macrovision setup table.*/ +/****/ + static const struct mvparms + { + unsigned short n0[nMVModes]; + unsigned short n1[nMVModes]; + unsigned short n2[nMVModes]; + unsigned short n3[nMVModes]; + unsigned short n4[nMVModes]; + unsigned short n5[nMVModes]; + unsigned short n6[nMVModes]; + unsigned short n7[nMVModes]; + unsigned short n8[nMVModes]; + unsigned short n9[nMVModes]; + unsigned short n10[nMVModes]; + unsigned short n11[nMVModes]; + unsigned short n12[nMVModes]; + unsigned short n13[nMVModes]; + unsigned short n14[nMVModes]; + unsigned short n15[nMVModes]; + unsigned short n16[nMVModes]; + unsigned short n17[nMVModes]; + unsigned short n18[nMVModes]; + unsigned short n19[nMVModes]; + unsigned short n20[nMVModes]; + unsigned short n21[nMVModes]; + unsigned short n22[nMVModes]; + unsigned short agc_pulse_level[nMVModes]; + unsigned short bp_pulse_level[nMVModes]; + } + + mvsetup = + { /*// ntsc ntsc ntsc ntsc pal pal */ + /*// MV AGC AGC + AGC + MV MV */ + /*// off. only 2-line 4-line off. on. */ + /*// CS. CS. */ + { + 0x00, 0x36, 0x3e, 0x3e, 0x00, 0x3e} + , /*n0 */ + { + 0x1d, 0x1d, 0x1d, 0x17, 0x1a, 0x1a} + , /*n1 */ + { + 0x11, 0x11, 0x11, 0x15, 0x22, 0x22} + , /*n2 */ + { + 0x25, 0x25, 0x25, 0x21, 0x2a, 0x2a} + , /*n3 */ + { + 0x11, 0x11, 0x11, 0x15, 0x22, 0x22} + , /*n4 */ + { + 0x01, 0x01, 0x01, 0x05, 0x05, 0x05} + , /*n5 */ + { + 0x07, 0x07, 0x07, 0x05, 0x02, 0x02} + , /*n6 */ + { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00} + , /*n7 */ + { + 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c} + , /*n8 */ + { + 0x1b, 0x1b, 0x1b, 0x1b, 0x3d, 0x3d} + , /*n9 */ + { + 0x24, 0x24, 0x24, 0x24, 0x14, 0x14} + , /*n10 */ + { + 0x780f, 0x780f, 0x780f, 0x780f, 0x7e07, 0x7e07} + , /*n11 */ + { + 0x0000, 0x0000, 0x0000, 0x0000, 0x5402, 0x5402} + , /*n12 */ + { + 0x0f, 0x0f, 0x0f, 0x0f, 0xfe, 0xfe} + , /*n13 */ + { + 0x0f, 0x0f, 0x0f, 0x0f, 0x7e, 0x7e} + , /*n14 */ + { + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60} + , /*n15 */ + { + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00} + , /*n16 */ + { + 0x0a, 0x0a, 0x0a, 0x0a, 0x08, 0x08} + , /*n17 */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + , /*n18 */ + { + 0x05, 0x05, 0x05, 0x05, 0x04, 0x04} + , /*n19 */ + { + 0x04, 0x04, 0x04, 0x04, 0x07, 0x07} + , /*n20 */ + { + 0x03ff, 0x03ff, 0x03ff, 0x03ff, 0x0155, 0x0155} + , /*n21 */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + , /*n22 */ + { + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3} + , /*agc_pulse_level */ + { + 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8} + , /*bp_pulse_level */ + }; + + int nMode; + unsigned long misc; + unsigned short n0; + + trigger_bits &= 0x3; + + /*Determine the OEM Macrovision Program Mode and Register 0 Data. */ + if (IS_NTSC(tv_std)) { + /*NTSC TV Standard. */ + if (trigger_bits == 0) { + /*turn Macrovision OFF. */ + nMode = nNTSC_APS00; + } else if (trigger_bits == 1) { + /*AGC Only. */ + nMode = nNTSC_APS01; + } else if (trigger_bits == 2) { + /*AGC + 2-line CS. */ + nMode = nNTSC_APS10; + } else { + /*AGC + 4-line CS. */ + nMode = nNTSC_APS11; + } + } else { + /*PAL TV Standard. */ + if (trigger_bits == 0) { + /*turn Macrovision OFF. */ + nMode = nPAL_APS00; + } else { + /*APS 01, 10, or 11. */ + nMode = nPAL_APSXX; + } + } + + /*Retrieve the Macrovision Program Mode Data */ + if (tv_std != GFX_TV_STANDARD_PAL_M) + n0 = mvsetup.n0[nMode]; + else { + /*PAL-M sets up like NTSC except for n0. */ + if ((trigger_bits & 0x03) == 0) + n0 = mvsetup.n0[nPAL_APS00]; + else + n0 = mvsetup.n0[nPAL_APSXX]; + } + + /*download settings now. */ + houston_WriteReg(MV_N0, n0, 1); + houston_WriteReg(MV_N1, mvsetup.n1[nMode], 1); + houston_WriteReg(MV_N2, mvsetup.n2[nMode], 1); + houston_WriteReg(MV_N3, mvsetup.n3[nMode], 1); + houston_WriteReg(MV_N4, mvsetup.n4[nMode], 1); + houston_WriteReg(MV_N5, mvsetup.n5[nMode], 1); + houston_WriteReg(MV_N6, mvsetup.n6[nMode], 1); + houston_WriteReg(MV_N7, mvsetup.n7[nMode], 1); + houston_WriteReg(MV_N8, mvsetup.n8[nMode], 1); + houston_WriteReg(MV_N9, mvsetup.n9[nMode], 1); + houston_WriteReg(MV_N10, mvsetup.n10[nMode], 1); + houston_WriteReg(MV_N11, mvsetup.n11[nMode] & 0xff, 1); + houston_WriteReg(MV_N11 + 1, mvsetup.n11[nMode] >> 8, 1); + houston_WriteReg(MV_N12, mvsetup.n12[nMode] & 0xff, 1); + houston_WriteReg(MV_N12 + 1, mvsetup.n12[nMode] >> 8, 1); + houston_WriteReg(MV_N13, mvsetup.n13[nMode], 1); + houston_WriteReg(MV_N14, mvsetup.n14[nMode], 1); + houston_WriteReg(MV_N15, mvsetup.n15[nMode], 1); + houston_WriteReg(MV_N16, mvsetup.n16[nMode], 1); + houston_WriteReg(MV_N17, mvsetup.n17[nMode], 1); + houston_WriteReg(MV_N18, mvsetup.n18[nMode], 1); + houston_WriteReg(MV_N19, mvsetup.n19[nMode], 1); + houston_WriteReg(MV_N20, mvsetup.n20[nMode], 1); + houston_WriteReg(MV_N21, mvsetup.n21[nMode] & 0xff, 1); + houston_WriteReg(MV_N21 + 1, mvsetup.n21[nMode] >> 8, 1); + houston_WriteReg(MV_N22, mvsetup.n22[nMode], 1); + houston_WriteReg(MV_AGC_PULSE_LEVEL, mvsetup.agc_pulse_level[nMode], 1); + houston_WriteReg(MV_BP_PULSE_LEVEL, mvsetup.bp_pulse_level[nMode], 1); + + houston_ReadReg(HOUSTON_MISC, &misc, 2); + if (trigger_bits == 0) + misc &= ~MISC_MV_SOFT_EN; + else + misc |= MISC_MV_SOFT_EN; + houston_WriteReg(HOUSTON_MISC, misc, 2); +} + +static void +conget_macrovision(unsigned long tv_std, unsigned int *p_cp_trigger_bits) +{ + unsigned long n0, n1; + + if (!p_cp_trigger_bits) + return; + + houston_ReadReg(MV_N0, &n0, 1); + houston_ReadReg(MV_N1, &n1, 1); + + *p_cp_trigger_bits = 0; + + if (IS_NTSC(tv_std)) { + switch (n0) { + case 0: + *p_cp_trigger_bits = 0; + break; + + case 0x36: + *p_cp_trigger_bits = 1; + break; + + case 0x3E: + { + if (0x1D == n1) + *p_cp_trigger_bits = 2; + else + *p_cp_trigger_bits = 3; + } + break; + } + } else if (IS_PAL(tv_std)) { + if (0 == n0) + *p_cp_trigger_bits = 0; + else { + /*don't know here what the non-zero trigger bits were */ + *p_cp_trigger_bits = 1; + } + } +} + +/*// PLAL_MediaGX.cpp*/ +/*//==========================================================================*/ +/****/ +/*These functions provides implementation of platform-specific functions*/ +/*MediaGX platform.*/ +/****/ +/*//==========================================================================*/ + +/*MediaGX control registers.*/ +#define CCR3 0xC3 +#define GCR 0xb8 + +/*Media GX registers*/ +/* +#define DC_UNLOCK 0x8300 +#define DC_GENERAL_CFG 0x8304 +#define DC_TIMING_CFG 0x8308 +#define DC_OUTPUT_CFG 0x830c +#define DC_H_TIMING_1 0X8330 +#define DC_H_TIMING_2 0X8334 +#define DC_H_TIMING_3 0X8338 +#define DC_FP_H_TIMING 0X833c +#define DC_V_TIMING_1 0X8340 +#define DC_V_TIMING_2 0X8344 +#define DC_V_TIMING_3 0X8348 +#define DC_FP_V_TIMING 0X834c +*/ +/*Media GX general config register.*/ +#define GX_DCLK_MUL 0x00c0 +#define GX_DCLKx1 0x0040 +#define GX_DCLKx2 0x0080 +#define GX_DCLKx4 0x00c0 + +/*Media GX timing config register.*/ +#define GX_TGEN 0x0020 + +/*Cx5530 register offsets (from GX_BASE).*/ +#define CX_DISPLAY_CONFIG 0x10004 +#define CX_DOT_CLK 0x10024 +#define CX_TV_CONFIG 0x10028 + +/*Cx5530 display configuration register.*/ +#define CX_FPVSYNC_POL 0x0800 +#define CX_FPHSYNC_POL 0x0400 +#define CX_FPDATA_ENB 0x0080 +#define CX_FPPOWER_ENB 0x0040 +#define CX_CRTVSYNC_POL 0x0200 +#define CX_CRTHSYNC_POL 0x0100 + +/*Cx5530 dot clock configuration register.*/ +#define CX_TVCLK_SELECT 0x0400 + +/*Cx5530 tv configuration register*/ +#define CX_INVERT_FPCLK (1 << 6) + +/*//==========================================================================*/ +/****/ +/*// FS450 I2C Address*/ +/****/ +/*// There are two possible 7-bit addresses, 0x4A and 0x6A.*/ +/*// The address if selectable via pins on the FS450.*/ +/*// There are also two possible 10-bit addresses, 0x224 and 0x276, but this*/ +/*// source is not designed to use them.*/ +/****/ + +#define FS450_I2C_ADDRESS (0x4A) + +static unsigned char +PLAL_FS450_i2c_address(void) +{ + return FS450_I2C_ADDRESS; +} + +/*//==========================================================================*/ +/****/ +/*// FS450 UIM mode*/ +/****/ +/*// This mode is programmed in the FS450 command register when enabling TV*/ +/*// out.*/ + +static int +PLAL_FS450_UIM_mode(void) +{ + return 3; +} + +/*//==========================================================================*/ +/****/ +/*// Read and Write MediaGX registers*/ + +static unsigned long +ReadGx(unsigned long inRegAddr) +{ + unsigned long data; + + DMAL_ReadUInt32(inRegAddr, &data); + + return data; +} + +static void +WriteGx(unsigned long inRegAddr, unsigned long inData) +{ + int is_timing_register; + unsigned long reg_timing_cfg; + + /*because the unlock register for the MediaGx video registers may not */ + /*persist, we will write the unlock code before every write. */ + DMAL_WriteUInt32(DC_UNLOCK, 0x4758); + + /*see if register is a timing register */ + is_timing_register = + (DC_H_TIMING_1 == inRegAddr) || + (DC_H_TIMING_2 == inRegAddr) || + (DC_H_TIMING_3 == inRegAddr) || + (DC_FP_H_TIMING == inRegAddr) || + (DC_V_TIMING_1 == inRegAddr) || + (DC_V_TIMING_2 == inRegAddr) || + (DC_V_TIMING_3 == inRegAddr) || (DC_FP_V_TIMING == inRegAddr); + + /*if the register is a timing register, clear the TGEN bit to allow modification */ + if (is_timing_register) { + DMAL_ReadUInt32(DC_TIMING_CFG, ®_timing_cfg); + DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg & ~GX_TGEN); + } + + /*write the requested register */ + DMAL_WriteUInt32(inRegAddr, inData); + + /*reset the TGEN bit to previous state */ + if (is_timing_register) { + DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg); + } +} + +#ifdef FS450_DIRECTREG + +/*//==========================================================================*/ +/****/ +/*// Platform-specific processing for a Read or Write Register calls.*/ +/*// The functions should return true if the specified register belongs to*/ +/*// this platform.*/ + +static int +PLAL_ReadRegister(S_REG_INFO * p_reg) +{ + if (!p_reg) + return 0; + + if (SOURCE_GCC == p_reg->source) { + p_reg->value = ReadGx(p_reg->offset); + + return 1; + } + + return 0; +} + +static int +PLAL_WriteRegister(const S_REG_INFO * p_reg) +{ + if (!p_reg) + return 0; + + if (SOURCE_GCC == p_reg->source) { + WriteGx(p_reg->offset, p_reg->value); + + return 1; + } + + return 0; +} + +#endif + +/*//==========================================================================*/ +/****/ +/*// Determine if TV is on*/ + +static int +PLAL_IsTVOn(void) +{ + unsigned long reg; + + /*check Cx5530 dot clock */ + reg = ReadGx(CX_DOT_CLK); + return (reg & CX_TVCLK_SELECT) ? 1 : 0; +} + +/*//==========================================================================*/ +/****/ +/*// Platform-specific actions to reset to VGA mode*/ + +static int +PLAL_EnableVga(void) +{ + unsigned long reg; + + /*2 x dclk */ + reg = ReadGx(DC_GENERAL_CFG); + reg &= ~GX_DCLK_MUL; + reg |= GX_DCLKx2; + WriteGx(DC_GENERAL_CFG, reg); + + /*select pll dot clock. */ + reg = ReadGx(CX_DOT_CLK); + reg &= ~CX_TVCLK_SELECT; + WriteGx(CX_DOT_CLK, reg); + + /*timing config, reset everything on dclk. */ + reg = ReadGx(DC_TIMING_CFG); + reg &= ~GX_TGEN; + WriteGx(DC_TIMING_CFG, reg); + reg |= GX_TGEN; + WriteGx(DC_TIMING_CFG, reg); + + /*un-invert FP clock */ + reg = ReadGx(CX_TV_CONFIG); + reg &= ~CX_INVERT_FPCLK; + WriteGx(CX_TV_CONFIG, reg); + + return 0; +} + +/*//==========================================================================*/ +/****/ +/*// Platform-specific actions to enter TVout mode*/ + +static int +PLAL_PrepForTVout(void) +{ + unsigned int reg; + + /*Cx5530 tv config. */ + reg = 0; + WriteGx(CX_TV_CONFIG, reg); + + /*invert FP clock */ + reg = (int)ReadGx(CX_TV_CONFIG); + reg |= CX_INVERT_FPCLK; + WriteGx(CX_TV_CONFIG, reg); + + return 0; +} + +static int +PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs) +{ + unsigned long reg; + + /*timing config, reset everything on dclk. */ + reg = ReadGx(DC_TIMING_CFG); + reg &= ~GX_TGEN; + WriteGx(DC_TIMING_CFG, reg); + + /*htotal and hactive. */ + reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1); + WriteGx(DC_H_TIMING_1, reg); + + /*hblank. */ + reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1); + WriteGx(DC_H_TIMING_2, reg); + + /*hsync. */ + reg = ((p_specs->h_sync + 63) << 16) | p_specs->h_sync; + WriteGx(DC_H_TIMING_3, reg); + + /*fp hsync. */ + WriteGx(DC_FP_H_TIMING, reg); + + /*vtotal and vactive. */ + reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1); + WriteGx(DC_V_TIMING_1, reg); + + /*vblank. */ + reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1); + WriteGx(DC_V_TIMING_2, reg); + + /*vsync. */ + reg = ((p_specs->v_sync) << 16) | (p_specs->v_sync - 1); + WriteGx(DC_V_TIMING_3, reg); + + /*fp vsync. */ + reg = ((p_specs->v_sync - 1) << 16) | (p_specs->v_sync - 2); + WriteGx(DC_FP_V_TIMING, reg); + + /*timing config, reenable all dclk stuff. */ + reg = ReadGx(DC_TIMING_CFG); + reg |= GX_TGEN; + WriteGx(DC_TIMING_CFG, reg); + + return 0; +} + +static int +PLAL_FinalEnableTVout(unsigned long vga_mode) +{ + unsigned int reg; + + /*Cx5530 select tv dot clock. */ + reg = (int)ReadGx(CX_DOT_CLK); + reg |= CX_TVCLK_SELECT; + WriteGx(CX_DOT_CLK, reg); + + /*2 x dclk (actually 1x) */ + reg = (int)ReadGx(DC_GENERAL_CFG); + reg &= ~GX_DCLK_MUL; + WriteGx(DC_GENERAL_CFG, reg); + + reg |= GX_DCLKx2; + WriteGx(DC_GENERAL_CFG, reg); + + /*Cx5530 display configuration register. */ + reg = (int)ReadGx(CX_DISPLAY_CONFIG); + reg |= (CX_FPVSYNC_POL | CX_FPHSYNC_POL | CX_FPDATA_ENB | CX_FPPOWER_ENB); + WriteGx(CX_DISPLAY_CONFIG, reg); + +/*disable, shouldn't be necessary*/ +#if 0 + /*kick MediaGX clock multiplier to clean up clock */ + reg = ReadGx(DC_GENERAL_CFG); + reg &= ~GX_DCLK_MUL; + WriteGx(DC_GENERAL_CFG, reg); + reg |= GX_DCLKx2; + WriteGx(DC_GENERAL_CFG, reg); +#endif + + return 0; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.h new file mode 100644 index 000000000..2b87710de --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.h @@ -0,0 +1,307 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs450.h,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: tv_fs450.h $ + * + * This file defines the common FS450 API. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef __FS450_H__ +#define __FS450_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* ==========================================================================*/ +/* Init and cleanup functions*/ + + int FS450_init(void); + void FS450_cleanup(void); + /* call FS450_init at startup to probe for and initialize FS450. */ + /* returns 0 if successful. */ + +/* ==========================================================================*/ +/* TV output on or off*/ + + int FS450_get_tv_enable(unsigned int *p_on); + int FS450_set_tv_enable(unsigned int on); + /* on is 1 for TV on, 0 for off */ + +/* ==========================================================================*/ +/* TV standard*/ + + int FS450_get_tv_standard(unsigned long *p_standard); + int FS450_get_available_tv_standards(unsigned long *p_standards); + int FS450_set_tv_standard(unsigned long standard); + /* standard is one of the FS450_TV_STANDARD constants */ + /* standards is a bitmask of zero or more FS450_TV_STANDARD constants */ + +/* FS450 TV Standard flags*/ +#define FS450_TV_STANDARD_NTSC_M 0x0001 +#define FS450_TV_STANDARD_NTSC_M_J 0x0002 +#define FS450_TV_STANDARD_PAL_B 0x0004 +#define FS450_TV_STANDARD_PAL_D 0x0008 +#define FS450_TV_STANDARD_PAL_H 0x0010 +#define FS450_TV_STANDARD_PAL_I 0x0020 +#define FS450_TV_STANDARD_PAL_M 0x0040 +#define FS450_TV_STANDARD_PAL_N 0x0080 +#define FS450_TV_STANDARD_PAL_G 0x0100 + +/* ==========================================================================*/ +/* VGA mode assumed by FS450*/ + + int FS450_get_vga_mode(unsigned long *p_vga_mode); + int FS450_get_available_vga_modes(unsigned long *p_vga_modes); + int FS450_set_vga_mode(unsigned long vga_mode); + /* vga_mode is one of the FS450_VGA_MODE constants */ + /* vga_modes is a bitmask of zero or more FS450_VGA_MODE constants */ + +/* FS450 VGA Mode flags*/ +#define FS450_VGA_MODE_UNKNOWN 0 +#define FS450_VGA_MODE_640X480 0x0001 +#define FS450_VGA_MODE_720X487 0x0002 +#define FS450_VGA_MODE_720X576 0x0004 +#define FS450_VGA_MODE_800X600 0x0008 +#define FS450_VGA_MODE_1024X768 0x0010 + +/* ==========================================================================*/ +/* TVout mode*/ + + int FS450_get_tvout_mode(unsigned long *p_tvout_mode); + int FS450_set_tvout_mode(unsigned long tvout_mode); + /* tvout_mode is a bitmask of FS450_TVOUT_MODE constants */ + +/* FS450 TVout mode flags*/ +#define FS450_TVOUT_MODE_CVBS 0x0001 +#define FS450_TVOUT_MODE_YC 0x0002 +#define FS450_TVOUT_MODE_RGB 0x0004 +#define FS450_TVOUT_MODE_CVBS_YC (FS450_TVOUT_MODE_CVBS | FS450_TVOUT_MODE_YC) + +/* ==========================================================================*/ +/* Flicker control*/ + + int FS450_get_sharpness(int *p_sharpness); + int FS450_set_sharpness(int sharpness); + /* sharpness is a percentage in tenths of a percent, 0 to 1000 */ + + int FS450_get_flicker_filter(int *p_flicker); + int FS450_set_flicker_filter(int flicker); + /* flicker_filter is a percentage in tenths of a percent, 0 to 1000 */ + +/* ==========================================================================*/ +/* Size and Position*/ + + int FS450_get_overscan(int *p_x, int *p_y); + int FS450_set_overscan(int x, int y); + int FS450_get_position(int *p_x, int *p_y); + int FS450_set_position(int x, int y); + /* x and y are horizontal and vertical adjustments, -1000 to +1000 */ + +/* ==========================================================================*/ +/* Visual adjustments*/ + + int FS450_get_color(int *p_color); + int FS450_set_color(int color); + /* color is a percentage, 0 to 100 */ + + int FS450_get_brightness(int *p_brightness); + int FS450_set_brightness(int brightness); + /* brightness is a percentage, 0 to 100 */ + + int FS450_get_contrast(int *p_contrast); + int FS450_set_contrast(int constrast); + /* contrast is a percentage, 0 to 100 */ + +/* ==========================================================================*/ +/* Luma and Chroma filter*/ + + int FS450_get_yc_filter(unsigned int *p_yc_filter); + int FS450_set_yc_filter(unsigned int yc_filter); + /* yc_filter is a bitmask of FS450_LUMA_FILTER and/or FS450_CHROMA_FILTER */ + +/* FS450 Luma and Chroma Filters*/ +#define FS450_LUMA_FILTER 0x0001 +#define FS450_CHROMA_FILTER 0x0002 + +/* ==========================================================================*/ +/* Macrovision*/ + + int FS450_get_aps_trigger_bits(unsigned int *p_trigger_bits); + int FS450_set_aps_trigger_bits(unsigned int trigger_bits); + /* trigger_bits is one of the FS450_APS_TRIGGER constants */ + +/* APS Trigger Bits*/ +#define FS450_APS_TRIGGER_OFF 0 +#define FS450_APS_TRIGGER_AGC_ONLY 1 +#define FS450_APS_TRIGGER_AGC_2_LINE 2 +#define FS450_APS_TRIGGER_AGC_4_LINE 3 + +/* ==========================================================================*/ +/* direct access to Houston and platform registers (debug builds only)*/ +/* The two functions FS450_ReadRegister and FS450_WriteRegister allow access*/ +/* to device registers. These functions are intended for debugging purposes*/ +/* only and should not be included in a shipping product.*/ + +#ifdef FS450_DIRECTREG + +#define SOURCE_HOUSTON 0 +#define SOURCE_GCC 1 + + typedef struct _S_REG_INFO + { + int source; + unsigned int size; + unsigned long offset; + unsigned long value; + } + S_REG_INFO; + + int FS450_ReadRegister(S_REG_INFO * p_reg); + int FS450_WriteRegister(S_REG_INFO * p_reg); + +#endif + +/* ==========================================================================*/ +/* Error Codes*/ + +#define ERR_INVALID_PARAMETER 0x1000 +#define ERR_NOT_SUPPORTED 0x1001 +#define ERR_CANNOT_CHANGE_WHILE_TV_ON 0x1002 + +#define ERR_DRIVER_NOT_FOUND 0x1100 +#define ERR_DRIVER_ERROR 0x1101 +#define ERR_DEVICE_NOT_FOUND 0x1120 + +#define ERR_I2C_MISSING_DEVICE 0x1200 +#define ERR_I2C_WRITE_FAILED 0x1201 +#define ERR_I2C_READ_FAILED 0x1202 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs451.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs451.c new file mode 100644 index 000000000..74948cf67 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs451.c @@ -0,0 +1,246 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_fs451.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: tv_fs451.c $ + * $Revision: 1.2 $ + * + * This file contains routines to control the FS451 tvout encoder. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/*----------------------------------------------------------------------------- + * gfx_set_tv_format + * + * This routine sets the TV encoder registers to the specified format + * and resolution. + * Currently only NTSC 640x480 is supported. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs451_set_tv_format(int format, int resolution) +#else +int +gfx_set_tv_format(int format, int resolution) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_output + * + * This routine sets the TV encoder registers to the specified output type. + * Supported output types are : S-VIDEO and Composite. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs451_set_tv_output(int output) +#else +int +gfx_set_tv_output(int output) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_defaults + * + * This routine sets all of the TV encoder registers to default values for + * the specified format. Currently only NTSC is supported. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs451_set_tv_defaults(int format) +#else +int +gfx_set_tv_defaults(int format) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_enable + * + * This routine enables or disables the TV output. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs451_set_tv_enable(int enable) +#else +int +gfx_set_tv_enable(int enable) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_enable + * + * This routine enables or disables the use of the hardware CC registers + * in the TV encoder. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs451_set_tv_cc_enable(int enable) +#else +int +gfx_set_tv_cc_enable(int enable) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_data + * + * This routine writes the two specified characters to the CC data register + * of the TV encoder. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +fs451_set_tv_cc_data(unsigned char data1, unsigned char data2) +#else +int +gfx_set_tv_cc_data(unsigned char data1, unsigned char data2) +#endif +{ + /* ### ADD ### IMPLEMENTATION */ + return (0); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_geode.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_geode.c new file mode 100644 index 000000000..193808340 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_geode.c @@ -0,0 +1,125 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/tv_geode.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/*----------------------------------------------------------------------------- + * TV_GEODE.C + * + * Version 1.20 - February 9, 2000 + * + * This file contains routines to program the TV encoder when it is + * integrated onto a Geode processor. + * + * History: + * Initial version ported from code by Ilia Stolov. + * Versions 0.1 through 1.20 by Brian Falardeau. + * + * Copyright (c) 1999-2000 National Semiconductor. + *----------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * gfx_set_tv_defaults + * + * This routine sets all of the TV encoder registers to default values for + * the specified format. Currently only NTSC is supported. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +geode_set_tv_defaults(int format) +#else +int +gfx_set_tv_defaults(int format) +#endif +{ + /* SET DEFAULTS FOR NTSC */ + + WRITE_VID32(SC1400_TVOUT_HORZ_TIM, 0x00790359); + WRITE_VID32(SC1400_TVOUT_HORZ_SYNC, 0x03580350); + WRITE_VID32(SC1400_TVOUT_VERT_SYNC, 0x0A002001); + WRITE_VID32(SC1400_TVOUT_LINE_END, 0x039C00F0); + WRITE_VID32(SC1400_TVOUT_VERT_DOWNSCALE, 0xFFFFFFFF); + WRITE_VID32(SC1400_TVOUT_HORZ_SCALING, 0x10220700); + WRITE_VID32(SC1400_TVOUT_EMMA_BYPASS, 0x0002D0F0); + WRITE_VID32(SC1400_TVENC_TIM_CTRL_1, 0xA2E03000); + WRITE_VID32(SC1400_TVENC_TIM_CTRL_2, 0x1FF20000); + WRITE_VID32(SC1400_TVENC_TIM_CTRL_3, 0x00000000); + WRITE_VID32(SC1400_TVENC_SUB_FREQ, 0x21F12000); + WRITE_VID32(SC1400_TVENC_DISP_POS, 0x00030071); + WRITE_VID32(SC1400_TVENC_DISP_SIZE, 0x00EF02CF); + + /* ### ADD ### DEFAULTS FOR PAL */ + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_enable + * + * This routine enables or disables the TV output. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +geode_set_tv_enable(int enable) +#else +int +gfx_set_tv_enable(int enable) +#endif +{ + unsigned long value; + + value = READ_VID32(SC1400_DISPLAY_CONFIG); + if (enable) + value |= SC1400_DCFG_TVOUT_EN; + else + value &= ~(SC1400_DCFG_TVOUT_EN); + WRITE_VID32(SC1400_DISPLAY_CONFIG, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_enable + * + * This routine enables or disables the use of the hardware CC registers + * in the TV encoder. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +geode_set_tv_cc_enable(int enable) +#else +int +gfx_set_tv_cc_enable(int enable) +#endif +{ + unsigned long value; + + value = READ_VID32(SC1400_TVENC_CC_CONTROL); + value &= ~(0x0005F); + if (enable) + value |= 0x51; + WRITE_VID32(SC1400_TVENC_CC_CONTROL, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_tv_cc_data + * + * This routine writes the two specified characters to the CC data register + * of the TV encoder. + *----------------------------------------------------------------------------- + */ +#if GFX_TV_DYNAMIC +int +geode_set_tv_cc_data(unsigned char data1, unsigned char data2) +#else +int +gfx_set_tv_cc_data(unsigned char data1, unsigned char data2) +#endif +{ + unsigned long value; + + value = data1 | (((unsigned long)data2) << 8); + WRITE_VID32(SC1400_TVENC_CC_DATA, value); + return (0); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vga_gu1.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vga_gu1.c new file mode 100644 index 000000000..d5fa26347 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vga_gu1.c @@ -0,0 +1,705 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vga_gu1.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: vga_gu1.c $ + * + * This file contains routines to set modes using the VGA registers. + * Since this file is for the first generation graphics unit, it interfaces + * to SoftVGA registers. It works for both VSA1 and VSA2. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* SoftVGA Extended CRTC register indices and bit definitions */ + +#define CRTC_EXTENDED_REGISTER_LOCK 0x30 +#define CRTC_MODE_SWITCH_CONTROL 0x3F + +/* BIT DEFINITIONS */ + +#define CRTC_BIT_16BPP 0x01 +#define CRTC_BIT_555 0x02 + +/* LOCAL ROUTINE DEFINITIONS */ + +int gu1_detect_vsa2(void); + +/*---------------------------------*/ +/* MODE TABLES FOR VGA REGISTERS */ +/*---------------------------------*/ + +/* FOR SoftVGA, the CRTC_EXTENDED_ADDRESS_CONTROL (0x43) is always equal to + * 0x03 for a packed linear frame buffer organization. The + * CRTC_EXTENDED_DAC_CONTROL (0x4B) is always equal to 0x03 to work with + * older versions of VSA1 (that needed to specify 8 or 16 bit bus to an + * external RAMDAC. This is not used in VSA2. The clock frequency is + * specified in register 0x4D if clock control (0x4C) is set to 0x80. + * Higher resolutions (1280x1024) use the CRTC_EXTENDED_VERTICAL_TIMING + * register (index 0x41). + */ + +gfx_vga_struct gfx_vga_modes[] = { +/*------------------------------------------------------------------------------*/ + {640, 480, 60, /* 640x480 */ + 25, /* 25 MHz clock = 60 Hz refresh rate */ + 0xE3, /* miscOutput register */ + {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, /* standard CRTC */ + 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3, 0xFF}, + {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}}, +/*------------------------------------------------------------------------------*/ + {640, 480, 72, /* 640x480 */ + 29, /* 29 MHz clock = 72 Hz refresh rate */ + 0xE3, /* miscOutput register */ + {0x63, 0x4f, 0x50, 0x86, 0x55, 0x99, 0x06, 0x3e, /* standard CRTC */ + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe9, 0x0c, 0xdf, 0x00, 0x00, 0xe7, 0x00, 0xe3, 0xff}, + {0x6D, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x01, 0x08, 0x80, 0x1F, 0x00, 0x4B}}, +/*------------------------------------------------------------------------------*/ + {640, 480, 75, /* 640x480 */ + 31, /* 31.5 MHz clock = 75 Hz refresh rate */ + 0xE3, /* miscOutput register */ + {0x64, 0x4F, 0x4F, 0x88, 0x54, 0x9B, 0xF2, 0x1F, /* standard CRTC */ + 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE1, 0x04, 0xDF, 0x50, 0x00, 0xDF, 0xF3, 0xE3, 0xFF}, + {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x00, 0x03, 0x80, 0x1F, 0x00, 0x00}}, +/*------------------------------------------------------------------------------*/ + {800, 600, 60, /* 800x600 */ + 40, /* 40 MHz clock = 60 Hz refresh rate */ + 0x23, /* miscOutput register */ + {0x7F, 0x63, 0x64, 0x82, 0x6B, 0x1B, 0x72, 0xF0, /* standard CRTC */ + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x0D, 0x57, 0x64, 0x00, 0x57, 0x73, 0xE3, 0xFF}, + {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x00, 0x03, 0x80, 0x28, 0x00, 0x00}}, +/*------------------------------------------------------------------------------*/ + {800, 600, 72, /* 800x600 */ + 47, /* 47 MHz clock = 72 Hz refresh rate */ + 0x2B, /* miscOutput register */ + {0x7D, 0x63, 0x63, 0x81, 0x6D, 0x1B, 0x98, 0xF0, /* standard CRTC */ + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7D, 0x03, 0x57, 0x00, 0x00, 0x57, 0x9A, 0xE3, 0xFF}, + {0x6F, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x01, 0x08, 0x80, 0x32, 0x00, 0x4B}}, +/*------------------------------------------------------------------------------*/ + {800, 600, 75, /* 800x600 */ + 49, /* 49.5 MHz clock = 75 Hz refresh rate */ + 0x23, /* miscOutput register */ + {0x7F, 0x63, 0x63, 0x83, 0x68, 0x11, 0x6F, 0xF0, /* standard CRTC */ + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x1C, 0x57, 0x64, 0x00, 0x57, 0x70, 0xE3, 0xFF}, + {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x00, 0x03, 0x80, 0x31, 0x00, 0x00}}, +/*------------------------------------------------------------------------------*/ + {1024, 768, 60, /* 1024x768 */ + 65, /* 65 MHz clock = 60 Hz refresh rate */ + 0xE3, /* miscOutput register */ + {0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xF5, /* standard CRTC */ + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x0A, 0xFF, 0x80, 0x00, 0xFF, 0x25, 0xE3, 0xFF}, + {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x00, 0x03, 0x80, 0x41, 0x00, 0x00}}, +/*------------------------------------------------------------------------------*/ + {1024, 768, 70, /* 1024x768 */ + 76, /* 76 MHz clock = 70 Hz refresh rate */ + 0x2B, /* miscOutput register */ + {0xA1, 0x7F, 0x7F, 0x85, 0x85, 0x95, 0x24, 0xF5, /* standard CRTC */ + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x00, 0x00, 0xFF, 0x26, 0xE3, 0xFF}, + {0x62, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x01, 0x02, 0x80, 0x4B, 0x00, 0x4B}}, +/*------------------------------------------------------------------------------*/ + {1024, 768, 75, /* 1024x768 */ + 79, /* 79 MHz clock = 75 Hz refresh rate */ + 0xE3, /* miscOutput register */ + {0x9F, 0x7F, 0x7F, 0x83, 0x84, 0x8F, 0x1E, 0xF5, /* standard CRTC */ + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x04, 0xFF, 0x80, 0x00, 0xFF, 0x1F, 0xE3, 0xFF}, + {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x00, 0x03, 0x80, 0x4F, 0x00, 0x00}}, +/*------------------------------------------------------------------------------*/ + {1280, 1024, 60, /* 1280x1024 */ + 108, /* 108 MHz clock = 60 Hz refresh rate */ + 0x23, /* miscOutput register */ + {0xCF, 0x9F, 0xA0, 0x92, 0xAA, 0x19, 0x28, 0x52, /* standard CRTC */ + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF}, + {0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x00, 0x03, 0x80, 0x6C, 0x00, 0x00}}, +/*------------------------------------------------------------------------------*/ + {1280, 1024, 75, /* 1280x1024 */ + 135, /* 135 MHz clock = 75 Hz refresh rate */ + 0x23, /* miscOutput register */ + {0xCE, 0x9F, 0x9F, 0x92, 0xA4, 0x15, 0x28, 0x52, /* standard CRTC */ + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF}, + {0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x00, 0x03, 0x80, 0x87, 0x00, 0x00}}, +/*------------------------------------------------------------------------------*/ + {1280, 1024, 85, /* 1280x1024 */ + 159, /* 159 MHz clock = 85 Hz refresh rate */ + 0x2B, /* miscOutput register */ + {0xD3, 0x9F, 0xA0, 0x98, 0xA8, 0x9C, 0x2E, 0x5A, /* standard CRTC */ + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x04, 0xFF, 0x00, 0x00, 0xFF, 0x30, 0xE3, 0xFF}, + {0x6B, 0x41, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, /* extended CRTC */ + 0x00, 0x00, 0x01, 0x00, 0x80, 0x9D, 0x00, 0x4B}}, + +/*------------------------------------------------------------------------------*/ +}; + +#define GFX_VGA_MODES sizeof(gfx_vga_modes)/sizeof(gfx_vga_struct) + +/*----------------------------------------------------------------------------- + * gfx_get_softvga_active + * + * This returns the active status of SoftVGA + *----------------------------------------------------------------------------- + */ +int +gfx_get_softvga_active(void) +{ + unsigned short crtcindex, crtcdata; + + if (gu1_detect_vsa2()) + return (gfx_get_vsa2_softvga_enable()); + + crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + OUTB(crtcindex, CRTC_MODE_SWITCH_CONTROL); + return (INB(crtcdata) & 0x1); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_test_pci + * + * This routine looks for the VGA PCI header. It checks to see that bit 1 + * of the command register is writable to know that SoftVGA is trapping + * the PCI config cuscles. If SoftVGA is not emulating the header, the + * hardware will still respond with the proper device ID, etc. + * + * We need to know that SoftVGA is really there so that we can set the + * command register and have the proper effect (enable trapping of VGA). + * Otherwise, if we enable VGA via the PCI header, trapping really won't be + * enabled and the VGA register writes will go out to the external card. + *----------------------------------------------------------------------------- + */ +int +gfx_vga_test_pci(void) +{ + int softvga = 1; + unsigned long value; + + value = gfx_pci_config_read(0x80009400); + if ((value & 0x0000FFFF) != 0x1078) + softvga = 0; + else { + value = gfx_pci_config_read(0x80009404); + gfx_pci_config_write(0x80009404, value | 0x02); + if (!(gfx_pci_config_read(0x80009404) & 0x02)) + softvga = 0; + gfx_pci_config_write(0x80009404, value); + } + return (softvga); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_get_pci_command + * + * This routine returns the value of the PCI command register. + *----------------------------------------------------------------------------- + */ +unsigned char +gfx_vga_get_pci_command(void) +{ + unsigned long value; + + value = gfx_pci_config_read(0x80009404); + return ((unsigned char)value); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_set_pci_command + * + * This routine writes the value of the PCI command register. It is used + * to enable or disable SoftVGA. + * + * Bit 0: Enable VGA IO + * Bit 1: Enable VGA memory + *----------------------------------------------------------------------------- + */ +int +gfx_vga_set_pci_command(unsigned char command) +{ + unsigned long value; + + value = gfx_pci_config_read(0x80009404) & 0xFFFFFF00; + value |= (unsigned long)command; + gfx_pci_config_write(0x80009404, value); + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_seq_reset + * + * This routine enables or disables SoftVGA. It is used to make SoftVGA + * "be quiet" and not interfere with any of the direct hardware access from + * Durango. For VSA1, the sequencer is reset to stop text redraws. VSA2 may + * provide a better way to have SoftVGA sit in the background. + *----------------------------------------------------------------------------- + */ +int +gfx_vga_seq_reset(int reset) +{ + OUTB(0x3C4, 0); + OUTB(0x3C5, (unsigned char)(reset ? 0x00 : 0x03)); + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_set_graphics_bits + * + * This routine sets the standard VGA sequencer, graphics controller, and + * attribute registers to appropriate values for a graphics mode (packed, + * 8 BPP or greater). This is also known as "VESA" modes. The timings for + * a particular mode are handled by the CRTC registers, which are set by + * the "gfx_vga_restore" routine. Most OSs that use VGA to set modes save + * and restore the standard VGA registers themselves, which is why these + * registers are not part of the save/restore paradigm. + *----------------------------------------------------------------------------- + */ +int +gfx_vga_set_graphics_bits(void) +{ + /* SET GRAPHICS BIT IN GRAPHICS CONTROLLER REG 0x06 */ + + OUTB(0x3CE, 0x06); + OUTB(0x3CF, 0x01); + + /* SET GRAPHICS BIT IN ATTRIBUTE CONTROLLER REG 0x10 */ + + INB(0x3BA); /* Reset flip-flop */ + INB(0x3DA); + OUTB(0x3C0, 0x10); + OUTB(0x3C0, 0x01); + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_mode + * + * This routine searches the VGA mode table for a match of the specified + * mode and then fills in the VGA structure with the associated VGA register + * values. The "gfx_vga_restore" routine can then be called to actually + * set the mode. + *----------------------------------------------------------------------------- + */ +int +gfx_vga_mode(gfx_vga_struct * vga, int xres, int yres, int bpp, int hz) +{ + unsigned int i; + unsigned short pitch; + + for (i = 0; i < GFX_VGA_MODES; i++) { + if ((gfx_vga_modes[i].xsize == xres) && + (gfx_vga_modes[i].ysize == yres) && (gfx_vga_modes[i].hz == hz)) { + /* COPY ENTIRE STRUCTURE FROM THE TABLE */ + + *vga = gfx_vga_modes[i]; + + /* SET PITCH TO 1K OR 2K */ + /* CRTC_EXTENDED_OFFSET index is 0x45, so offset = 0x05 */ + + pitch = (unsigned short)xres; + if (bpp > 8) + pitch <<= 1; + if (pitch <= 1024) + pitch = 1024 >> 3; + else + pitch = 2048 >> 3; + vga->stdCRTCregs[0x13] = (unsigned char)pitch; + vga->extCRTCregs[0x05] = (unsigned char)((pitch >> 8) & 0x03); + + /* SET PROPER COLOR DEPTH VALUE */ + /* CRTC_EXTENDED_COLOR_CONTROL index is 0x46, so offset = 0x06 */ + + switch (bpp) { + case 15: + vga->extCRTCregs[0x06] = CRTC_BIT_16BPP | CRTC_BIT_555; + break; + case 16: + vga->extCRTCregs[0x06] = CRTC_BIT_16BPP; + break; + default: + vga->extCRTCregs[0x06] = 0; + break; + } + return (GFX_STATUS_OK); + } + } + return (GFX_STATUS_UNSUPPORTED); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_pitch + * + * This routine updates the VGA regisers in the specified VGA structure for + * the specified pitch. It does not program the hardware. + *----------------------------------------------------------------------------- + */ +int +gfx_vga_pitch(gfx_vga_struct * vga, unsigned short pitch) +{ + pitch >>= 3; + vga->stdCRTCregs[0x13] = (unsigned char)pitch; + vga->extCRTCregs[0x05] = (unsigned char)((pitch >> 8) & 0x03); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_save + * + * This routine saves the state of the VGA registers into the specified + * structure. Flags indicate what portions of the register state need to + * be saved. + *----------------------------------------------------------------------------- + */ +int +gfx_vga_save(gfx_vga_struct * vga, int flags) +{ + int i; + unsigned short crtcindex, crtcdata; + + crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + /* CHECK MISCELLANEOUS OUTPUT FLAG */ + + if (flags & GFX_VGA_FLAG_MISC_OUTPUT) { + /* SAVE MISCCELLANEOUS OUTPUT REGISTER */ + + vga->miscOutput = INB(0x3CC); + } + + /* CHECK STANDARD CRTC FLAG */ + + if (flags & GFX_VGA_FLAG_STD_CRTC) { + /* SAVE STANDARD CRTC REGISTERS */ + + for (i = 0; i < GFX_STD_CRTC_REGS; i++) { + OUTB(crtcindex, (unsigned char)i); + vga->stdCRTCregs[i] = INB(crtcdata); + } + } + + /* CHECK EXTENDED CRTC FLAG */ + + if (flags & GFX_VGA_FLAG_EXT_CRTC) { + /* SAVE EXTENDED CRTC REGISTERS */ + + for (i = 0; i < GFX_EXT_CRTC_REGS; i++) { + OUTB(crtcindex, (unsigned char)(0x40 + i)); + vga->extCRTCregs[i] = INB(crtcdata); + } + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_clear_extended + * + * This routine clears the extended SoftVGA register values to have SoftVGA + * behave like standard VGA. + *----------------------------------------------------------------------------- + */ +void +gfx_vga_clear_extended(void) +{ + int i; + unsigned short crtcindex, crtcdata; + + crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + OUTB(crtcindex, 0x30); + OUTB(crtcdata, 0x57); + OUTB(crtcdata, 0x4C); + for (i = 0x40; i <= 0x4F; i++) { + OUTB(crtcindex, (unsigned char)i); + OUTB(crtcdata, 0); + } + OUTB(crtcindex, 0x30); + OUTB(crtcdata, 0x00); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_restore + * + * This routine restores the state of the VGA registers from the specified + * structure. Flags indicate what portions of the register state need to + * be saved. + *----------------------------------------------------------------------------- + */ +int +gfx_vga_restore(gfx_vga_struct * vga, int flags) +{ + int i; + unsigned short crtcindex, crtcdata; + + crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + /* CHECK MISCELLANEOUS OUTPUT FLAG */ + + if (flags & GFX_VGA_FLAG_MISC_OUTPUT) { + /* RESTORE MISCELLANEOUS OUTPUT REGISTER VALUE */ + + OUTB(0x3C2, vga->miscOutput); + } + + /* CHECK STANDARD CRTC FLAG */ + + if (flags & GFX_VGA_FLAG_STD_CRTC) { + /* UNLOCK STANDARD CRTC REGISTERS */ + + OUTB(crtcindex, 0x11); + OUTB(crtcdata, 0); + + /* RESTORE STANDARD CRTC REGISTERS */ + + for (i = 0; i < GFX_STD_CRTC_REGS; i++) { + OUTB(crtcindex, (unsigned char)i); + OUTB(crtcdata, vga->stdCRTCregs[i]); + } + } + + /* CHECK EXTENDED CRTC FLAG */ + + if (flags & GFX_VGA_FLAG_EXT_CRTC) { + /* UNLOCK EXTENDED CRTC REGISTERS */ + + OUTB(crtcindex, 0x30); + OUTB(crtcdata, 0x57); + OUTB(crtcdata, 0x4C); + + /* RESTORE EXTENDED CRTC REGISTERS */ + + for (i = 0; i < GFX_EXT_CRTC_REGS; i++) { + OUTB(crtcindex, (unsigned char)(0x40 + i)); + OUTB(crtcdata, vga->extCRTCregs[i]); + } + + /* LOCK EXTENDED CRTC REGISTERS */ + + OUTB(crtcindex, 0x30); + OUTB(crtcdata, 0x00); + + /* CHECK IF DIRECT FRAME BUFFER MODE (VESA MODE) */ + + if (vga->extCRTCregs[0x03] & 1) { + /* SET BORDER COLOR TO BLACK */ + /* This really should be another thing saved/restored, but */ + /* Durango currently doesn't do the attr controller registers. */ + + INB(0x3BA); /* Reset flip-flop */ + INB(0x3DA); + OUTB(0x3C0, 0x11); + OUTB(0x3C0, 0x00); + } + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_mode_switch + * + * This routine programs the SoftVGA register to indicate that a mode switch + * is in progress. This results in a cleaner mode switch since SoftVGA will + * not validate the hardware with intermediate values. + *----------------------------------------------------------------------------- + */ +int +gfx_vga_mode_switch(int active) +{ + unsigned short crtcindex, crtcdata; + + crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + /* UNLOCK EXTENDED CRTC REGISTERS */ + + OUTB(crtcindex, CRTC_EXTENDED_REGISTER_LOCK); + OUTB(crtcdata, 0x57); + OUTB(crtcdata, 0x4C); + + /* SIGNAL THE BEGINNING OR END OF THE MODE SWITCH */ + /* SoftVGA will hold off validating the back end hardware. */ + + OUTB(crtcindex, CRTC_MODE_SWITCH_CONTROL); + active = active ? 1 : 0; + OUTB(crtcdata, (unsigned char)active); + + /* WAIT UNTIL SOFTVGA HAS VALIDATED MODE IF ENDING MODE SWITCH */ + /* This is for VSA1 only, where SoftVGA waits until the next */ + /* vertical blank to validate the hardware state. */ + + if ((!active) && (!(gu1_detect_vsa2()))) { + OUTB(crtcindex, 0x33); + while (INB(crtcdata) & 0x80) ; + } + + /* LOCK EXTENDED CRTC REGISTERS */ + + OUTB(crtcindex, CRTC_EXTENDED_REGISTER_LOCK); + OUTB(crtcdata, 0x00); + return (0); +} + +/*----------------------------------------------------------------------------- + * gu1_detect_vsa2 + * + * This routine detects if VSA2 is present. The interface to SoftVGA + * changed slightly. + *----------------------------------------------------------------------------- + */ +int +gu1_detect_vsa2(void) +{ + unsigned short crtcindex, crtcdata; + + crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + OUTB(crtcindex, 0x35); + if (INB(crtcdata) != 'C') + return (0); + OUTB(crtcindex, 0x36); + if (INB(crtcdata) != 'X') + return (0); + return (1); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1200.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1200.c new file mode 100644 index 000000000..f52d02b35 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1200.c @@ -0,0 +1,2930 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1200.c,v 1.2 2003/01/14 09:34:34 alanh Exp $ */ +/* + * $Workfile: vid_1200.c $ + * + * This file contains routines to control the SC1200 video overlay hardware. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/*---------------------------------------------------------------------------- + * SC1200 PLL TABLE + *---------------------------------------------------------------------------- + */ + +typedef struct tagSC1200PLL +{ + long frequency; /* 16.16 fixed point frequency */ + unsigned long clock_select; /* clock select register (0x2C) */ +} +SC1200PLL; + +SC1200PLL gfx_sc1200_clock_table[] = { + {(25L << 16) | ((1750L * 65536L) / 10000L), 0x0070E00C}, /* 25.1750 (sc=24.9231) */ + {(27L << 16) | ((0000L * 65536L) / 10000L), 0x00300100}, /* 27.0000 */ + {(28L << 16) | ((3220L * 65536L) / 10000L), 0x0070EC0C}, /* 28.3220 (SC=27.000) */ + {(31L << 16) | ((5000L * 65536L) / 10000L), 0x00500D02}, /* 31.5000 */ + {(36L << 16) | ((0000L * 65536L) / 10000L), 0x00500F02}, /* 36.0000 */ + {(37L << 16) | ((5000L * 65536L) / 10000L), 0x0050B108}, /* 37.5000 */ + {(40L << 16) | ((0000L * 65536L) / 10000L), 0x0050D20D}, /* 40.0000 */ + {(44L << 16) | ((9000L * 65536L) / 10000L), 0x0050DC0D}, /* 44.9000 */ + {(49L << 16) | ((5000L * 65536L) / 10000L), 0x00501502}, /* 49.5000 */ + {(50L << 16) | ((0000L * 65536L) / 10000L), 0x0050A404}, /* 50.0000 */ + {(50L << 16) | ((3500L * 65536L) / 10000L), 0x0050E00C}, /* 50.3500 */ + {(54L << 16) | ((0000L * 65536L) / 10000L), 0x00300300}, /* 54.0000 */ + {(56L << 16) | ((3916L * 65536L) / 10000L), 0x0050F40D}, /* 56.3916 */ + {(56L << 16) | ((6440L * 65536L) / 10000L), 0x0050EC0C}, /* 56.6440 */ + {(59L << 16) | ((0000L * 65536L) / 10000L), 0x0030A207}, /* 59.0000 */ + {(63L << 16) | ((0000L * 65536L) / 10000L), 0x00300D02}, /* 63.0000 */ + {(65L << 16) | ((0000L * 65536L) / 10000L), 0x0030CC0F}, /* 65.0000 */ + {(67L << 16) | ((5000L * 65536L) / 10000L), 0x00300400}, /* 67.5000 */ + {(70L << 16) | ((8000L * 65536L) / 10000L), 0x00301403}, /* 70.8000 */ + {(72L << 16) | ((0000L * 65536L) / 10000L), 0x00300F02}, /* 72.0000 */ + {(75L << 16) | ((0000L * 65536L) / 10000L), 0x0030B108}, /* 75.0000 */ + {(78L << 16) | ((7500L * 65536L) / 10000L), 0x0030A205}, /* 78.7500 */ + {(80L << 16) | ((0000L * 65536L) / 10000L), 0x0030D20D}, /* 80.0000 */ + {(87L << 16) | ((2728L * 65536L) / 10000L), 0x0030E00E}, /* 87.2728 */ + {(89L << 16) | ((8000L * 65536L) / 10000L), 0x0030DC0D}, /* 89.8000 */ + {(94L << 16) | ((5000L * 65536L) / 10000L), 0x00300600}, /* 99.0000 */ + {(99L << 16) | ((0000L * 65536L) / 10000L), 0x00301502}, /* 99.0000 */ + {(100L << 16) | ((0000L * 65536L) / 10000L), 0x0030A404}, /* 100.00 */ + {(108L << 16) | ((0000L * 65536L) / 10000L), 0x00100300}, /* 108.00 */ + {(112L << 16) | ((5000L * 65536L) / 10000L), 0x00301802}, /* 108.00 */ + {(130L << 16) | ((0000L * 65536L) / 10000L), 0x0010CC0F}, /* 130.00 */ + {(135L << 16) | ((0000L * 65536L) / 10000L), 0x00100400}, /* 135.00 */ + {(157L << 16) | ((5000L * 65536L) / 10000L), 0x0010A205}, /* 157.50 */ + {(162L << 16) | ((0000L * 65536L) / 10000L), 0x00100500}, /* 162.00 */ + {(175L << 16) | ((0000L * 65536L) / 10000L), 0x0010E00E}, /* 175.50 */ + {(189L << 16) | ((0000L * 65536L) / 10000L), 0x00100600}, /* 189.00 */ + {(202L << 16) | ((0000L * 65536L) / 10000L), 0x0010EF0E}, /* 202.50 */ + {(232L << 16) | ((0000L * 65536L) / 10000L), 0x0010AA04}, /* 232.50 */ + + /* Precomputed inidces in the hardware */ + {0x0018EC4D, 0x000F0000}, /* 24.923052 */ + {0x00192CCC, 0x00000000}, /* 25.1750 */ + {0x001B0000, 0x00300100}, /* 27.0000 */ + {0x001F8000, 0x00010000}, /* 31.5000 */ + {0x00240000, 0x00020000}, /* 36.0000 */ + {0x00280000, 0x00030000}, /* 40.0000 */ + {0x00318000, 0x00050000}, /* 49.5000 */ + {0x00320000, 0x00040000}, /* 50.0000 */ + {0x00384000, 0x00060000}, /* 56.2500 */ + {0x00410000, 0x00080000}, /* 65.0000 */ + {0x004E8000, 0x000A0000}, /* 78.5000 */ + {0x005E8000, 0x000B0000}, /* 94.5000 */ + {0x006C0000, 0x000C0000}, /* 108.0000 */ + {0x00870000, 0x000D0000}, /* 135.0000 */ +}; + +#define NUM_SC1200_FREQUENCIES sizeof(gfx_sc1200_clock_table)/sizeof(SC1200PLL) + +int sc1200_set_video_enable(int enable); +int sc1200_set_video_format(unsigned long format); +int sc1200_set_video_size(unsigned short width, unsigned short height); +int sc1200_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch); +int sc1200_set_video_offset(unsigned long offset); +int sc1200_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset, + unsigned long voffset); +int sc1200_set_video_window(short x, short y, unsigned short w, + unsigned short h); +int sc1200_set_video_left_crop(unsigned short x); +int sc1200_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int sc1200_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int sc1200_set_video_vertical_downscale(unsigned short srch, + unsigned short dsth); +void sc1200_set_video_vertical_downscale_enable(int enable); +int sc1200_set_video_downscale_config(unsigned short type, unsigned short m); +int sc1200_set_video_color_key(unsigned long key, unsigned long mask, + int bluescreen); +int sc1200_set_video_filter(int xfilter, int yfilter); +int sc1200_set_video_palette(unsigned long *palette); +int sc1200_set_video_palette_entry(unsigned long index, unsigned long color); +int sc1200_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4); +int sc1200_set_video_downscale_enable(int enable); +int sc1200_set_video_source(VideoSourceType source); +int sc1200_set_vbi_source(VbiSourceType source); +int sc1200_set_vbi_lines(unsigned long even, unsigned long odd); +int sc1200_set_vbi_total(unsigned long even, unsigned long odd); +int sc1200_set_video_interlaced(int enable); +int sc1200_set_color_space_YUV(int enable); +int sc1200_set_vertical_scaler_offset(char offset); +int sc1200_set_top_line_in_odd(int enable); +int sc1200_set_genlock_delay(unsigned long delay); +int sc1200_set_genlock_enable(int flags); +int sc1200_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, + unsigned long color1, unsigned long color2); +int sc1200_set_video_cursor_enable(int enable); +int sc1200_set_video_request(short x, short y); + +int sc1200_select_alpha_region(int region); +int sc1200_set_alpha_enable(int enable); +int sc1200_set_alpha_window(short x, short y, + unsigned short width, unsigned short height); +int sc1200_set_alpha_value(unsigned char alpha, char delta); +int sc1200_set_alpha_priority(int priority); +int sc1200_set_alpha_color(unsigned long color); +int sc1200_set_alpha_color_enable(int enable); +int sc1200_set_no_ck_outside_alpha(int enable); +int sc1200_disable_softvga(void); +int sc1200_enable_softvga(void); +int sc1200_set_macrovision_enable(int enable); +void sc1200_reset_video(void); +int sc1200_set_display_control(int sync_polarities); +void sc1200_set_clock_frequency(unsigned long frequency); +int sc1200_set_screen_enable(int enable); +int sc1200_set_crt_enable(int enable); + +/* READ ROUTINES IN GFX_VID.C */ + +int sc1200_get_video_enable(void); +int sc1200_get_video_format(void); +unsigned long sc1200_get_video_src_size(void); +unsigned long sc1200_get_video_line_size(void); +unsigned long sc1200_get_video_xclip(void); +unsigned long sc1200_get_video_offset(void); +void sc1200_get_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset); +void sc1200_get_video_yuv_pitch(unsigned long *ypitch, + unsigned long *uvpitch); +unsigned long sc1200_get_video_upscale(void); +unsigned long sc1200_get_video_scale(void); +unsigned long sc1200_get_video_downscale_delta(void); +int sc1200_get_video_vertical_downscale_enable(void); +int sc1200_get_video_downscale_config(unsigned short *type, + unsigned short *m); +void sc1200_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4); +void sc1200_get_video_downscale_enable(int *enable); +unsigned long sc1200_get_video_dst_size(void); +unsigned long sc1200_get_video_position(void); +unsigned long sc1200_get_video_color_key(void); +unsigned long sc1200_get_video_color_key_mask(void); +int sc1200_get_video_palette_entry(unsigned long index, + unsigned long *palette); +int sc1200_get_video_color_key_src(void); +int sc1200_get_video_filter(void); +int sc1200_get_video_request(short *x, short *y); +int sc1200_get_video_source(VideoSourceType * source); +int sc1200_get_vbi_source(VbiSourceType * source); +unsigned long sc1200_get_vbi_lines(int odd); +unsigned long sc1200_get_vbi_total(int odd); +int sc1200_get_video_interlaced(void); +int sc1200_get_color_space_YUV(void); +int sc1200_get_vertical_scaler_offset(char *offset); +unsigned long sc1200_get_genlock_delay(void); +int sc1200_get_genlock_enable(void); +int sc1200_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, + unsigned long *color1, unsigned short *color2); +unsigned long sc1200_read_crc(void); +unsigned long sc1200_read_crc32(void); +unsigned long sc1200_read_window_crc(int source, unsigned short x, + unsigned short y, unsigned short width, + unsigned short height, int crc32); +int sc1200_get_macrovision_enable(void); + +void sc1200_get_alpha_enable(int *enable); +void sc1200_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height); +void sc1200_get_alpha_value(unsigned char *alpha, char *delta); +void sc1200_get_alpha_priority(int *priority); +void sc1200_get_alpha_color(unsigned long *color); +unsigned long sc1200_get_clock_frequency(void); +int sc1200_get_vsa2_softvga_enable(void); +int sc1200_get_sync_polarities(void); + +/*--------------------------------------------------------------------------- + * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine is used to disable all components of video overlay before + * performing a mode switch. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_reset_video(void) +#else +void +gfx_reset_video(void) +#endif +{ + int i; + + gfx_set_video_enable(0); + + /* SET WINDOW 0 AFTER RESET */ + + for (i = 2; i >= 0; i--) { + gfx_select_alpha_region(i); + gfx_set_alpha_enable(0); + gfx_set_alpha_color_enable(0); + } +} + +/*----------------------------------------------------------------------------- + * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine configures the display output. + * + * "sync_polarities" is used to set the polarities of the sync pulses according + * to the following mask: + * + * Bit 0: If set to 1, negative horizontal polarity is programmed, + * otherwise positive horizontal polarity is programmed. + * Bit 1: If set to 1, negative vertical polarity is programmed, + * otherwise positive vertical polarity is programmed. + * + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_display_control(int sync_polarities) +#else +int +gfx_set_display_control(int sync_polarities) +#endif +{ + unsigned long dcfg; + + /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */ + + dcfg = READ_VID32(SC1200_DISPLAY_CONFIG); + dcfg &= ~(SC1200_DCFG_CRT_SYNC_SKW_MASK | SC1200_DCFG_PWR_SEQ_DLY_MASK | + SC1200_DCFG_CRT_HSYNC_POL | SC1200_DCFG_CRT_VSYNC_POL | + SC1200_DCFG_FP_PWR_EN | SC1200_DCFG_FP_DATA_EN); + + dcfg |= (SC1200_DCFG_CRT_SYNC_SKW_INIT | + SC1200_DCFG_PWR_SEQ_DLY_INIT | SC1200_DCFG_GV_PAL_BYP); + + if (PanelEnable) + dcfg |= SC1200_DCFG_FP_PWR_EN; + + /* SET APPROPRIATE SYNC POLARITIES */ + + if (sync_polarities & 0x1) + dcfg |= SC1200_DCFG_CRT_HSYNC_POL; + if (sync_polarities & 0x2) + dcfg |= SC1200_DCFG_CRT_VSYNC_POL; + + WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_clock_frequency + * + * This routine sets the clock frequency, specified as a 16.16 fixed point + * value (0x00318000 = 49.5 MHz). It will set the closest frequency found + * in the lookup table. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_set_clock_frequency(unsigned long frequency) +#else +void +gfx_set_clock_frequency(unsigned long frequency) +#endif +{ + unsigned int index; + unsigned long value, pll; + long min, diff; + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + value = gfx_sc1200_clock_table[0].clock_select; + min = (long)gfx_sc1200_clock_table[0].frequency - frequency; + if (min < 0L) + min = -min; + for (index = 1; index < NUM_SC1200_FREQUENCIES; index++) { + diff = (long)gfx_sc1200_clock_table[index].frequency - frequency; + if (diff < 0L) + diff = -diff; + if (diff < min) { + min = diff; + value = gfx_sc1200_clock_table[index].clock_select; + } + } + + /* SET THE DOT CLOCK REGISTER */ + + pll = READ_VID32(SC1200_VID_MISC); + WRITE_VID32(SC1200_VID_MISC, pll | SC1200_PLL_POWER_NORMAL); + WRITE_VID32(SC1200_VID_CLOCK_SELECT, value); + return; +} + +/*--------------------------------------------------------------------------- + * gfx_set_screen_enable (PRIVATE ROUTINE - NOT PART OF API) + * + * This routine enables or disables the graphics display logic of the video processor. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_screen_enable(int enable) +#else +int +gfx_set_screen_enable(int enable) +#endif +{ + unsigned long config; + + config = READ_VID32(SC1200_DISPLAY_CONFIG); + if (enable) + WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_DIS_EN); + else + WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~SC1200_DCFG_DIS_EN); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_crt_enable + * + * This routine enables or disables the CRT output from the video processor. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_crt_enable(int enable) +#else +int +gfx_set_crt_enable(int enable) +#endif +{ + unsigned long config, misc; + + config = READ_VID32(SC1200_DISPLAY_CONFIG); + misc = READ_VID32(SC1200_VID_MISC); + + /* + * IMPORTANT: For all modes do NOT disable the graphics display logic + * because it might be needed for TV + */ + + switch (enable) { + case CRT_DISABLE: /* HSync:Off VSync:Off */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~(SC1200_DCFG_HSYNC_EN + | SC1200_DCFG_VSYNC_EN + | SC1200_DCFG_DAC_BL_EN)); + WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); + break; + case CRT_ENABLE: /* Enable CRT display, including display logic */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_HSYNC_EN + | SC1200_DCFG_VSYNC_EN | SC1200_DCFG_DAC_BL_EN); + WRITE_VID32(SC1200_VID_MISC, misc & ~SC1200_DAC_POWER_DOWN); + + /* ENABLE GRAPHICS DISPLAY LOGIC */ + gfx_set_screen_enable(1); + break; + case CRT_STANDBY: /* HSync:Off VSync:On */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_HSYNC_EN + | SC1200_DCFG_DAC_BL_EN)) + | SC1200_DCFG_VSYNC_EN); + WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); + break; + case CRT_SUSPEND: /* HSync:On VSync:Off */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_VSYNC_EN + | SC1200_DCFG_DAC_BL_EN)) + | SC1200_DCFG_HSYNC_EN); + WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_enable + * + * This routine enables or disables the video overlay functionality. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_enable(int enable) +#else +int +gfx_set_video_enable(int enable) +#endif +{ + unsigned long vcfg; + + /* WAIT FOR VERTICAL BLANK TO START */ + /* Otherwise a glitch can be observed. */ + + if (gfx_test_timing_active()) { + if (!gfx_test_vertical_active()) { + while (!gfx_test_vertical_active()) ; + } + while (gfx_test_vertical_active()) ; + } + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + if (enable) { + /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(1); + + /* ENABLE SC1200 VIDEO OVERLAY */ + + vcfg |= SC1200_VCFG_VID_EN; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + } else { + /* DISABLE SC1200 VIDEO OVERLAY */ + + vcfg &= ~SC1200_VCFG_VID_EN; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + + /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(0); + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_format + * + * Sets input video format type, to one of the YUV formats or to RGB. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_format(unsigned long format) +#else +int +gfx_set_video_format(unsigned long format) +#endif +{ + unsigned long ctrl, vcfg = 0; + + /* SET THE SC1200 VIDEO INPUT FORMAT */ + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL); + ctrl &= ~(SC1200_VIDEO_INPUT_IS_RGB); + vcfg &= ~(SC1200_VCFG_VID_INP_FORMAT | SC1200_VCFG_4_2_0_MODE); + switch (format) { + case VIDEO_FORMAT_UYVY: + vcfg |= SC1200_VCFG_UYVY_FORMAT; + break; + case VIDEO_FORMAT_YUYV: + vcfg |= SC1200_VCFG_YUYV_FORMAT; + break; + case VIDEO_FORMAT_Y2YU: + vcfg |= SC1200_VCFG_Y2YU_FORMAT; + break; + case VIDEO_FORMAT_YVYU: + vcfg |= SC1200_VCFG_YVYU_FORMAT; + break; + case VIDEO_FORMAT_Y0Y1Y2Y3: + vcfg |= SC1200_VCFG_UYVY_FORMAT; + vcfg |= SC1200_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y3Y2Y1Y0: + vcfg |= SC1200_VCFG_Y2YU_FORMAT; + vcfg |= SC1200_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y1Y0Y3Y2: + vcfg |= SC1200_VCFG_YUYV_FORMAT; + vcfg |= SC1200_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y1Y2Y3Y0: + vcfg |= SC1200_VCFG_YVYU_FORMAT; + vcfg |= SC1200_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_RGB: + ctrl |= SC1200_VIDEO_INPUT_IS_RGB; + vcfg |= SC1200_VCFG_UYVY_FORMAT; + break; + case VIDEO_FORMAT_P2M_P2L_P1M_P1L: + ctrl |= SC1200_VIDEO_INPUT_IS_RGB; + vcfg |= SC1200_VCFG_Y2YU_FORMAT; + break; + case VIDEO_FORMAT_P1M_P1L_P2M_P2L: + ctrl |= SC1200_VIDEO_INPUT_IS_RGB; + vcfg |= SC1200_VCFG_YUYV_FORMAT; + break; + case VIDEO_FORMAT_P1M_P2L_P2M_P1L: + ctrl |= SC1200_VIDEO_INPUT_IS_RGB; + vcfg |= SC1200_VCFG_YVYU_FORMAT; + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + + /* ALWAYS DISABLE GRAPHICS CSC */ + /* This is enabled in the function gfx_set_color_space_YUV for */ + /* YUV blending on TV. */ + + ctrl &= ~SC1200_CSC_GFX_RGB_TO_YUV; + + if (ctrl & SC1200_VIDEO_INPUT_IS_RGB) + ctrl &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; + else + ctrl |= SC1200_CSC_VIDEO_YUV_TO_RGB; + + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, ctrl); + + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_size + * + * This routine specifies the size of the source data. It is used only + * to determine how much data to transfer per frame, and is not used to + * calculate the scaling value (that is handled by a separate routine). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_size(unsigned short width, unsigned short height) +#else +int +gfx_set_video_size(unsigned short width, unsigned short height) +#endif +{ + unsigned long size, vcfg; + + /* SET THE SC1200 VIDEO LINE SIZE */ + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + vcfg &= ~(SC1200_VCFG_LINE_SIZE_LOWER_MASK | SC1200_VCFG_LINE_SIZE_UPPER); + size = (width >> 1); + vcfg |= (size & 0x00FF) << 8; + if (size & 0x0100) + vcfg |= SC1200_VCFG_LINE_SIZE_UPPER; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + + /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + /* Add 1 line to bypass issue #803 */ + gfx_set_display_video_size(width, (unsigned short)(height + 2)); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_offset + * + * This routine sets the starting offset for the video buffer when only + * one offset needs to be specified. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_offset(unsigned long offset) +#else +int +gfx_set_video_offset(unsigned long offset) +#endif +{ + /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ + + gfx_vid_offset = offset; + + /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_offset(offset); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_upscale + * + * This routine sets the scale factor for the video overlay window. The + * size of the source and destination regions are specified in pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#else +int +gfx_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#endif +{ + unsigned long xscale, yscale; + + /* SAVE PARAMETERS (unless don't-care zero destination arguments are used) */ + /* These are needed for clipping the video window later. */ + + if (dstw != 0) { + gfx_vid_srcw = srcw; + gfx_vid_dstw = dstw; + } + if (dsth != 0) { + gfx_vid_srch = srch; + gfx_vid_dsth = dsth; + } + + /* CALCULATE SC1200 SCALE FACTORS */ + + if (dstw == 0) + xscale = READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff; /* keep previous if don't-care argument */ + else if (dstw <= srcw) + xscale = 0x2000l; /* horizontal downscaling is currently done in a separate function */ + else if ((srcw == 1) || (dstw == 1)) + return GFX_STATUS_BAD_PARAMETER; + else + xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l); + + if (dsth == 0) + yscale = (READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff0000) >> 16; /* keep previous if don't-care argument */ + else if (dsth <= srch) + yscale = 0x2000l; /* No vertical downscaling in SC1200 so force to 1x if attempted */ + else if ((srch == 1) || (dsth == 1)) + return GFX_STATUS_BAD_PARAMETER; + else + yscale = (0x2000l * (srch - 1l)) / (dsth - 1l); + + WRITE_VID32(SC1200_VIDEO_UPSCALE, (yscale << 16) | xscale); + + /* CALL ROUTINE TO UPDATE WINDOW POSITION */ + /* This is required because the scale values effect the number of */ + /* source data pixels that need to be clipped, as well as the */ + /* amount of data that needs to be transferred. */ + + gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width, + gfx_vid_height); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_scale + * + * This routine sets the scale factor for the video overlay window. The + * size of the source and destination regions are specified in pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#else +int +gfx_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#endif +{ + return gfx_set_video_upscale(srcw, srch, dstw, dsth); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_config + * + * This routine sets the downscale type and factor for the video overlay window. + * Note: No downscaling support for RGB565 and YUV420 video formats. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_downscale_config(unsigned short type, unsigned short m) +#else +int +gfx_set_video_downscale_config(unsigned short type, unsigned short m) +#endif +{ + unsigned long downscale; + + if ((m < 1) || (m > 16)) + return GFX_STATUS_BAD_PARAMETER; + + downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); + downscale &= + ~(SC1200_VIDEO_DOWNSCALE_FACTOR_MASK | + SC1200_VIDEO_DOWNSCALE_TYPE_MASK); + downscale |= ((m - 1l) << SC1200_VIDEO_DOWNSCALE_FACTOR_POS); + switch (type) { + case VIDEO_DOWNSCALE_KEEP_1_OF: + downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_A; + break; + case VIDEO_DOWNSCALE_DROP_1_OF: + downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_B; + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_coefficients + * + * This routine sets the downscale filter coefficients. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4) +#else +int +gfx_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4) +#endif +{ + if ((coef1 + coef2 + coef3 + coef4) != 16) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS, + ((unsigned long)coef1 << SC1200_VIDEO_DOWNSCALER_COEF1_POS) | + ((unsigned long)coef2 << SC1200_VIDEO_DOWNSCALER_COEF2_POS) | + ((unsigned long)coef3 << SC1200_VIDEO_DOWNSCALER_COEF3_POS) | + ((unsigned long)coef4 << SC1200_VIDEO_DOWNSCALER_COEF4_POS)); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_enable + * + * This routine enables or disables downscaling for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_downscale_enable(int enable) +#else +int +gfx_set_video_downscale_enable(int enable) +#endif +{ + unsigned long downscale; + + downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); + downscale &= ~SC1200_VIDEO_DOWNSCALE_ENABLE; + if (enable) + downscale |= SC1200_VIDEO_DOWNSCALE_ENABLE; + WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_window + * + * This routine sets the position and size of the video overlay window. The + * y position is specified in screen relative coordinates, and may be negative. + * The size of destination region is specified in pixels. The line size + * indicates the number of bytes of source data per scanline. + * For the effect of negative x values, call the function + * gfx_set_video_left_crop(). + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_window(short x, short y, unsigned short w, unsigned short h) +#else +int +gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) +#endif +{ + unsigned long control; + unsigned long hadjust, vadjust; + unsigned long xstart, ystart, xend, yend; + + /* For left cropping call the function gfx_set_video_left_crop() */ + + if (x < 0) + return GFX_STATUS_BAD_PARAMETER; + + /* SAVE PARAMETERS */ + /* These are needed to call this routine if the scale value changes. */ + /* In the case of SC1200 they are also needed for restoring when video is re-enabled */ + + gfx_vid_xpos = x; + gfx_vid_ypos = y; + gfx_vid_width = w; + gfx_vid_height = h; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 14l; + vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l; + + /* HORIZONTAL START */ + + xstart = (unsigned long)x + hadjust; + + /* HORIZONTAL END */ + /* End positions in register are non-inclusive (one more than the actual end) */ + + if ((x + w) < gfx_get_hactive()) + xend = (unsigned long)x + (unsigned long)w + hadjust; + else /* right clipping needed */ + xend = (unsigned long)gfx_get_hactive() + hadjust; + + /* VERTICAL START */ + + ystart = (unsigned long)y + vadjust; + + /* VERTICAL END */ + + if ((y + h) < gfx_get_vactive()) + yend = (unsigned long)y + (unsigned long)h + vadjust; + else /* bottom clipping needed */ + yend = (unsigned long)gfx_get_vactive() + vadjust; + + /* SET VIDEO LINE INVERT BIT */ + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (y & 0x1) + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + control | SC1200_VIDEO_LINE_OFFSET_ODD); + else + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + control & ~SC1200_VIDEO_LINE_OFFSET_ODD); + + /* SET VIDEO POSITION */ + + WRITE_VID32(SC1200_VIDEO_X_POS, (xend << 16) | xstart); + WRITE_VID32(SC1200_VIDEO_Y_POS, (yend << 16) | ystart); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_left_crop + * + * This routine sets the number of pixels which will be cropped from the + * beginning of each video line. The video window will begin to display only + * from the pixel following the cropped pixels, and the cropped pixels + * will be ignored. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_left_crop(unsigned short x) +#else +int +gfx_set_video_left_crop(unsigned short x) +#endif +{ + unsigned long vcfg, initread; + + /* CLIPPING ON LEFT */ + /* Adjust initial read for scale, checking for divide by zero */ + + if (gfx_vid_dstw) + initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw; + + else + initread = 0l; + + /* SET INITIAL READ ADDRESS */ + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + vcfg &= ~SC1200_VCFG_INIT_READ_MASK; + vcfg |= (initread << 15) & SC1200_VCFG_INIT_READ_MASK; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_color_key + * + * This routine specifies the color key value and mask for the video overlay + * hardware. To disable color key, the color and mask should both be set to + * zero. The hardware uses the color key in the following equation: + * + * ((source data) & (color key mask)) == ((color key) & (color key mask)) + * + * If "graphics" is set to TRUE, the source data is graphics, and color key + * is an RGB value. If "graphics" is set to FALSE, the source data is the video, + * and color key is a YUV value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_color_key(unsigned long key, unsigned long mask, + int graphics) +#else +int +gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) +#endif +{ + unsigned long dcfg = 0; + + /* SET SC1200 COLOR KEY VALUE */ + + WRITE_VID32(SC1200_VIDEO_COLOR_KEY, key); + WRITE_VID32(SC1200_VIDEO_COLOR_MASK, mask); + + /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */ + + dcfg = READ_VID32(SC1200_DISPLAY_CONFIG); + if (graphics & 0x01) + dcfg &= ~SC1200_DCFG_VG_CK; + else + dcfg |= SC1200_DCFG_VG_CK; + WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_filter + * + * This routine enables or disables the video overlay filters. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_filter(int xfilter, int yfilter) +#else +int +gfx_set_video_filter(int xfilter, int yfilter) +#endif +{ + unsigned long vcfg = 0; + + /* ENABLE OR DISABLE SC1200 VIDEO OVERLAY FILTERS */ + + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + vcfg &= ~(SC1200_VCFG_X_FILTER_EN | SC1200_VCFG_Y_FILTER_EN); + if (xfilter) + vcfg |= SC1200_VCFG_X_FILTER_EN; + if (yfilter) + vcfg |= SC1200_VCFG_Y_FILTER_EN; + WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette + * + * This routine loads the video hardware palette. If a NULL pointer is + * specified, the palette is bypassed (for SC1200, this means loading the + * palette with identity values). + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_palette(unsigned long *palette) +#else +int +gfx_set_video_palette(unsigned long *palette) +#endif +{ + unsigned long i, entry; + + /* WAIT FOR VERTICAL BLANK TO END */ + /* Otherwise palette will not be written properly. */ + + if (gfx_test_timing_active()) { + if (gfx_test_vertical_active()) { + while (gfx_test_vertical_active()) ; + } + while (!gfx_test_vertical_active()) ; + } + + /* LOAD SC1200 VIDEO PALETTE */ + + WRITE_VID32(SC1200_PALETTE_ADDRESS, 0); + for (i = 0; i < 256; i++) { + if (palette) + entry = palette[i]; + else + entry = (i << 8) | (i << 16) | (i << 24); + WRITE_VID32(SC1200_PALETTE_DATA, entry); + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette_entry + * + * This routine loads a single entry of the video hardware palette. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_palette_entry(unsigned long index, unsigned long palette) +#else +int +gfx_set_video_palette_entry(unsigned long index, unsigned long palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + /* WAIT FOR VERTICAL BLANK TO END */ + /* Otherwise palette will not be written properly. */ + + if (gfx_test_timing_active()) { + if (gfx_test_vertical_active()) { + while (gfx_test_vertical_active()) ; + } + while (!gfx_test_vertical_active()) ; + } + + /* SET A SINGLE ENTRY */ + + WRITE_VID32(SC1200_PALETTE_ADDRESS, index); + WRITE_VID32(SC1200_PALETTE_DATA, palette); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_request() + * + * This routine sets the horizontal (pixel) and vertical (line) video request + * values. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_request(short x, short y) +#else +int +gfx_set_video_request(short x, short y) +#endif +{ + /* SET SC1200 VIDEO REQUEST */ + + x += gfx_get_htotal() - gfx_get_hsync_end() - 2; + y += gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + if ((x < 0) || (x > SC1200_VIDEO_REQUEST_MASK) || + (y < 0) || (y > SC1200_VIDEO_REQUEST_MASK)) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_VID32(SC1200_VIDEO_REQUEST, + ((unsigned long)x << SC1200_VIDEO_X_REQUEST_POS) | + ((unsigned long)y << SC1200_VIDEO_Y_REQUEST_POS)); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_source() + * + * This routine sets the video source to either memory or Direct VIP. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_source(VideoSourceType source) +#else +int +gfx_set_video_source(VideoSourceType source) +#endif +{ + unsigned long display_mode; + + display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE); + + /* SET SC1200 VIDEO SOURCE */ + switch (source) { + case VIDEO_SOURCE_MEMORY: + WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, + (display_mode & ~SC1200_VIDEO_SOURCE_MASK) | + SC1200_VIDEO_SOURCE_GX1); + break; + case VIDEO_SOURCE_DVIP: + WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, + (display_mode & ~SC1200_VIDEO_SOURCE_MASK) | + SC1200_VIDEO_SOURCE_DVIP); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_source() + * + * This routine sets the vbi source to either memory or Direct VIP. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_vbi_source(VbiSourceType source) +#else +int +gfx_set_vbi_source(VbiSourceType source) +#endif +{ + unsigned long display_mode; + + display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE); + + /* SET SC1200 VBI SOURCE */ + switch (source) { + case VBI_SOURCE_MEMORY: + WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, + (display_mode & ~SC1200_VBI_SOURCE_MASK) | + SC1200_VBI_SOURCE_GX1); + break; + case VBI_SOURCE_DVIP: + WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE, + (display_mode & ~SC1200_VBI_SOURCE_MASK) | + SC1200_VBI_SOURCE_DVIP); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_lines() + * + * This routine sets the VBI lines to pass to the TV encoder. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_vbi_lines(unsigned long even, unsigned long odd) +#else +int +gfx_set_vbi_lines(unsigned long even, unsigned long odd) +#endif +{ + /* SET SC1200 VBI LINES */ + WRITE_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE, + even & SC1200_VIDEO_VBI_LINE_ENABLE_MASK); + WRITE_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE, + odd & SC1200_VIDEO_VBI_LINE_ENABLE_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vbi_total() + * + * This routine sets the total number of VBI bytes for each field. + * The total is needed when both VBI and active video are received from memory. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_vbi_total(unsigned long even, unsigned long odd) +#else +int +gfx_set_vbi_total(unsigned long even, unsigned long odd) +#endif +{ + /* SET SC1200 VBI TOTAL */ + WRITE_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT, + even & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); + WRITE_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT, + odd & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_interlaced() + * + * This routine configures the video processor video overlay mode to be + * interlaced YUV. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_interlaced(int enable) +#else +int +gfx_set_video_interlaced(int enable) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + /* SET INTERLACED VIDEO */ + if (enable) + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + control | SC1200_VIDEO_IS_INTERLACED); + else + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + control & ~SC1200_VIDEO_IS_INTERLACED); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_color_space_YUV() + * + * This routine configures the video processor to process graphics and video + * in either YUV or RGB color space. The mode should be set to tune image + * quality. + * Setting "enable" to TRUE improves image quality on TV, + * but in this mode colors on CRT will not be correct. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_color_space_YUV(int enable) +#else +int +gfx_set_color_space_YUV(int enable) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + + /* SET SC1200 VIDEO COLOR SPACE TO YUV OR RGB */ + + if (enable) { + /* ENABLE YUV BLENDING */ + /* YUV blending cannot be enabled in RGB video formats */ + + control |= SC1200_CSC_GFX_RGB_TO_YUV; /* Convert graphics to YUV */ + control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; /* Leave video in YUV */ + + if (control & SC1200_VIDEO_INPUT_IS_RGB) + return (GFX_STATUS_UNSUPPORTED); /* Can't convert video from RGB to YUV */ + } else { + /* RGB BLENDING */ + + control &= ~SC1200_CSC_GFX_RGB_TO_YUV; /* Leave graphics in RGB */ + if (control & SC1200_VIDEO_INPUT_IS_RGB) + control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; /* Leave video in RGB */ + else + control |= SC1200_CSC_VIDEO_YUV_TO_RGB; /* Convert video to RGB */ + } + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_vertical_scaler_offset() + * + * This routine sets the value by which the odd frame is shifted with respect + * to the even frame. This is useful for de-interlacing in Bob method, by + * setting the shift value to be one line. + * If offset is 0, no shifting occurs. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_vertical_scaler_offset(char offset) +#else +int +gfx_set_vertical_scaler_offset(char offset) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (offset == 1) { + control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK; /* Clear shifting value */ + control |= SC1200_VERTICAL_SCALER_SHIFT_INIT; /* Set shifting value */ + control |= SC1200_VERTICAL_SCALER_SHIFT_EN; /* Enable odd frame shifting */ + } else if (offset == 0) { + control &= ~SC1200_VERTICAL_SCALER_SHIFT_EN; /* No shifting occurs */ + control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK; /* Clear shifting value */ + } else + return (GFX_STATUS_BAD_PARAMETER); /* TODO: how to program other values ? */ + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_top_line_in_odd() + * + * This routine sets the field in which the top line of input video resides. + * If enable is "0", this is the even field (default). [not to be confused + * with the odd field being the top field on TV]. + * If enable is "1", this is the odd field. + * Use enable "1" for input devices whose field indication is reversed from + * normal, i.e. an indication of "odd" field is given for even field data, + * and vice versa. + * This setting affects the video processor only when it is in either interlaced + * or Bob (scaler offset active) modes. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_top_line_in_odd(int enable) +#else +int +gfx_set_top_line_in_odd(int enable) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (enable) + control |= SC1200_TOP_LINE_IN_ODD; /* Set shifting value */ + else + control &= ~SC1200_TOP_LINE_IN_ODD; /* No shifting occurs */ + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_genlock_delay() + * + * This routine sets the delay between VIP VSYNC and display controller VSYNC. + * The delay is in 27 MHz clocks. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_genlock_delay(unsigned long delay) +#else +int +gfx_set_genlock_delay(unsigned long delay) +#endif +{ + /* SET SC1200 GENLOCK DELAY */ + WRITE_VID32(SC1200_GENLOCK_DELAY, delay & SC1200_GENLOCK_DELAY_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_genlock_enable() + * + * This routine sets and configures the genlock according to the flags parameter. + * Flags value of 0 disables genlock and resets its configuration. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_genlock_enable(int flags) +#else +int +gfx_set_genlock_enable(int flags) +#endif +{ + unsigned long genlock = 0; + + if (flags) { + /* SET SC1200 GENLOCK CONFIGURATION */ + if (flags & GENLOCK_SINGLE) + genlock |= SC1200_GENLOCK_SINGLE_ENABLE; + if (flags & GENLOCK_FIELD_SYNC) + genlock |= SC1200_GENLOCK_FIELD_SYNC_ENABLE; + if (flags & GENLOCK_CONTINUOUS) + genlock |= SC1200_GENLOCK_CONTINUOUS_ENABLE; + if (flags & GENLOCK_SYNCED_EDGE_FALLING) + genlock |= SC1200_GENLOCK_GX_VSYNC_FALLING_EDGE; + if (flags & GENLOCK_SYNCING_EDGE_FALLING) + genlock |= SC1200_GENLOCK_VIP_VSYNC_FALLING_EDGE; + if (flags & GENLOCK_TIMEOUT) + genlock |= SC1200_GENLOCK_TIMEOUT_ENABLE; + if (flags & GENLOCK_TVENC_RESET_EVEN_FIELD) + genlock |= SC1200_GENLOCK_TVENC_RESET_EVEN_FIELD; + if (flags & GENLOCK_TVENC_RESET_BEFORE_DELAY) + genlock |= SC1200_GENLOCK_TVENC_RESET_BEFORE_DELAY; + if (flags & GENLOCK_TVENC_RESET) + genlock |= SC1200_GENLOCK_TVENC_RESET_ENABLE; + if (flags & GENLOCK_SYNC_TO_TVENC) + genlock |= SC1200_GENLOCK_SYNC_TO_TVENC; + } + WRITE_VID32(SC1200_GENLOCK, genlock); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_cursor() + * + * This routine configures the video hardware cursor. + * If the "mask"ed bits in the graphics pixel match "key", then either "color1" + * or "color2" will be used for this pixel, according to the value of bit + * number "select_color2" of the graphics pixel. + * + * key - 24 bit RGB value + * mask - 24 bit mask + * color1, color2 - RGB or YUV, depending on the current color space conversion + * select_color2 - value between 0 to 23 + * + * To disable match, a "mask" and "key" value of 0xffffff should be set, + * because the graphics pixels incoming to the video processor have maximum 16 + * bits set (0xF8FCF8). + * + * This feature is useful for disabling alpha blending of the cursor. + * Otherwise cursor image would be blurred (or completely invisible if video + * alpha is maximum value). + * Note: the cursor pixel replacements take place both inside and outside the + * video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, unsigned long color1, + unsigned long color2) +#else +int +gfx_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, unsigned long color1, + unsigned long color2) +#endif +{ + if (select_color2 > SC1200_CURSOR_COLOR_BITS) + return GFX_STATUS_BAD_PARAMETER; + key = (key & SC1200_COLOR_MASK) | ((unsigned long)select_color2 << + SC1200_CURSOR_COLOR_KEY_OFFSET_POS); + WRITE_VID32(SC1200_CURSOR_COLOR_KEY, key); + WRITE_VID32(SC1200_CURSOR_COLOR_MASK, mask); + WRITE_VID32(SC1200_CURSOR_COLOR_1, color1); + WRITE_VID32(SC1200_CURSOR_COLOR_2, color2); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_enable + * + * This routine enables or disables the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_enable(int enable) +#else +int +gfx_set_alpha_enable(int enable) +#endif +{ + unsigned long address = 0, value = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4); + value = READ_VID32(address); + if (enable) + value |= (SC1200_ACTRL_WIN_ENABLE | SC1200_ACTRL_LOAD_ALPHA); + else + value &= ~(SC1200_ACTRL_WIN_ENABLE); + WRITE_VID32(address, value); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_window + * + * This routine sets the size of the currently selected alpha region. + * Note: "x" and "y" are signed to enable using negative values needed for + * implementing workarounds of hardware issues. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_window(short x, short y, + unsigned short width, unsigned short height) +#else +int +gfx_set_alpha_window(short x, short y, + unsigned short width, unsigned short height) +#endif +{ + unsigned long address = 0; + + /* CHECK FOR CLIPPING */ + + if ((x + width) > gfx_get_hactive()) + width = gfx_get_hactive() - x; + if ((y + height) > gfx_get_vactive()) + height = gfx_get_vactive() - y; + + /* ADJUST POSITIONS */ + + x += gfx_get_htotal() - gfx_get_hsync_end() - 2; + y += gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 4); + + /* End positions in register are non-inclusive (one more than the actual end) */ + + WRITE_VID32(address, (unsigned long)x | + ((unsigned long)(x + width) << 16)); + WRITE_VID32(address + 4l, (unsigned long)y | + ((unsigned long)(y + height) << 16)); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_value + * + * This routine sets the alpha value for the currently selected alpha + * region. It also specifies an increment/decrement value for fading. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_value(unsigned char alpha, char delta) +#else +int +gfx_set_alpha_value(unsigned char alpha, char delta) +#endif +{ + unsigned long address = 0, value = 0; + unsigned char new_value = 0; + int loop = 1; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4); + value = READ_VID32(address); + value &= SC1200_ACTRL_WIN_ENABLE; /* keep only enable bit */ + value |= (unsigned long)alpha; + value |= (((unsigned long)delta) & 0xff) << 8; + value |= SC1200_ACTRL_LOAD_ALPHA; + WRITE_VID32(address, value); + + /* WORKAROUND FOR ISSUE #1187 */ + /* Need to verify that the alpha operation succeeded */ + + while (1) { + /* WAIT FOR VERTICAL BLANK TO END */ + if (gfx_test_timing_active()) { + if (gfx_test_vertical_active()) + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + } + new_value = + (unsigned + char)((READ_VID32(SC1200_ALPHA_WATCH) >> (gfx_alpha_select << 3)) + & 0xff); + if (new_value == alpha) + return GFX_STATUS_OK; + if (++loop > 10) + return GFX_STATUS_ERROR; + WRITE_VID32(address, value); + } +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_priority + * + * This routine sets the priority of the currently selected alpha region. + * A higher value indicates a higher priority. + * Note: Priority of enabled alpha windows must be different. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_priority(int priority) +#else +int +gfx_set_alpha_priority(int priority) +#endif +{ + unsigned long pos = 0, value = 0; + + if (priority > 3) + return (GFX_STATUS_BAD_PARAMETER); + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + value = READ_VID32(SC1200_VID_ALPHA_CONTROL); + pos = 16 + (gfx_alpha_select << 1); + value &= ~(0x03l << pos); + value |= (unsigned long)priority << pos; + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, value); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_color + * + * This routine sets the color to be displayed inside the currently selected + * alpha window when there is a color key match (when the alpha color + * mechanism is enabled). + * "color" is a 24 bit RGB value (for RGB blending) or YUV value (for YUV blending). + * In Interlaced YUV blending mode, Y/2 value should be used. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_color(unsigned long color) +#else +int +gfx_set_alpha_color(unsigned long color) +#endif +{ + unsigned long address = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4); + + /* ONLY 24 VALID BITS */ + color &= 0xffffffl; + + /* KEEP UPPER BYTE UNCHANGED */ + WRITE_VID32(address, (color | (READ_VID32(address) & ~0xffffffl))); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_color_enable + * + * Enable or disable the color mechanism in the alpha window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_alpha_color_enable(int enable) +#else +int +gfx_set_alpha_color_enable(int enable) +#endif +{ + unsigned long color; + unsigned long address = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4); + color = READ_VID32(address); + if (enable) + color |= SC1200_ALPHA_COLOR_ENABLE; + else + color &= ~SC1200_ALPHA_COLOR_ENABLE; + WRITE_VID32(address, color); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_no_ck_outside_alpha + * + * This function affects where inside the video window color key or chroma + * key comparison is done: + * If enable is TRUE, color/chroma key comparison is performed only inside + * the enabled alpha windows. Outside the (enabled) alpha windows, only video + * is displayed if color key is used, and only graphics is displayed if chroma + * key is used. + * If enable is FALSE, color/chroma key comparison is performed in all the + * video window area. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_no_ck_outside_alpha(int enable) +#else +int +gfx_set_no_ck_outside_alpha(int enable) +#endif +{ + unsigned long value; + + value = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (enable) + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + value | SC1200_NO_CK_OUTSIDE_ALPHA); + else + WRITE_VID32(SC1200_VID_ALPHA_CONTROL, + value & ~SC1200_NO_CK_OUTSIDE_ALPHA); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_macrovision_enable + * + * This routine enables or disables macrovision on the tv encoder output. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_set_macrovision_enable(int enable) +#else +int +gfx_set_macrovision_enable(int enable) +#endif +{ + if (enable) + WRITE_VID32(SC1200_TVENC_MV_CONTROL, SC1200_TVENC_MV_ENABLE); + else + WRITE_VID32(SC1200_TVENC_MV_CONTROL, 0); + return (GFX_STATUS_OK); +} + +#define SC1200_VIDEO_PCI_44 0x80009444 + +/*--------------------------------------------------------------------------- + * gfx_disable_softvga + * + * Disables SoftVga. This function is only valid with VSA2, Returns 1 if + * SoftVga can be disabled; 0 if not. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_disable_softvga(void) +#else +int +gfx_disable_softvga(void) +#endif +{ + unsigned long reg_val; + + /* get the current value */ + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + /* setting video PCI register 44 bit 0 to 1 disables SoftVga */ + reg_val |= 0x1; + gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val); + + /* see if we set the bit and return the appropriate value */ + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0x1) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_enable_softvga + * + * Enables SoftVga. This function is only valid with VSA2, Returns 1 if + * SoftVga can be enbled; 0 if not. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_enable_softvga(void) +#else +int +gfx_enable_softvga(void) +#endif +{ + unsigned long reg_val; + + /* get the current value */ + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + /* clearing video PCI register 44 bit 0 enables SoftVga */ + gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val & 0xfffffffel); + + /* see if we cleared the bit and return the appropriate value */ + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_clock_frequency + * + * This routine returns the current clock frequency in 16.16 format. + * It reads the current register value and finds the match in the table. + * If no match is found, this routine returns 0. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_clock_frequency(void) +#else +unsigned long +gfx_get_clock_frequency(void) +#endif +{ + unsigned int index; + unsigned long value, mask; + + mask = 0x007FFF0F; + value = READ_VID32(SC1200_VID_CLOCK_SELECT) & mask; + for (index = 0; index < NUM_SC1200_FREQUENCIES; index++) { + if ((gfx_sc1200_clock_table[index].clock_select & mask) == value) + return (gfx_sc1200_clock_table[index].frequency); + } + return (0); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*--------------------------------------------------------------------------- + * gfx_get_vsa2_softvga_enable + * + * This function returns the enable status of SoftVGA. It is valid + * only if VSAII is present. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_vsa2_softvga_enable(void) +#else +int +gfx_get_vsa2_softvga_enable(void) +#endif +{ + unsigned long reg_val; + + reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0) + return (1); + else + return (0); + +} + +/*--------------------------------------------------------------------------- + * gfx_get_sync_polarities + * + * This routine returns the polarities of the sync pulses: + * Bit 0: Set if negative horizontal polarity. + * Bit 1: Set if negative vertical polarity. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_sync_polarities(void) +#else +int +gfx_get_sync_polarities(void) +#endif +{ + int polarities = 0; + + if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_HSYNC_POL) + polarities |= 1; + if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_VSYNC_POL) + polarities |= 2; + return (polarities); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_palette_entry + * + * This routine returns a single palette entry. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_palette_entry(unsigned long index, unsigned long *palette) +#else +int +gfx_get_video_palette_entry(unsigned long index, unsigned long *palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + /* READ A SINGLE ENTRY */ + + WRITE_VID32(SC1200_PALETTE_ADDRESS, index); + *palette = READ_VID32(SC1200_PALETTE_DATA); + + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_enable + * + * This routine returns the value "one" if video overlay is currently enabled, + * otherwise it returns the value "zero". + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_enable(void) +#else +int +gfx_get_video_enable(void) +#endif +{ + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_VID_EN) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_format + * + * This routine returns the current video overlay format. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_format(void) +#else +int +gfx_get_video_format(void) +#endif +{ + unsigned long ctrl, vcfg; + + ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL); + vcfg = READ_VID32(SC1200_VIDEO_CONFIG); + + if (ctrl & SC1200_VIDEO_INPUT_IS_RGB) { + switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { + case SC1200_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_RGB; + case SC1200_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_P2M_P2L_P1M_P1L; + case SC1200_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_P1M_P1L_P2M_P2L; + case SC1200_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_P1M_P2L_P2M_P1L; + } + } + + if (vcfg & SC1200_VCFG_4_2_0_MODE) { + switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { + case SC1200_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_Y0Y1Y2Y3; + case SC1200_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_Y3Y2Y1Y0; + case SC1200_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_Y1Y0Y3Y2; + case SC1200_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_Y1Y2Y3Y0; + } + } else { + switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) { + case SC1200_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_UYVY; + case SC1200_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_Y2YU; + case SC1200_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_YUYV; + case SC1200_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_YVYU; + } + } + return (GFX_STATUS_ERROR); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_src_size + * + * This routine returns the size of the source video overlay buffer. The + * return value is (height << 16) | width. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_src_size(void) +#else +unsigned long +gfx_get_video_src_size(void) +#endif +{ + unsigned long width = 0, height = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ + + width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER) + width += 512l; + + if (width) { + /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */ + /* Get total size from display controller - abtracted. */ + + height = gfx_get_display_video_size() / (width << 1); + } + return ((height << 16) | width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_line_size + * + * This routine returns the line size of the source video overlay buffer, in + * pixels. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_line_size(void) +#else +unsigned long +gfx_get_video_line_size(void) +#endif +{ + unsigned long width = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ + + width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER) + width += 512l; + return (width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_xclip + * + * This routine returns the number of bytes clipped on the left side of a + * video overlay line (skipped at beginning). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_xclip(void) +#else +unsigned long +gfx_get_video_xclip(void) +#endif +{ + unsigned long clip = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */ + + clip = (READ_VID32(SC1200_VIDEO_CONFIG) >> 14) & 0x000007FC; + return (clip); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_offset + * + * This routine returns the current offset for the video overlay buffer. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_offset(void) +#else +unsigned long +gfx_get_video_offset(void) +#endif +{ + return (gfx_get_display_video_offset()); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_upscale + * + * This routine returns the scale factor for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_upscale(void) +#else +unsigned long +gfx_get_video_upscale(void) +#endif +{ + return (READ_VID32(SC1200_VIDEO_UPSCALE)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_scale + * + * This routine returns the scale factor for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_scale(void) +#else +unsigned long +gfx_get_video_scale(void) +#endif +{ + return gfx_get_video_upscale(); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_config + * + * This routine returns the current type and value of video downscaling. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_downscale_config(unsigned short *type, unsigned short *m) +#else +int +gfx_get_video_downscale_config(unsigned short *type, unsigned short *m) +#endif +{ + unsigned long downscale; + + downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL); + *m = (unsigned short)((downscale & SC1200_VIDEO_DOWNSCALE_FACTOR_MASK) >> + SC1200_VIDEO_DOWNSCALE_FACTOR_POS) + 1; + + switch (downscale & SC1200_VIDEO_DOWNSCALE_TYPE_MASK) { + case SC1200_VIDEO_DOWNSCALE_TYPE_A: + *type = VIDEO_DOWNSCALE_KEEP_1_OF; + break; + case SC1200_VIDEO_DOWNSCALE_TYPE_B: + *type = VIDEO_DOWNSCALE_DROP_1_OF; + break; + default: + return GFX_STATUS_ERROR; + break; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_coefficients + * + * This routine returns the current video downscaling coefficients. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4) +#else +void +gfx_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4) +#endif +{ + unsigned long coef; + + coef = READ_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS); + *coef1 = + (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF1_POS) & + SC1200_VIDEO_DOWNSCALER_COEF_MASK); + *coef2 = + (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF2_POS) & + SC1200_VIDEO_DOWNSCALER_COEF_MASK); + *coef3 = + (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF3_POS) & + SC1200_VIDEO_DOWNSCALER_COEF_MASK); + *coef4 = + (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF4_POS) & + SC1200_VIDEO_DOWNSCALER_COEF_MASK); + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_enable + * + * This routine returns 1 if video downscaling is currently enabled, + * or 0 if it is currently disabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_video_downscale_enable(int *enable) +#else +void +gfx_get_video_downscale_enable(int *enable) +#endif +{ + if (READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL) & + SC1200_VIDEO_DOWNSCALE_ENABLE) + *enable = 1; + else + *enable = 0; + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_dst_size + * + * This routine returns the size of the displayed video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_dst_size(void) +#else +unsigned long +gfx_get_video_dst_size(void) +#endif +{ + unsigned long xsize, ysize; + + xsize = READ_VID32(SC1200_VIDEO_X_POS); + xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF); + ysize = READ_VID32(SC1200_VIDEO_Y_POS); + ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF); + return ((ysize << 16) | xsize); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_position + * + * This routine returns the position of the video overlay window. The + * return value is (ypos << 16) | xpos. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_position(void) +#else +unsigned long +gfx_get_video_position(void) +#endif +{ + unsigned long hadjust, vadjust; + unsigned long xpos, ypos; + + /* READ HARDWARE POSITION */ + + xpos = READ_VID32(SC1200_VIDEO_X_POS) & 0x000007FF; + ypos = READ_VID32(SC1200_VIDEO_Y_POS) & 0x000007FF; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = + (unsigned long)gfx_get_htotal() - + (unsigned long)gfx_get_hsync_end() - 14l; + vadjust = + (unsigned long)gfx_get_vtotal() - + (unsigned long)gfx_get_vsync_end() + 1l; + xpos -= hadjust; + ypos -= vadjust; + return ((ypos << 16) | (xpos & 0x0000FFFF)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key + * + * This routine returns the current video color key value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_color_key(void) +#else +unsigned long +gfx_get_video_color_key(void) +#endif +{ + return (READ_VID32(SC1200_VIDEO_COLOR_KEY)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_mask + * + * This routine returns the current video color mask value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_video_color_key_mask(void) +#else +unsigned long +gfx_get_video_color_key_mask(void) +#endif +{ + return (READ_VID32(SC1200_VIDEO_COLOR_MASK)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_src + * + * This routine returns 0 for video data compare, 1 for graphics data. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_color_key_src(void) +#else +int +gfx_get_video_color_key_src(void) +#endif +{ + if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_VG_CK) + return (0); + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_filter + * + * This routine returns if the filters are currently enabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_filter(void) +#else +int +gfx_get_video_filter(void) +#endif +{ + int retval = 0; + + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_X_FILTER_EN) + retval |= 1; + if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_Y_FILTER_EN) + retval |= 2; + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_request + * + * This routine returns the horizontal (pixel) and vertical (lines) video + * request values. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_request(short *x, short *y) +#else +int +gfx_get_video_request(short *x, short *y) +#endif +{ + int request = 0; + + request = (int)(READ_VID32(SC1200_VIDEO_REQUEST)); + *x = (request >> SC1200_VIDEO_X_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK; + *y = (request >> SC1200_VIDEO_Y_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK; + + *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2; + *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_source + * + * This routine returns the current video source. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_source(VideoSourceType * source) +#else +int +gfx_get_video_source(VideoSourceType * source) +#endif +{ + switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VIDEO_SOURCE_MASK) { + case SC1200_VIDEO_SOURCE_GX1: + *source = VIDEO_SOURCE_MEMORY; + break; + case SC1200_VIDEO_SOURCE_DVIP: + *source = VIDEO_SOURCE_DVIP; + break; + default: + return GFX_STATUS_ERROR; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_source + * + * This routine returns the current vbi source. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_vbi_source(VbiSourceType * source) +#else +int +gfx_get_vbi_source(VbiSourceType * source) +#endif +{ + switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VBI_SOURCE_MASK) { + case SC1200_VBI_SOURCE_GX1: + *source = VBI_SOURCE_MEMORY; + break; + case SC1200_VBI_SOURCE_DVIP: + *source = VBI_SOURCE_DVIP; + break; + default: + return GFX_STATUS_ERROR; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_lines + * + * This routine returns the VBI lines which are sent to the TV encoder. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_vbi_lines(int odd) +#else +unsigned long +gfx_get_vbi_lines(int odd) +#endif +{ + if (odd) + return (READ_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE) & + SC1200_VIDEO_VBI_LINE_ENABLE_MASK); + return (READ_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE) & + SC1200_VIDEO_VBI_LINE_ENABLE_MASK); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vbi_total + * + * This routine returns the total number of VBI bytes in the field. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_vbi_total(int odd) +#else +unsigned long +gfx_get_vbi_total(int odd) +#endif +{ + if (odd) + return (READ_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT) & + SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); + return (READ_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT) & + SC1200_VIDEO_VBI_TOTAL_COUNT_MASK); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_interlaced() + * + * This routine returns "1" if input video is currently in interlaced mode. + * "0" otherwise. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_interlaced(void) +#else +int +gfx_get_video_interlaced(void) +#endif +{ + if (READ_VID32(SC1200_VID_ALPHA_CONTROL) & SC1200_VIDEO_IS_INTERLACED) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_color_space_YUV() + * + * This routine returns "1" if video processor color space mode is currently + * YUV. "0" otherwise. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_color_space_YUV(void) +#else +int +gfx_get_color_space_YUV(void) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + + /* IS SC1200 VIDEO COLOR SPACE RGB OR CONVERTED TO RGB */ + if ((control & SC1200_VIDEO_INPUT_IS_RGB) + || (control & SC1200_CSC_VIDEO_YUV_TO_RGB)) + return (0); + else + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_get_vertical_scaler_offset() + * + * This routine sets "offset" to the value by which odd frames are shifted, + * if insert is enabled, and to 0 if no shifting occurs. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_vertical_scaler_offset(char *offset) +#else +int +gfx_get_vertical_scaler_offset(char *offset) +#endif +{ + unsigned long control; + + control = READ_VID32(SC1200_VID_ALPHA_CONTROL); + if (control & SC1200_VERTICAL_SCALER_SHIFT_EN) { + if ((control & SC1200_VERTICAL_SCALER_SHIFT_MASK) == + SC1200_VERTICAL_SCALER_SHIFT_INIT) + *offset = 1; + else + return GFX_STATUS_ERROR; /* TODO: find the interpretation of other values */ + } else + *offset = 0; + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_genlock_delay + * + * This routine returns the genlock delay in 27 MHz clocks. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_get_genlock_delay(void) +#else +unsigned long +gfx_get_genlock_delay(void) +#endif +{ + return (READ_VID32(SC1200_GENLOCK_DELAY) & SC1200_GENLOCK_DELAY_MASK); +} + +/*--------------------------------------------------------------------------- + * gfx_get_genlock_enable + * + * This routine returns "1" if genlock is currently enabled, "0" otherwise. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_genlock_enable(void) +#else +int +gfx_get_genlock_enable(void) +#endif +{ + if (READ_VID32(SC1200_GENLOCK) & + (SC1200_GENLOCK_SINGLE_ENABLE | SC1200_GENLOCK_CONTINUOUS_ENABLE)) + return (1); + else + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_cursor() + * + * This routine configures the video hardware cursor. + * If the "mask"ed bits in the graphics pixel match "key", then either "color1" + * or "color2" will be used for this pixel, according to the value of the bit + * in offset "select_color2". + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, unsigned long *color1, + unsigned short *color2) +#else +int +gfx_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, unsigned long *color1, + unsigned short *color2) +#endif +{ + *select_color2 = + (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_KEY) >> + SC1200_CURSOR_COLOR_KEY_OFFSET_POS); + *key = READ_VID32(SC1200_CURSOR_COLOR_KEY) & SC1200_COLOR_MASK; + *mask = READ_VID32(SC1200_CURSOR_COLOR_MASK) & SC1200_COLOR_MASK; + *color1 = READ_VID32(SC1200_CURSOR_COLOR_1) & SC1200_COLOR_MASK; + *color2 = + (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_2) & + SC1200_COLOR_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_read_crc + * + * This routine returns the hardware CRC value, which is used for automated + * testing. The value is like a checksum, but will change if pixels move + * locations. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1200_read_crc(void) +#else +unsigned long +gfx_read_crc(void) +#endif +{ + unsigned long crc = 0xFFFFFFFF; + + if (gfx_test_timing_active()) { + /* WAIT UNTIL ACTIVE DISPLAY */ + + while (!gfx_test_vertical_active()) ; + + /* RESET CRC DURING ACTIVE DISPLAY */ + + WRITE_VID32(SC1200_VID_CRC, 0); + WRITE_VID32(SC1200_VID_CRC, 1); + + /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */ + + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + crc = READ_VID32(SC1200_VID_CRC) >> 8; + } + return (crc); +} + +/*----------------------------------------------------------------------------- + * gfx_get_macrovision_enable + * + * This routine returns the value "one" if macrovision currently enabled in the + * TV encoder, otherwise it returns the value "zero". + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1200_get_macrovision_enable(void) +#else +int +gfx_get_macrovision_enable(void) +#endif +{ + if (READ_VID32(SC1200_TVENC_MV_CONTROL) == SC1200_TVENC_MV_ENABLE) + return (1); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_enable + * + * This routine returns 1 if the selected alpha window is currently + * enabled, or 0 if it is currently disabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_enable(int *enable) +#else +void +gfx_get_alpha_enable(int *enable) +#endif +{ + unsigned long value = 0; + + *enable = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(SC1200_ALPHA_CONTROL_1 + + ((unsigned long)gfx_alpha_select << 4)); + if (value & SC1200_ACTRL_WIN_ENABLE) + *enable = 1; + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_size + * + * This routine returns the size of the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height) +#else +void +gfx_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height) +#endif +{ + unsigned long value = 0; + + *x = 0; + *y = 0; + *width = 0; + *height = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(SC1200_ALPHA_XPOS_1 + + ((unsigned long)gfx_alpha_select << 4)); + *x = (unsigned short)(value & 0x000007FF); + *width = (unsigned short)((value >> 16) & 0x000007FF) - *x; + value = + READ_VID32(SC1200_ALPHA_YPOS_1 + + ((unsigned long)gfx_alpha_select << 4)); + *y = (unsigned short)(value & 0x000007FF); + *height = (unsigned short)((value >> 16) & 0x000007FF) - *y; + } + *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2; + *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1; + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_value + * + * This routine returns the alpha value and increment/decrement value of + * the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_value(unsigned char *alpha, char *delta) +#else +void +gfx_get_alpha_value(unsigned char *alpha, char *delta) +#endif +{ + unsigned long value = 0; + + *alpha = 0; + *delta = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(SC1200_ALPHA_CONTROL_1 + + ((unsigned long)gfx_alpha_select << 4)); + *alpha = (unsigned char)(value & 0x00FF); + *delta = (char)((value >> 8) & 0x00FF); + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_priority + * + * This routine returns the priority of the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_priority(int *priority) +#else +void +gfx_get_alpha_priority(int *priority) +#endif +{ + unsigned long pos = 0, value = 0; + + *priority = 0; + if (gfx_alpha_select <= 2) { + value = READ_VID32(SC1200_VID_ALPHA_CONTROL); + pos = 16 + (gfx_alpha_select << 1); + *priority = (int)((value >> pos) & 3); + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_color + * + * This routine returns the color register value for the currently selected + * alpha region. Bit 24 is set if the color register is enabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1200_get_alpha_color(unsigned long *color) +#else +void +gfx_get_alpha_color(unsigned long *color) +#endif +{ + *color = 0; + if (gfx_alpha_select <= 2) { + *color = + READ_VID32(SC1200_ALPHA_COLOR_1 + + ((unsigned long)gfx_alpha_select << 4)); + } + return; +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1400.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1400.c new file mode 100644 index 000000000..11f936160 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1400.c @@ -0,0 +1,924 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1400.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/*----------------------------------------------------------------------------- + * VID_1400.C + * + * Version 2.0 - February 21, 2000 + * + * This file contains routines to control the SC1400 video overlay hardware. + * + * History: + * Versions 0.1 through 2.0 by Brian Falardeau. + * + * Copyright (c) 1999-2000 National Semiconductor. + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * SC1400 PLL TABLE + *---------------------------------------------------------------------------- + */ + +typedef struct tagSC1400PLL +{ + long frequency; /* 16.16 fixed point frequency */ + unsigned long clock_select; /* clock select register (0x2C) */ +} +SC1400PLL; + +SC1400PLL gfx_sc1400_clock_table[] = { + {0x00192CCC, 0x00000000}, /* 25.1750 */ + {0x001C526E, 0x00010000}, /* 28.3220 */ + {0x001F8000, 0x00020000}, /* 31.5000 */ + {0x00240000, 0x000E0000}, /* 36.0000 */ + {0x00258000, 0x0010110C}, /* 37.5000 */ + {0x00280000, 0x00040000}, /* 40.0000 */ + {0x002CE666, 0x00090000}, /* 44.9000 */ + {0x00320000, 0x00100C06}, /* 50.0000 */ + {0x00325999, 0x0050600C}, /* 50.3500 */ + {0x00360000, 0x00100100}, /* 54.0000 */ + {0x0038643F, 0x0010160A}, /* 56.3916 */ + {0x0038A3D7, 0x00506C0C}, /* 56.6440 */ + {0x003B0000, 0x0010170A}, /* 59.6583 */ + {0x003BA886, 0x00100A04}, /* 59.6583 */ + {0x003F0000, 0x00100602}, /* 63.0000 */ + {0x00410000, 0x00060000}, /* 65.0000 */ + {0x00438000, 0x00100401}, /* 67.5000 */ + {0x0046CCCC, 0x00101407}, /* 70.8000 */ + {0x00480000, 0x00100702}, /* 72.0000 */ + {0x004B0000, 0x00070000}, /* 75.0000 */ + {0x004EC000, 0x0010220B}, /* 78.7500 */ + {0x00500000, 0x00304C0C}, /* 80.0000 */ + {0x00510000, 0x00100200}, /* 81.0000 */ + {0x00550000, 0x00080000}, /* 85.0000 */ + {0x0059CCCC, 0x00100902}, /* 89.8000 */ + {0x00630000, 0x00100A02}, /* 99.0000 */ + {0x00640000, 0x00102409}, /* 100.0000 */ + {0x006C0000, 0x00100300}, /* 108.0000 */ + {0x00870000, 0x00050000}, /* 135.0000 */ + {0x009D8000, 0x00102205}, /* 157.5000 */ + {0x00A20000, 0x00100500}, /* 162.0000 */ + {0x00AA0000, 0x000B0000}, /* 170.0000 */ + {0x00AF0000, 0x00100C01}, /* 175.0000 */ + {0x00BD0000, 0x00100600}, /* 189.0000 */ + {0x00CA0000, 0x00100E01}, /* 202.0000 */ + {0x00E80000, 0x00102A04}, /* 232.0000 */ +}; + +#define NUM_SC1400_FREQUENCIES sizeof(gfx_sc1400_clock_table)/sizeof(SC1400PLL) + +/*--------------------------------------------------------------------------- + * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine is used to disable all components of video overlay before + * performing a mode switch. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1400_reset_video(void) +#else +void +gfx_reset_video(void) +#endif +{ + gfx_set_video_enable(0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_clock_frequency + * + * This routine sets the clock frequency, specified as a 16.16 fixed point + * value (0x00318000 = 49.5 MHz). It will set the closest frequency found + * in the lookup table. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +sc1400_set_clock_frequency(unsigned long frequency) +#else +void +gfx_set_clock_frequency(unsigned long frequency) +#endif +{ + int index; + unsigned long value; + long min, diff; + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + value = gfx_sc1400_clock_table[0].clock_select; + min = (long)gfx_sc1400_clock_table[0].frequency - frequency; + if (min < 0L) + min = -min; + for (index = 1; index < NUM_SC1400_FREQUENCIES; index++) { + diff = (long)gfx_sc1400_clock_table[index].frequency - frequency; + if (diff < 0L) + diff = -diff; + if (diff < min) { + min = diff; + value = gfx_sc1400_clock_table[index].clock_select; + } + } + + /* SET THE DOT CLOCK REGISTER */ + + WRITE_VID32(SC1400_VID_MISC, 0x00001000); + WRITE_VID32(SC1400_VID_CLOCK_SELECT, value); + return; +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_enable + * + * This routine enables or disables the video overlay functionality. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_enable(int enable) +#else +int +gfx_set_video_enable(int enable) +#endif +{ + unsigned long vcfg; + + /* WAIT FOR VERTICAL BLANK TO START */ + /* Otherwise a glitch can be observed. */ + + if (gfx_test_timing_active()) { + if (!gfx_test_vertical_active()) { + while (!gfx_test_vertical_active()) ; + } + while (gfx_test_vertical_active()) ; + } + vcfg = READ_VID32(SC1400_VIDEO_CONFIG); + if (enable) { + /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(1); + + /* SET SC1400 BUS CONTROL PARAMETERS */ + /* Currently always high speed, 8-bit interface. */ + + vcfg |= SC1400_VCFG_HIGH_SPD_INT; + vcfg &= ~(SC1400_VCFG_EARLY_VID_RDY | SC1400_VCFG_16_BIT_EN); + + /* ENABLE SC1400 VIDEO OVERLAY */ + + vcfg |= SC1400_VCFG_VID_EN; + WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); + } else { + /* DISABLE SC1400 VIDEO OVERLAY */ + + vcfg &= ~SC1400_VCFG_VID_EN; + WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); + + /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(0); + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_format + * + * Currently only sets 4:2:0 format, Y1 V Y0 U. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_format(unsigned long format) +#else +int +gfx_set_video_format(unsigned long format) +#endif +{ + unsigned long vcfg = 0; + + /* SET THE SC1400 VIDEO INPUT FORMAT */ + + vcfg = READ_VID32(SC1400_VIDEO_CONFIG); + vcfg &= ~(SC1400_VCFG_VID_INP_FORMAT | SC1400_VCFG_4_2_0_MODE); + vcfg &= ~(SC1400_VCFG_CSC_BYPASS); + if (format < 4) + vcfg |= (format << 2); + else + vcfg |= SC1400_VCFG_CSC_BYPASS; + WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_size + * + * This routine specifies the size of the source data. It is used only + * to determine how much data to transfer per frame, and is not used to + * calculate the scaling value (that is handled by a separate routine). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_size(unsigned short width, unsigned short height) +#else +int +gfx_set_video_size(unsigned short width, unsigned short height) +#endif +{ + unsigned long size, vcfg; + + /* SET THE SC1400 VIDEO LINE SIZE */ + + vcfg = READ_VID32(SC1400_VIDEO_CONFIG); + vcfg &= ~(SC1400_VCFG_LINE_SIZE_LOWER_MASK | SC1400_VCFG_LINE_SIZE_UPPER); + size = (width >> 1); + vcfg |= (size & 0x00FF) << 8; + if (size & 0x0100) + vcfg |= SC1400_VCFG_LINE_SIZE_UPPER; + WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); + + /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_size(width, height); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_offset + * + * This routine sets the starting offset for the video buffer when only + * one offset needs to be specified. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_offset(unsigned long offset) +#else +int +gfx_set_video_offset(unsigned long offset) +#endif +{ + /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ + + gfx_vid_offset = offset; + + /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_offset(offset); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_scale + * + * This routine sets the scale factor for the video overlay window. The + * size of the source and destination regions are specified in pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#else +int +gfx_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#endif +{ + unsigned long xscale, yscale; + + /* SAVE PARAMETERS */ + /* These are needed for clipping the video window later. */ + + gfx_vid_srcw = srcw; + gfx_vid_srch = srch; + gfx_vid_dstw = dstw; + gfx_vid_dsth = dsth; + + /* CALCULATE SC1400 SCALE FACTORS */ + /* No downscaling in SC1400 so force to 1x if attempted. */ + + if (srcw < dstw) + xscale = (0x2000 * (srcw - 1)) / (dstw - 1); + else + xscale = 0x1FFF; + if (srch < dsth) + yscale = (0x2000 * (srch - 1)) / (dsth - 1); + else + yscale = 0x1FFF; + WRITE_VID32(SC1400_VIDEO_SCALE, (yscale << 16) | xscale); + + /* CALL ROUTINE TO UPDATE WINDOW POSITION */ + /* This is required because the scale values effect the number of */ + /* source data pixels that need to be clipped, as well as the */ + /* amount of data that needs to be transferred. */ + + gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width, + gfx_vid_height); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_window + * + * This routine sets the position and size of the video overlay window. The + * position is specified in screen relative coordinates, and may be negative. + * The size of destination region is specified in pixels. The line size + * indicates the number of bytes of source data per scanline. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_window(short x, short y, unsigned short w, unsigned short h) +#else +int +gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) +#endif +{ + unsigned long vcfg = 0; + unsigned long hadjust, vadjust; + unsigned long initread; + unsigned long xstart, ystart, xend, yend; + unsigned long offset, line_size; + + /* SAVE PARAMETERS */ + /* These are needed to call this routine if the scale value changes. */ + + gfx_vid_xpos = x; + gfx_vid_ypos = y; + gfx_vid_width = w; + gfx_vid_height = h; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13; + vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + if (x > 0) { + /* NO CLIPPING ON LEFT */ + + xstart = x + hadjust; + initread = 0; + } else { + /* CLIPPING ON LEFT */ + /* Adjust initial read for scale, checking for divide by zero */ + + xstart = hadjust; + initread = -x; + if (gfx_vid_dstw) + initread = ((-x) * gfx_vid_srcw) / gfx_vid_dstw; + else + initread = 0; + } + + /* CLIPPING ON RIGHT */ + + xend = x + w; + if (xend > gfx_get_hactive()) + xend = gfx_get_hactive(); + xend += hadjust; + + /* CLIPPING ON TOP */ + + offset = gfx_vid_offset; + if (y >= 0) { + ystart = y + vadjust; + } else { + ystart = vadjust; + line_size = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) + line_size += 512; + if (gfx_vid_dsth) + offset = gfx_vid_offset + (line_size << 1) * + (((-y) * gfx_vid_srch) / gfx_vid_dsth); + } + + /* CLIPPING ON BOTTOM */ + + yend = y + h; + if (yend >= gfx_get_vactive()) + yend = gfx_get_vactive(); + yend += vadjust; + + /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_offset(offset); + + /* DISABLE REGISTER UPDATES */ + + vcfg = READ_VID32(SC1400_VIDEO_CONFIG); + vcfg &= ~SC1400_VCFG_VID_REG_UPDATE; + WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); + + /* SET VIDEO POSITION */ + + WRITE_VID32(SC1400_VIDEO_X_POS, (xend << 16) | xstart); + WRITE_VID32(SC1400_VIDEO_Y_POS, (yend << 16) | ystart); + + /* SET INITIAL READ ADDRESS AND ENABLE REGISTER UPDATES */ + + vcfg &= ~SC1400_VCFG_INIT_READ_MASK; + vcfg |= (initread << 15) & SC1400_VCFG_INIT_READ_MASK; + vcfg |= SC1400_VCFG_VID_REG_UPDATE; + WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_color_key + * + * This routine specifies the color key value and mask for the video overlay + * hardware. To disable color key, the color and mask should both be set to + * zero. The hardware uses the color key in the following equation: + * + * ((source data) & (color key mask)) == ((color key) & (color key mask)) + * + * The source data can be either graphics data or video data. The bluescreen + * parameter is set to have the hardware compare video data and clear to + * comapare graphics data. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_color_key(unsigned long key, unsigned long mask, + int graphics) +#else +int +gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) +#endif +{ + unsigned long dcfg = 0; + + /* SET SC1400 COLOR KEY VALUE */ + + WRITE_VID32(SC1400_VIDEO_COLOR_KEY, key); + WRITE_VID32(SC1400_VIDEO_COLOR_MASK, mask); + + /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */ + + dcfg = READ_VID32(SC1400_DISPLAY_CONFIG); + if (graphics & 0x01) + dcfg &= ~SC1400_DCFG_VG_CK; + else + dcfg |= SC1400_DCFG_VG_CK; + WRITE_VID32(SC1400_DISPLAY_CONFIG, dcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_filter + * + * This routine enables or disables the video overlay filters. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_filter(int xfilter, int yfilter) +#else +int +gfx_set_video_filter(int xfilter, int yfilter) +#endif +{ + unsigned long vcfg = 0; + + /* ENABLE OR DISABLE SC1400 VIDEO OVERLAY FILTERS */ + + vcfg = READ_VID32(SC1400_VIDEO_CONFIG); + vcfg &= ~(SC1400_VCFG_X_FILTER_EN | SC1400_VCFG_Y_FILTER_EN); + if (xfilter) + vcfg |= SC1400_VCFG_X_FILTER_EN; + if (yfilter) + vcfg |= SC1400_VCFG_Y_FILTER_EN; + WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette + * + * This routine loads the video hardware palette. If a NULL pointer is + * specified, the palette is bypassed (for SC1400, this means loading the + * palette with identity values). + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_video_palette(unsigned long *palette) +#else +int +gfx_set_video_palette(unsigned long *palette) +#endif +{ + unsigned long i, entry; + + /* LOAD SC1400 VIDEO PALETTE */ + + WRITE_VID32(SC1400_PALETTE_ADDRESS, 0); + for (i = 0; i < 256; i++) { + if (palette) + entry = palette[i]; + else + entry = i | (i << 8) | (i << 16); + WRITE_VID32(SC1400_PALETTE_DATA, entry); + } + return (0); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*--------------------------------------------------------------------------- + * gfx_get_sync_polarities + * + * This routine returns the polarities of the sync pulses: + * Bit 0: Set if negative horizontal polarity. + * Bit 1: Set if negative vertical polarity. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_get_sync_polarities(void) +#else +int +gfx_get_sync_polarities(void) +#endif +{ + int polarities = 0; + + if (READ_VID32(SC1400_DISPLAY_CONFIG) & 0x00000100) + polarities |= 1; + if (READ_VID32(SC1400_DISPLAY_CONFIG) & 0x00000200) + polarities |= 2; + return (polarities); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_enable + * + * This routine returns the value "one" if video overlay is currently enabled, + * otherwise it returns the value "zero". + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_get_video_enable(void) +#else +int +gfx_get_video_enable(void) +#endif +{ + if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_VID_EN) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_format + * + * This routine returns the current video overlay format. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_get_video_format(void) +#else +int +gfx_get_video_format(void) +#endif +{ + unsigned long vcfg; + + vcfg = READ_VID32(SC1400_VIDEO_CONFIG); + if (vcfg & SC1400_VCFG_CSC_BYPASS) + return (4); + else + return ((vcfg >> 2) & 3); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_src_size + * + * This routine returns the size of the source video overlay buffer. The + * return value is (height << 16) | width. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_src_size(void) +#else +unsigned long +gfx_get_video_src_size(void) +#endif +{ + unsigned long width = 0, height = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ + + width = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) + width += 512; + + if (width) { + /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */ + /* Get total size from display controller - abtracted. */ + + height = gfx_get_display_video_size() / (width << 1); + } + return ((height << 16) | width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_line_size + * + * This routine returns the line size of the source video overlay buffer, in + * pixels. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_line_size(void) +#else +unsigned long +gfx_get_video_line_size(void) +#endif +{ + unsigned long width = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ + + width = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) + width += 512; + return (width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_xclip + * + * This routine returns the number of bytes clipped on the left side of a + * video overlay line (skipped at beginning). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_xclip(void) +#else +unsigned long +gfx_get_video_xclip(void) +#endif +{ + unsigned long clip = 0; + + /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ + + clip = (READ_VID32(SC1400_VIDEO_CONFIG) >> 14) & 0x000007FC; + return (clip); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_offset + * + * This routine returns the current offset for the video overlay buffer. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_offset(void) +#else +unsigned long +gfx_get_video_offset(void) +#endif +{ + return (gfx_get_display_video_offset()); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_scale + * + * This routine returns the scale factor for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_scale(void) +#else +unsigned long +gfx_get_video_scale(void) +#endif +{ + return (READ_VID32(SC1400_VIDEO_SCALE)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_dst_size + * + * This routine returns the size of the displayed video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_dst_size(void) +#else +unsigned long +gfx_get_video_dst_size(void) +#endif +{ + unsigned long xsize, ysize; + + xsize = READ_VID32(SC1400_VIDEO_X_POS); + xsize = ((xsize >> 16) & 0x3FF) - (xsize & 0x03FF); + ysize = READ_VID32(SC1400_VIDEO_Y_POS); + ysize = ((ysize >> 16) & 0x3FF) - (ysize & 0x03FF); + return ((ysize << 16) | xsize); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_position + * + * This routine returns the position of the video overlay window. The + * return value is (ypos << 16) | xpos. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_position(void) +#else +unsigned long +gfx_get_video_position(void) +#endif +{ + unsigned long hadjust, vadjust; + unsigned long xpos, ypos; + + /* READ HARDWARE POSITION */ + + xpos = READ_VID32(SC1400_VIDEO_X_POS) & 0x000003FF; + ypos = READ_VID32(SC1400_VIDEO_Y_POS) & 0x000003FF; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13; + vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1; + xpos -= hadjust; + ypos -= vadjust; + return ((ypos << 16) | (xpos & 0x0000FFFF)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key + * + * This routine returns the current video color key value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_color_key(void) +#else +unsigned long +gfx_get_video_color_key(void) +#endif +{ + return (READ_VID32(SC1400_VIDEO_COLOR_KEY)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_mask + * + * This routine returns the current video color mask value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_video_color_key_mask(void) +#else +unsigned long +gfx_get_video_color_key_mask(void) +#endif +{ + return (READ_VID32(SC1400_VIDEO_COLOR_MASK)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_src + * + * This routine returns 0 for video data compare, 1 for graphics data. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_get_video_color_key_src(void) +#else +int +gfx_get_video_color_key_src(void) +#endif +{ + if (READ_VID32(SC1400_DISPLAY_CONFIG) & SC1400_DCFG_VG_CK) + return (0); + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_filter + * + * This routine returns if the filters are currently enabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_get_video_filter(void) +#else +int +gfx_get_video_filter(void) +#endif +{ + int retval = 0; + + if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_X_FILTER_EN) + retval |= 1; + if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_Y_FILTER_EN) + retval |= 2; + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_clock_frequency + * + * This routine returns the current clock frequency in 16.16 format. + * It reads the current register value and finds the match in the table. + * If no match is found, this routine returns 0. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_clock_frequency(void) +#else +unsigned long +gfx_get_clock_frequency(void) +#endif +{ + int index; + unsigned long value, mask; + + mask = 0x007FFF0F; + value = READ_VID32(SC1400_VID_CLOCK_SELECT) & mask; + for (index = 0; index < NUM_SC1400_FREQUENCIES; index++) { + if ((gfx_sc1400_clock_table[index].clock_select & mask) == value) + return (gfx_sc1400_clock_table[index].frequency); + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_read_crc + * + * This routine returns the hardware CRC value, which is used for automated + * testing. The value is like a checksum, but will change if pixels move + * locations. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_read_crc(void) +#else +unsigned long +gfx_read_crc(void) +#endif +{ + unsigned long crc = 0xFFFFFFFF; + + if (gfx_test_timing_active()) { + // WAIT UNTIL ACTIVE DISPLAY + + while (!gfx_test_vertical_active()) ; + + // RESET CRC DURING ACTIVE DISPLAY + + WRITE_VID32(SC1400_VID_CRC, 0); + WRITE_VID32(SC1400_VID_CRC, 1); + + // WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE + + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + crc = READ_VID32(SC1400_VID_CRC) >> 8; + } + return (crc); +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_5530.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_5530.c new file mode 100644 index 000000000..17d5f3b50 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_5530.c @@ -0,0 +1,1446 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_5530.c,v 1.2 2003/02/21 16:51:10 alanh Exp $ */ +/* + * $Workfile: vid_5530.c $ + * + * This file contains routines to control the CS5530 video overlay hardware. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/*---------------------------------------------------------------------------- + * CS5530 PLL TABLE + *---------------------------------------------------------------------------- + */ +typedef struct tagCS5530PLLENTRY +{ + long frequency; /* 16.16 fixed point frequency */ + unsigned long pll_value; /* associated register value */ +} +CS5530PLLENTRY; + +CS5530PLLENTRY CS5530_PLLtable[] = { + {0x00192CCC, 0x31C45801,}, /* 25.1750 */ + {0x001C526E, 0x20E36802,}, /* 28.3220 */ + {0x001F8000, 0x33915801,}, /* 31.5000 */ + {0x00240000, 0x31EC4801,}, /* 36.0000 */ + {0x00258000, 0x21E22801,}, /* 37.5000 */ + {0x00280000, 0x33088801,}, /* 40.0000 */ + {0x002CE666, 0x33E22801,}, /* 44.9000 */ + {0x00318000, 0x336C4801,}, /* 49.5000 */ + {0x00320000, 0x23088801,}, /* 50.0000 */ + {0x00325999, 0x23088801,}, /* 50.3500 */ + {0x00360000, 0x3708A801,}, /* 54.0000 */ + {0x00384000, 0x23E36802,}, /* 56.2500 */ + {0x0038643F, 0x23E36802,}, /* 56.3916 */ + {0x0038A4DD, 0x23E36802,}, /* 56.6444 */ + {0x003B0000, 0x37C45801,}, /* 59.0000 */ + {0x003F0000, 0x23EC4801,}, /* 63.0000 */ + {0x00410000, 0x37911801,}, /* 65.0000 */ + {0x00438000, 0x37963803,}, /* 67.5000 */ + {0x0046CCCC, 0x37058803,}, /* 70.8000 */ + {0x00480000, 0x3710C805,}, /* 72.0000 */ + {0x004B0000, 0x37E22801,}, /* 75.0000 */ + {0x004EC000, 0x27915801,}, /* 78.7500 */ + {0x00500000, 0x37D8D802,}, /* 80.0000 */ + {0x0059CCCC, 0x27588802,}, /* 89.8000 */ + {0x005E8000, 0x27EC4802,}, /* 94.5000 */ + {0x00630000, 0x27AC6803,}, /* 99.0000 */ + {0x00640000, 0x27088801,}, /* 100.0000 */ + {0x006C0000, 0x2710C805,}, /* 108.0000 */ + {0x00708000, 0x27E36802,}, /* 112.5000 */ + {0x00820000, 0x27C58803,}, /* 130.0000 */ + {0x00870000, 0x27316803,}, /* 135.0000 */ + {0x009D8000, 0x2F915801,}, /* 157.5000 */ + {0x00A20000, 0x2F08A801,}, /* 162.0000 */ + {0x00AF0000, 0x2FB11802,}, /* 175.0000 */ + {0x00BD0000, 0x2FEC4802,}, /* 189.0000 */ + {0x00CA0000, 0x2F963803,}, /* 202.0000 */ + {0x00E80000, 0x2FB1B802,}, /* 232.0000 */ +}; + +#define NUM_CS5530_FREQUENCIES sizeof(CS5530_PLLtable)/sizeof(CS5530PLLENTRY) + +int cs5530_set_video_enable(int enable); +int cs5530_set_video_format(unsigned long format); +int cs5530_set_video_size(unsigned short width, unsigned short height); +int cs5530_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch); +int cs5530_set_video_offset(unsigned long offset); +int cs5530_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset, + unsigned long voffset); +int cs5530_set_video_window(short x, short y, unsigned short w, + unsigned short h); +int cs5530_set_video_left_crop(unsigned short x); +int cs5530_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int cs5530_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int cs5530_set_video_vertical_downscale(unsigned short srch, + unsigned short dsth); +void cs5530_set_video_vertical_downscale_enable(int enable); +int cs5530_set_video_downscale_config(unsigned short type, unsigned short m); +int cs5530_set_video_color_key(unsigned long key, unsigned long mask, + int bluescreen); +int cs5530_set_video_filter(int xfilter, int yfilter); +int cs5530_set_video_palette(unsigned long *palette); +int cs5530_set_video_palette_entry(unsigned long index, unsigned long color); +int cs5530_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4); +int cs5530_set_video_downscale_enable(int enable); +int cs5530_set_video_source(VideoSourceType source); +int cs5530_set_vbi_source(VbiSourceType source); +int cs5530_set_vbi_lines(unsigned long even, unsigned long odd); +int cs5530_set_vbi_total(unsigned long even, unsigned long odd); +int cs5530_set_video_interlaced(int enable); +int cs5530_set_color_space_YUV(int enable); +int cs5530_set_vertical_scaler_offset(char offset); +int cs5530_set_top_line_in_odd(int enable); +int cs5530_set_genlock_delay(unsigned long delay); +int cs5530_set_genlock_enable(int flags); +int cs5530_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, + unsigned long color1, unsigned long color2); +int cs5530_set_video_cursor_enable(int enable); +int cs5530_set_video_request(short x, short y); + +int cs5530_select_alpha_region(int region); +int cs5530_set_alpha_enable(int enable); +int cs5530_set_alpha_window(short x, short y, + unsigned short width, unsigned short height); +int cs5530_set_alpha_value(unsigned char alpha, char delta); +int cs5530_set_alpha_priority(int priority); +int cs5530_set_alpha_color(unsigned long color); +int cs5530_set_alpha_color_enable(int enable); +int cs5530_set_no_ck_outside_alpha(int enable); +int cs5530_disable_softvga(void); +int cs5530_enable_softvga(void); +int cs5530_set_macrovision_enable(int enable); +int cs5530_set_crt_enable(int enable); +void cs5530_reset_video(void); +int cs5530_set_display_control(int sync_polarities); +void cs5530_set_clock_frequency(unsigned long frequency); + +/* READ ROUTINES IN GFX_VID.C */ + +int cs5530_get_video_enable(void); +int cs5530_get_video_format(void); +unsigned long cs5530_get_video_src_size(void); +unsigned long cs5530_get_video_line_size(void); +unsigned long cs5530_get_video_xclip(void); +unsigned long cs5530_get_video_offset(void); +void cs5530_get_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset); +void cs5530_get_video_yuv_pitch(unsigned long *ypitch, + unsigned long *uvpitch); +unsigned long cs5530_get_video_upscale(void); +unsigned long cs5530_get_video_scale(void); +unsigned long cs5530_get_video_downscale_delta(void); +int cs5530_get_video_vertical_downscale_enable(void); +int cs5530_get_video_downscale_config(unsigned short *type, + unsigned short *m); +void cs5530_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4); +void cs5530_get_video_downscale_enable(int *enable); +unsigned long cs5530_get_video_dst_size(void); +unsigned long cs5530_get_video_position(void); +unsigned long cs5530_get_video_color_key(void); +unsigned long cs5530_get_video_color_key_mask(void); +int cs5530_get_video_palette_entry(unsigned long index, + unsigned long *palette); +int cs5530_get_video_color_key_src(void); +int cs5530_get_video_filter(void); +int cs5530_get_video_request(short *x, short *y); +int cs5530_get_video_source(VideoSourceType * source); +int cs5530_get_vbi_source(VbiSourceType * source); +unsigned long cs5530_get_vbi_lines(int odd); +unsigned long cs5530_get_vbi_total(int odd); +int cs5530_get_video_interlaced(void); +int cs5530_get_color_space_YUV(void); +int cs5530_get_vertical_scaler_offset(char *offset); +unsigned long cs5530_get_genlock_delay(void); +int cs5530_get_genlock_enable(void); +int cs5530_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, + unsigned long *color1, unsigned short *color2); +unsigned long cs5530_read_crc(void); +unsigned long cs5530_read_crc32(void); +unsigned long cs5530_read_window_crc(int source, unsigned short x, + unsigned short y, unsigned short width, + unsigned short height, int crc32); +int cs5530_get_macrovision_enable(void); + +void cs5530_get_alpha_enable(int *enable); +void cs5530_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height); +void cs5530_get_alpha_value(unsigned char *alpha, char *delta); +void cs5530_get_alpha_priority(int *priority); +void cs5530_get_alpha_color(unsigned long *color); +unsigned long cs5530_get_clock_frequency(void); +int cs5530_get_vsa2_softvga_enable(void); +int cs5530_get_sync_polarities(void); + +/*--------------------------------------------------------------------------- + * gfx_set_crt_enable + * + * This routine enables or disables the CRT output from the video processor. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_crt_enable(int enable) +#else +int +gfx_set_crt_enable(int enable) +#endif +{ + unsigned long config; + + config = READ_VID32(CS5530_DISPLAY_CONFIG); + + switch (enable) { + case CRT_DISABLE: /* Disable everything */ + + WRITE_VID32(CS5530_DISPLAY_CONFIG, + config & ~(CS5530_DCFG_DIS_EN | CS5530_DCFG_HSYNC_EN | + CS5530_DCFG_VSYNC_EN | CS5530_DCFG_DAC_BL_EN | + CS5530_DCFG_DAC_PWDNX)); + break; + + case CRT_ENABLE: /* Enable CRT display, including display logic */ + + WRITE_VID32(CS5530_DISPLAY_CONFIG, + config | CS5530_DCFG_DIS_EN | CS5530_DCFG_HSYNC_EN | + CS5530_DCFG_VSYNC_EN | CS5530_DCFG_DAC_BL_EN | + CS5530_DCFG_DAC_PWDNX); + break; + + case CRT_STANDBY: /* HSync:Off VSync:On */ + + WRITE_VID32(CS5530_DISPLAY_CONFIG, + (config & + ~(CS5530_DCFG_DIS_EN | CS5530_DCFG_HSYNC_EN | + CS5530_DCFG_DAC_BL_EN | CS5530_DCFG_DAC_PWDNX)) + | CS5530_DCFG_VSYNC_EN); + break; + + case CRT_SUSPEND: /* HSync:On VSync:Off */ + + WRITE_VID32(CS5530_DISPLAY_CONFIG, + (config & + ~(CS5530_DCFG_DIS_EN | CS5530_DCFG_VSYNC_EN | + CS5530_DCFG_DAC_BL_EN | CS5530_DCFG_DAC_PWDNX)) + | CS5530_DCFG_HSYNC_EN); + break; + + default: + return (GFX_STATUS_BAD_PARAMETER); + } + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine is used to disable all components of video overlay before + * performing a mode switch. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +cs5530_reset_video(void) +#else +void +gfx_reset_video(void) +#endif +{ + gfx_set_video_enable(0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine configures the display output. + * + * "sync_polarities" is used to set the polarities of the sync pulses according + * to the following mask: + * + * Bit 0: If set to 1, negative horizontal polarity is programmed, + * otherwise positive horizontal polarity is programmed. + * Bit 1: If set to 1, negative vertical polarity is programmed, + * otherwise positive vertical polarity is programmed. + * + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_display_control(int sync_polarities) +#else +int +gfx_set_display_control(int sync_polarities) +#endif +{ + unsigned long dcfg; + + /* ENABLE DISPLAY OUTPUT FROM CX5530 */ + + dcfg = READ_VID32(CS5530_DISPLAY_CONFIG); + + /* CLEAR RELEVANT FIELDS */ + + dcfg &= ~(CS5530_DCFG_CRT_SYNC_SKW_MASK | CS5530_DCFG_PWR_SEQ_DLY_MASK | + CS5530_DCFG_CRT_HSYNC_POL | CS5530_DCFG_CRT_VSYNC_POL | + CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN); + + /* INITIALIZATION */ + + dcfg |= (CS5530_DCFG_CRT_SYNC_SKW_INIT | + CS5530_DCFG_PWR_SEQ_DLY_INIT | CS5530_DCFG_GV_PAL_BYP); + + if (PanelEnable) { + dcfg |= CS5530_DCFG_FP_PWR_EN; + dcfg |= CS5530_DCFG_FP_DATA_EN; + } + + /* SET APPROPRIATE SYNC POLARITIES */ + + if (sync_polarities & 1) + dcfg |= CS5530_DCFG_CRT_HSYNC_POL; + if (sync_polarities & 2) + dcfg |= CS5530_DCFG_CRT_VSYNC_POL; + + WRITE_VID32(CS5530_DISPLAY_CONFIG, dcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_clock_frequency + * + * This routine sets the clock frequency, specified as a 16.16 fixed point + * value (0x00318000 = 49.5 MHz). It will set the closest frequency found + * in the lookup table. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +cs5530_set_clock_frequency(unsigned long frequency) +#else +void +gfx_set_clock_frequency(unsigned long frequency) +#endif +{ + unsigned int index; + unsigned long value; + long min, diff; + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + value = CS5530_PLLtable[0].pll_value; + min = (long)CS5530_PLLtable[0].frequency - frequency; + if (min < 0L) + min = -min; + for (index = 1; index < NUM_CS5530_FREQUENCIES; index++) { + diff = (long)CS5530_PLLtable[index].frequency - frequency; + if (diff < 0L) + diff = -diff; + if (diff < min) { + min = diff; + value = CS5530_PLLtable[index].pll_value; + } + } + + /* SET THE DOT CLOCK REGISTER */ + + WRITE_VID32(CS5530_DOT_CLK_CONFIG, value); + WRITE_VID32(CS5530_DOT_CLK_CONFIG, value | 0x80000100); /* set reset/bypass */ + gfx_delay_milliseconds(1); /* wait for PLL to settle */ + WRITE_VID32(CS5530_DOT_CLK_CONFIG, value & 0x7FFFFFFF); /* clear reset */ + WRITE_VID32(CS5530_DOT_CLK_CONFIG, value & 0x7FFFFEFF); /* clear bypass */ + return; +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_enable + * + * This routine enables or disables the video overlay functionality. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_enable(int enable) +#else +int +gfx_set_video_enable(int enable) +#endif +{ + unsigned long vcfg; + + /* WAIT FOR VERTICAL BLANK TO START */ + /* Otherwise a glitch can be observed. */ + + if (gfx_test_timing_active()) { + if (!gfx_test_vertical_active()) { + while (!gfx_test_vertical_active()) ; + } + while (gfx_test_vertical_active()) ; + } + vcfg = READ_VID32(CS5530_VIDEO_CONFIG); + if (enable) { + /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(1); + + /* SET CS5530 BUS CONTROL PARAMETERS */ + /* Currently always high speed, 8-bit interface. */ + + vcfg |= CS5530_VCFG_HIGH_SPD_INT; + vcfg &= ~(CS5530_VCFG_EARLY_VID_RDY | CS5530_VCFG_16_BIT_EN); + + /* ENABLE CS5530 VIDEO OVERLAY */ + + vcfg |= CS5530_VCFG_VID_EN; + WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg); + } else { + /* DISABLE CS5530 VIDEO OVERLAY */ + + vcfg &= ~CS5530_VCFG_VID_EN; + WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg); + + /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(0); + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_format + * + * Currently only sets 4:2:0 format, Y1 V Y0 U. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_format(unsigned long format) +#else +int +gfx_set_video_format(unsigned long format) +#endif +{ + unsigned long vcfg = 0; + + /* SET THE CS5530 VIDEO INPUT FORMAT */ + + vcfg = READ_VID32(CS5530_VIDEO_CONFIG); + vcfg &= ~(CS5530_VCFG_VID_INP_FORMAT | CS5530_VCFG_4_2_0_MODE); + vcfg &= ~(CS5530_VCFG_CSC_BYPASS); + vcfg &= ~(CS5530_VCFG_GV_SEL); + + if (format < 4) + vcfg |= (format << 2); + else { + if (format == VIDEO_FORMAT_Y0Y1Y2Y3) { + vcfg |= CS5530_VCFG_4_2_0_MODE; + vcfg |= 1 << 2; + } + if (format == VIDEO_FORMAT_RGB) { + vcfg |= CS5530_VCFG_CSC_BYPASS; + vcfg |= CS5530_VCFG_GV_SEL; + } + } + + WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_size + * + * This routine specifies the size of the source data. It is used only + * to determine how much data to transfer per frame, and is not used to + * calculate the scaling value (that is handled by a separate routine). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_size(unsigned short width, unsigned short height) +#else +int +gfx_set_video_size(unsigned short width, unsigned short height) +#endif +{ + unsigned long size, vcfg; + + /* SET THE CS5530 VIDEO LINE SIZE */ + + vcfg = READ_VID32(CS5530_VIDEO_CONFIG); + vcfg &= ~(CS5530_VCFG_LINE_SIZE_LOWER_MASK | CS5530_VCFG_LINE_SIZE_UPPER); + size = (width >> 1); + vcfg |= (size & 0x00FF) << 8; + if (size & 0x0100) + vcfg |= CS5530_VCFG_LINE_SIZE_UPPER; + WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg); + + /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_size(width, height); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_offset + * + * This routine sets the starting offset for the video buffer when only + * one offset needs to be specified. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_offset(unsigned long offset) +#else +int +gfx_set_video_offset(unsigned long offset) +#endif +{ + /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ + + gfx_vid_offset = offset; + + /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_offset(offset); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_scale + * + * This routine sets the scale factor for the video overlay window. The + * size of the source and destination regions are specified in pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#else +int +gfx_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#endif +{ + unsigned long xscale, yscale; + + /* SAVE PARAMETERS */ + /* These are needed for clipping the video window later. */ + + gfx_vid_srcw = srcw; + gfx_vid_srch = srch; + gfx_vid_dstw = dstw; + gfx_vid_dsth = dsth; + + /* CALCULATE CS5530 SCALE FACTORS */ + /* No downscaling in CS5530 so force to 1x if attempted. */ + + if (dstw <= srcw) + xscale = 0x1FFF; + else if (dstw == 1 || srcw == 1) + return GFX_STATUS_BAD_PARAMETER; + else + xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l); + if (dsth <= srch) + yscale = 0x1FFF; + else if (dsth == 1 || srch == 1) + return GFX_STATUS_BAD_PARAMETER; + else + yscale = (0x2000l * (srch - 1l)) / (dsth - 1l); + WRITE_VID32(CS5530_VIDEO_SCALE, (yscale << 16) | xscale); + + /* CALL ROUTINE TO UPDATE WINDOW POSITION */ + /* This is required because the scale values effect the number of */ + /* source data pixels that need to be clipped, as well as the */ + /* amount of data that needs to be transferred. */ + + gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width, + gfx_vid_height); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_window + * + * This routine sets the position and size of the video overlay window. The + * position is specified in screen relative coordinates, and may be negative. + * The size of destination region is specified in pixels. The line size + * indicates the number of bytes of source data per scanline. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_window(short x, short y, unsigned short w, unsigned short h) +#else +int +gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) +#endif +{ + unsigned long vcfg = 0; + unsigned long hadjust, vadjust; + unsigned long xstart, ystart, xend, yend; + + /* SAVE PARAMETERS */ + /* These are needed to call this routine if the scale value changes. */ + + gfx_vid_xpos = x; + gfx_vid_ypos = y; + gfx_vid_width = w; + gfx_vid_height = h; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13l; + vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l; + + /* HORIZONTAL START */ + xstart = (unsigned long)x + hadjust; + + /* HORIZONTAL END */ + /* End positions in register are non-inclusive (one more than the actual end) */ + + if ((x + w) < gfx_get_hactive()) + xend = (unsigned long)x + (unsigned long)w + hadjust; + else /* right clipping needed */ + xend = (unsigned long)gfx_get_hactive() + hadjust; + + /* VERTICAL START */ + + ystart = (unsigned long)y + vadjust; + + /* VERTICAL END */ + + if ((y + h) < gfx_get_vactive()) + yend = (unsigned long)y + (unsigned long)h + vadjust; + else /* bottom clipping needed */ + yend = (unsigned long)gfx_get_vactive() + vadjust; + + /* DISABLE REGISTER UPDATES */ + + vcfg = READ_VID32(CS5530_VIDEO_CONFIG); + vcfg &= ~CS5530_VCFG_VID_REG_UPDATE; + WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg); + + /* SET VIDEO POSITION */ + + WRITE_VID32(CS5530_VIDEO_X_POS, (xend << 16) | xstart); + WRITE_VID32(CS5530_VIDEO_Y_POS, (yend << 16) | ystart); + + vcfg |= CS5530_VCFG_VID_REG_UPDATE; + WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_left_crop + * + * This routine sets the number of pixels which will be cropped from the + * beginning of each video line. The video window will begin to display only + * from the pixel following the cropped pixels, and the cropped pixels + * will be ignored. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_left_crop(unsigned short x) +#else +int +gfx_set_video_left_crop(unsigned short x) +#endif +{ + unsigned long vcfg, initread; + + /* CLIPPING ON LEFT */ + /* Adjust initial read for scale, checking for divide by zero */ + + if (gfx_vid_dstw) + initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw; + + else + initread = 0; + + /* SET INITIAL READ ADDRESS AND ENABLE REGISTER UPDATES */ + + vcfg = READ_VID32(CS5530_VIDEO_CONFIG); + vcfg &= ~CS5530_VCFG_INIT_READ_MASK; + vcfg |= (initread << 15) & CS5530_VCFG_INIT_READ_MASK; + vcfg |= CS5530_VCFG_VID_REG_UPDATE; + WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_color_key + * + * This routine specifies the color key value and mask for the video overlay + * hardware. To disable color key, the color and mask should both be set to + * zero. The hardware uses the color key in the following equation: + * + * ((source data) & (color key mask)) == ((color key) & (color key mask)) + * + * The source data can be either graphics data or video data. The bluescreen + * parameter is set to have the hardware compare video data and clear to + * comapare graphics data. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_color_key(unsigned long key, unsigned long mask, + int graphics) +#else +int +gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) +#endif +{ + unsigned long dcfg = 0; + + /* SET CS5530 COLOR KEY VALUE */ + + WRITE_VID32(CS5530_VIDEO_COLOR_KEY, key); + WRITE_VID32(CS5530_VIDEO_COLOR_MASK, mask); + + /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */ + + dcfg = READ_VID32(CS5530_DISPLAY_CONFIG); + if (graphics & 0x01) + dcfg &= ~CS5530_DCFG_VG_CK; + else + dcfg |= CS5530_DCFG_VG_CK; + WRITE_VID32(CS5530_DISPLAY_CONFIG, dcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_filter + * + * This routine enables or disables the video overlay filters. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_filter(int xfilter, int yfilter) +#else +int +gfx_set_video_filter(int xfilter, int yfilter) +#endif +{ + unsigned long vcfg = 0; + + /* ENABLE OR DISABLE CS5530 VIDEO OVERLAY FILTERS */ + + vcfg = READ_VID32(CS5530_VIDEO_CONFIG); + vcfg &= ~(CS5530_VCFG_X_FILTER_EN | CS5530_VCFG_Y_FILTER_EN); + if (xfilter) + vcfg |= CS5530_VCFG_X_FILTER_EN; + if (yfilter) + vcfg |= CS5530_VCFG_Y_FILTER_EN; + WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette + * + * This routine loads the video hardware palette. If a NULL pointer is + * specified, the palette is bypassed (for CS5530, this means loading the + * palette with identity values). + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_palette(unsigned long *palette) +#else +int +gfx_set_video_palette(unsigned long *palette) +#endif +{ + unsigned long i, entry; + + /* LOAD CS5530 VIDEO PALETTE */ + + WRITE_VID32(CS5530_PALETTE_ADDRESS, 0); + for (i = 0; i < 256; i++) { + if (palette) + entry = palette[i]; + else + entry = i | (i << 8) | (i << 16); + WRITE_VID32(CS5530_PALETTE_DATA, entry); + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette_entry + * + * This routine loads a single entry of the video hardware palette. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_set_video_palette_entry(unsigned long index, unsigned long palette) +#else +int +gfx_set_video_palette_entry(unsigned long index, unsigned long palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + /* SET A SINGLE ENTRY */ + + WRITE_VID32(CS5530_PALETTE_ADDRESS, index); + WRITE_VID32(CS5530_PALETTE_DATA, palette); + + return (0); +} + +#define CX55xx_VIDEO_PCI_44 0x80009444 + +/*--------------------------------------------------------------------------- + * gfx_disable_softvga + * + * Disables SoftVga. This function is only valid with VSA2, Returns 1 if + * SoftVga can be disabled; 0 if not. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_disable_softvga(void) +#else +int +gfx_disable_softvga(void) +#endif +{ + unsigned long reg_val; + + /* get the current value */ + reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44); + /* setting video PCI register 44 bit 0 to 1 disables SoftVga */ + reg_val |= 0x1; + gfx_pci_config_write(CX55xx_VIDEO_PCI_44, reg_val); + + /* see if we set the bit and return the appropriate value */ + reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0x1) + return (1); + else + return (0); + +} + +/*--------------------------------------------------------------------------- + * gfx_enable_softvga + * + * Enables SoftVga. This function is only valid with VSA2, Returns 1 if + * SoftVga can be enbled; 0 if not. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_enable_softvga(void) +#else +int +gfx_enable_softvga(void) +#endif +{ + unsigned long reg_val; + + /* get the current value */ + reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44); + /* clearing video PCI register 44 bit 0 enables SoftVga */ + gfx_pci_config_write(CX55xx_VIDEO_PCI_44, reg_val & 0xfffffffe); + + /* see if we cleared the bit and return the appropriate value */ + reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0) + return (1); + else + return (0); + +} + +/*--------------------------------------------------------------------------- + * gfx_get_clock_frequency + * + * This routine returns the current clock frequency in 16.16 format. + * It reads the current register value and finds the match in the table. + * If no match is found, this routine returns 0. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_clock_frequency(void) +#else +unsigned long +gfx_get_clock_frequency(void) +#endif +{ + unsigned int index; + unsigned long value, mask; + + mask = 0x7FFFFEDC; + value = READ_VID32(CS5530_DOT_CLK_CONFIG) & mask; + for (index = 0; index < NUM_CS5530_FREQUENCIES; index++) { + if ((CS5530_PLLtable[index].pll_value & mask) == value) + return (CS5530_PLLtable[index].frequency); + } + return (0); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*--------------------------------------------------------------------------- + * gfx_get_vsa2_softvga_enable + * + * This function returns the enable status of SoftVGA. It is valid + * only if VSAII is present. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_get_vsa2_softvga_enable(void) +#else +int +gfx_get_vsa2_softvga_enable(void) +#endif +{ + unsigned long reg_val; + + reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44); + if ((reg_val & 0x1) == 0) + return (1); + else + return (0); + +} + +/*--------------------------------------------------------------------------- + * gfx_get_sync_polarities + * + * This routine returns the polarities of the sync pulses: + * Bit 0: Set if negative horizontal polarity. + * Bit 1: Set if negative vertical polarity. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_get_sync_polarities(void) +#else +int +gfx_get_sync_polarities(void) +#endif +{ + int polarities = 0; + + if (READ_VID32(CS5530_DISPLAY_CONFIG) & 0x00000100) + polarities |= 1; + if (READ_VID32(CS5530_DISPLAY_CONFIG) & 0x00000200) + polarities |= 2; + return (polarities); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_palette_entry + * + * This routine returns a single palette entry. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_get_video_palette_entry(unsigned long index, unsigned long *palette) +#else +int +gfx_get_video_palette_entry(unsigned long index, unsigned long *palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + /* READ A SINGLE ENTRY */ + + WRITE_VID32(CS5530_PALETTE_ADDRESS, index); + *palette = READ_VID32(CS5530_PALETTE_DATA); + + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_enable + * + * This routine returns the value "one" if video overlay is currently enabled, + * otherwise it returns the value "zero". + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_get_video_enable(void) +#else +int +gfx_get_video_enable(void) +#endif +{ + if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_VID_EN) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_format + * + * This routine returns the current video overlay format. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_get_video_format(void) +#else +int +gfx_get_video_format(void) +#endif +{ + unsigned long vcfg; + + vcfg = READ_VID32(CS5530_VIDEO_CONFIG); + if (vcfg & CS5530_VCFG_CSC_BYPASS) + return (VIDEO_FORMAT_RGB); + if (vcfg & CS5530_VCFG_4_2_0_MODE) + return (VIDEO_FORMAT_Y0Y1Y2Y3); + + return ((int)((vcfg >> 2) & 3)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_src_size + * + * This routine returns the size of the source video overlay buffer. The + * return value is (height << 16) | width. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_src_size(void) +#else +unsigned long +gfx_get_video_src_size(void) +#endif +{ + unsigned long width = 0, height = 0; + + /* DETERMINE SOURCE WIDTH FROM THE CS5530 VIDEO LINE SIZE */ + + width = (READ_VID32(CS5530_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_LINE_SIZE_UPPER) + width += 512l; + + if (width) { + /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */ + /* Get total size from display controller - abtracted. */ + + height = gfx_get_display_video_size() / (width << 1); + } + return ((height << 16) | width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_line_size + * + * This routine returns the line size of the source video overlay buffer, in + * pixels. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_line_size(void) +#else +unsigned long +gfx_get_video_line_size(void) +#endif +{ + unsigned long width = 0; + + /* DETERMINE SOURCE WIDTH FROM THE CS5530 VIDEO LINE SIZE */ + + width = (READ_VID32(CS5530_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_LINE_SIZE_UPPER) + width += 512l; + return (width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_xclip + * + * This routine returns the number of bytes clipped on the left side of a + * video overlay line (skipped at beginning). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_xclip(void) +#else +unsigned long +gfx_get_video_xclip(void) +#endif +{ + unsigned long clip = 0; + + /* DETERMINE SOURCE WIDTH FROM THE CS5530 VIDEO LINE SIZE */ + + clip = (READ_VID32(CS5530_VIDEO_CONFIG) >> 14) & 0x000007FC; + return (clip); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_offset + * + * This routine returns the current offset for the video overlay buffer. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_offset(void) +#else +unsigned long +gfx_get_video_offset(void) +#endif +{ + return (gfx_get_display_video_offset()); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_scale + * + * This routine returns the scale factor for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_scale(void) +#else +unsigned long +gfx_get_video_scale(void) +#endif +{ + return (READ_VID32(CS5530_VIDEO_SCALE)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_dst_size + * + * This routine returns the size of the displayed video overlay window. + * NOTE: This is the displayed window size, which may be different from + * the real window size if clipped. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_dst_size(void) +#else +unsigned long +gfx_get_video_dst_size(void) +#endif +{ + unsigned long xsize, ysize; + + xsize = READ_VID32(CS5530_VIDEO_X_POS); + xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x07FF); + ysize = READ_VID32(CS5530_VIDEO_Y_POS); + ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x07FF); + return ((ysize << 16) | xsize); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_position + * + * This routine returns the position of the video overlay window. The + * return value is (ypos << 16) | xpos. + * NOTE: This is the displayed window position, which may be different from + * the real window position if clipped. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_position(void) +#else +unsigned long +gfx_get_video_position(void) +#endif +{ + unsigned long hadjust, vadjust; + unsigned long xpos, ypos; + + /* READ HARDWARE POSITION */ + + xpos = READ_VID32(CS5530_VIDEO_X_POS) & 0x000007FF; + ypos = READ_VID32(CS5530_VIDEO_Y_POS) & 0x000007FF; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13l; + vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l; + xpos -= hadjust; + ypos -= vadjust; + return ((ypos << 16) | (xpos & 0x0000FFFF)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key + * + * This routine returns the current video color key value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_color_key(void) +#else +unsigned long +gfx_get_video_color_key(void) +#endif +{ + return (READ_VID32(CS5530_VIDEO_COLOR_KEY)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_mask + * + * This routine returns the current video color mask value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_get_video_color_key_mask(void) +#else +unsigned long +gfx_get_video_color_key_mask(void) +#endif +{ + return (READ_VID32(CS5530_VIDEO_COLOR_MASK)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_src + * + * This routine returns 0 for video data compare, 1 for graphics data. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_get_video_color_key_src(void) +#else +int +gfx_get_video_color_key_src(void) +#endif +{ + if (READ_VID32(CS5530_DISPLAY_CONFIG) & CS5530_DCFG_VG_CK) + return (0); + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_filter + * + * This routine returns if the filters are currently enabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +cs5530_get_video_filter(void) +#else +int +gfx_get_video_filter(void) +#endif +{ + int retval = 0; + + if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_X_FILTER_EN) + retval |= 1; + if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_Y_FILTER_EN) + retval |= 2; + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_read_crc + * + * This routine returns the hardware CRC value, which is used for automated + * testing. The value is like a checksum, but will change if pixels move + * locations. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +cs5530_read_crc(void) +#else +unsigned long +gfx_read_crc(void) +#endif +{ + unsigned long crc = 0xFFFFFFFF; + + if (gfx_test_timing_active()) { + /* WAIT UNTIL ACTIVE DISPLAY */ + + while (!gfx_test_vertical_active()) ; + + /* RESET CRC DURING ACTIVE DISPLAY */ + + WRITE_VID32(CS5530_CRCSIG_TFT_TV, 0); + WRITE_VID32(CS5530_CRCSIG_TFT_TV, 1); + + /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */ + + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + crc = READ_VID32(CS5530_CRCSIG_TFT_TV) >> 8; + } + return (crc); +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_rdcl.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_rdcl.c new file mode 100644 index 000000000..8e429d8e1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_rdcl.c @@ -0,0 +1,2913 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_rdcl.c,v 1.3 2003/02/21 16:51:10 alanh Exp $ */ +/* + * $Workfile: vid_rdcl.c $ + * + * This file contains routines to control the Redcloud display filter video overlay hardware. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* REDCLOUD PLL TABLE */ + +typedef struct RCDFPLL +{ + long frequency; /* 16.16 fixed point frequency */ + unsigned long post_div3; /* MCP Frequency dividers and multipliers */ + unsigned long pre_mul2; + unsigned long pre_div2; + unsigned long pll_value; /* MCP DotPLL Register Upper 32(0x0015) */ +} +RCDFPLLENTRY; + +RCDFPLLENTRY RCDF_PLLtable48MHz[] = { + {0x00192CCC, 0, 0, 0, 0x00000037}, /* 25.1750 */ + {0x001C526E, 1, 1, 0, 0x00000B1A}, /* 28.3220 */ + {0x001F8000, 1, 0, 0, 0x000002D2}, /* 31.5000 */ + {0x00240000, 1, 1, 0, 0x00000FE2}, /* 36.0000 */ + {0x00258000, 1, 0, 0, 0x0000057A}, /* 37.5000 */ + {0x00280000, 1, 0, 0, 0x0000030A}, /* 40.0000 */ + {0x002CE666, 0, 0, 0, 0x00000063}, /* 44.9000 */ + {0x00318000, 0, 0, 0, 0x0000054B}, /* 49.5000 */ + {0x00320000, 0, 0, 0, 0x0000026E}, /* 50.0000 */ + {0x00325999, 0, 1, 0, 0x00000037}, /* 50.3500 */ + {0x00360000, 1, 1, 0, 0x00000B0D}, /* 54.0000 */ + {0x00384000, 0, 0, 0, 0x00000577}, /* 56.2500 */ + {0x0038643F, 0, 0, 0, 0x000007F7}, /* 56.3916 */ + {0x0038A4DD, 0, 0, 0, 0x0000057B}, /* 56.6444 */ + {0x003B0000, 0, 1, 0, 0x00000707}, /* 59.0000 */ + {0x003F0000, 1, 1, 0, 0x00000B39}, /* 63.0000 */ + {0x00410000, 1, 1, 0, 0x00000B45}, /* 65.0000 */ + {0x00438000, 1, 1, 0, 0x00000FC1}, /* 67.5000 */ + {0x0046CCCC, 1, 0, 0, 0x00000561}, /* 70.8000 */ + {0x00480000, 1, 0, 0, 0x000007E1}, /* 72.0000 */ + {0x004B0000, 0, 0, 0, 0x00000052}, /* 75.0000 */ + {0x004EC000, 0, 0, 0, 0x00000056}, /* 78.7500 */ + {0x00500000, 1, 1, 0, 0x00000709}, /* 80.0000 */ + {0x0059CCCC, 0, 1, 0, 0x00000262}, /* 89.8000 */ + {0x005E8000, 0, 0, 0, 0x000002D2}, /* 94.5000 */ + {0x00630000, 0, 1, 0, 0x00000B4A}, /* 99.0000 */ + {0x00640000, 0, 1, 0, 0x00000036}, /* 100.0000 */ + {0x006C0000, 0, 0, 0, 0x000007E2}, /* 108.0000 */ + {0x00708000, 0, 0, 0, 0x000007F6}, /* 112.5000 */ + {0x00820000, 1, 1, 0, 0x00000FB0}, /* 130.0000 */ + {0x00870000, 1, 1, 0, 0x00000B50}, /* 135.0000 */ + {0x009D8000, 0, 0, 0, 0x00000055}, /* 157.5000 */ + {0x00A20000, 0, 0, 0, 0x000009C1}, /* 162.0000 */ + {0x00AF8000, 0, 0, 0, 0x000002C1}, /* 175.5000 */ + {0x00BD0000, 0, 0, 0, 0x000002D1}, /* 189.0000 */ + {0x00CA8000, 0, 0, 0, 0x00000551}, /* 202.5000 */ + {0x00E58000, 0, 0, 0, 0x0000057D}, /* 229.5000 */ +}; + +RCDFPLLENTRY RCDF_PLLtable14MHz[] = { + {0x00192CCC, 0, 0, 0, 0x00000037}, /* 25.1750 */ + {0x001C526E, 0, 0, 0, 0x00000B7B}, /* 28.3220 */ + {0x001F8000, 0, 0, 0, 0x000004D3}, /* 31.5000 */ + {0x00240000, 0, 0, 0, 0x00000BE3}, /* 36.0000 */ + {0x00258000, 0, 0, 0, 0x0000074F}, /* 37.5000 */ + {0x00280000, 0, 0, 0, 0x0000050B}, /* 40.0000 */ + {0x002CE666, 0, 0, 0, 0x00000063}, /* 44.9000 */ + {0x00318000, 0, 0, 0, 0x0000054B}, /* 49.5000 */ + {0x00320000, 0, 0, 0, 0x0000026E}, /* 50.0000 */ + {0x00325999, 0, 0, 0, 0x000007C3}, /* 50.3500 */ + {0x00360000, 0, 0, 0, 0x000007E3}, /* 54.0000 */ + {0x00384000, 0, 0, 0, 0x00000577}, /* 56.2500 */ + {0x0038643F, 0, 0, 0, 0x000002FB}, /* 56.3916 */ + {0x0038A4DD, 0, 0, 0, 0x0000057B}, /* 56.6444 */ + {0x003B0000, 0, 0, 0, 0x0000058B}, /* 59.0000 */ + {0x003F0000, 0, 0, 0, 0x0000095E}, /* 63.0000 */ + {0x00410000, 0, 0, 0, 0x0000096A}, /* 65.0000 */ + {0x00438000, 0, 0, 0, 0x00000BC2}, /* 67.5000 */ + {0x0046CCCC, 0, 0, 0, 0x0000098A}, /* 70.8000 */ + {0x00480000, 0, 0, 0, 0x00000BE2}, /* 72.0000 */ + {0x004B0000, 0, 0, 0, 0x00000052}, /* 75.0000 */ + {0x004EC000, 0, 0, 0, 0x00000056}, /* 78.7500 */ + {0x00500000, 0, 0, 0, 0x0000050A}, /* 80.0000 */ + {0x0059CCCC, 0, 0, 0, 0x0000078E}, /* 89.8000 */ + {0x005E8000, 0, 0, 0, 0x000002D2}, /* 94.5000 */ + {0x00630000, 0, 0, 0, 0x000011F6}, /* 99.0000 */ + {0x00640000, 0, 0, 0, 0x0000054E}, /* 100.0000 */ + {0x006C0000, 0, 0, 0, 0x000007E2}, /* 108.0000 */ + {0x00708000, 0, 0, 0, 0x000002FA}, /* 112.5000 */ + {0x00820000, 0, 0, 0, 0x00000BB1}, /* 130.0000 */ + {0x00870000, 0, 0, 0, 0x00000975}, /* 135.0000 */ + {0x009D8000, 0, 0, 0, 0x00000055}, /* 157.5000 */ + {0x00A20000, 0, 0, 0, 0x000009C1}, /* 162.0000 */ + {0x00AF8000, 0, 0, 0, 0x000002C1}, /* 175.5000 */ + {0x00BD0000, 0, 0, 0, 0x00000539}, /* 189.0000 */ + {0x00CA8000, 0, 0, 0, 0x00000551}, /* 202.5000 */ + {0x00E58000, 0, 0, 0, 0x0000057D}, /* 229.5000 */ +}; + +#define NUM_RCDF_FREQUENCIES sizeof(RCDF_PLLtable14MHz)/sizeof(RCDFPLLENTRY) + +int redcloud_set_video_enable(int enable); +int redcloud_set_video_format(unsigned long format); +int redcloud_set_video_size(unsigned short width, unsigned short height); +int redcloud_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch); +int redcloud_set_video_offset(unsigned long offset); +int redcloud_set_video_yuv_offsets(unsigned long yoffset, + unsigned long uoffset, + unsigned long voffset); +int redcloud_set_video_window(short x, short y, unsigned short w, + unsigned short h); +int redcloud_set_video_left_crop(unsigned short x); +int redcloud_set_video_upscale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int redcloud_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth); +int redcloud_set_video_vertical_downscale(unsigned short srch, + unsigned short dsth); +void redcloud_set_video_vertical_downscale_enable(int enable); +int redcloud_set_video_downscale_config(unsigned short type, + unsigned short m); +int redcloud_set_video_color_key(unsigned long key, unsigned long mask, + int bluescreen); +int redcloud_set_video_filter(int xfilter, int yfilter); +int redcloud_set_video_palette(unsigned long *palette); +int redcloud_set_video_palette_entry(unsigned long index, + unsigned long color); +int redcloud_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4); +int redcloud_set_video_downscale_enable(int enable); +int redcloud_set_video_source(VideoSourceType source); +int redcloud_set_vbi_source(VbiSourceType source); +int redcloud_set_vbi_lines(unsigned long even, unsigned long odd); +int redcloud_set_vbi_total(unsigned long even, unsigned long odd); +int redcloud_set_video_interlaced(int enable); +int redcloud_set_color_space_YUV(int enable); +int redcloud_set_vertical_scaler_offset(char offset); +int redcloud_set_top_line_in_odd(int enable); +int redcloud_set_genlock_delay(unsigned long delay); +int redcloud_set_genlock_enable(int flags); +int redcloud_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, + unsigned long color1, unsigned long color2); +int redcloud_set_video_cursor_enable(int enable); +int redcloud_set_video_request(short x, short y); + +int redcloud_select_alpha_region(int region); +int redcloud_set_alpha_enable(int enable); +int redcloud_set_alpha_window(short x, short y, + unsigned short width, unsigned short height); +int redcloud_set_alpha_value(unsigned char alpha, char delta); +int redcloud_set_alpha_priority(int priority); +int redcloud_set_alpha_color(unsigned long color); +int redcloud_set_alpha_color_enable(int enable); +int redcloud_set_no_ck_outside_alpha(int enable); +int redcloud_disable_softvga(void); +int redcloud_enable_softvga(void); +int redcloud_set_macrovision_enable(int enable); +void redcloud_reset_video(void); +int redcloud_set_display_control(int sync_polarities); +void redcloud_set_clock_frequency(unsigned long frequency); +int redcloud_set_crt_enable(int enable); + +/* READ ROUTINES IN GFX_VID.C */ + +int redcloud_get_video_enable(void); +int redcloud_get_video_format(void); +unsigned long redcloud_get_video_src_size(void); +unsigned long redcloud_get_video_line_size(void); +unsigned long redcloud_get_video_xclip(void); +unsigned long redcloud_get_video_offset(void); +void redcloud_get_video_yuv_offsets(unsigned long *yoffset, + unsigned long *uoffset, + unsigned long *voffset); +void redcloud_get_video_yuv_pitch(unsigned long *ypitch, + unsigned long *uvpitch); +unsigned long redcloud_get_video_upscale(void); +unsigned long redcloud_get_video_scale(void); +unsigned long redcloud_get_video_downscale_delta(void); +int redcloud_get_video_vertical_downscale_enable(void); +int redcloud_get_video_downscale_config(unsigned short *type, + unsigned short *m); +void redcloud_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4); +void redcloud_get_video_downscale_enable(int *enable); +unsigned long redcloud_get_video_dst_size(void); +unsigned long redcloud_get_video_position(void); +unsigned long redcloud_get_video_color_key(void); +unsigned long redcloud_get_video_color_key_mask(void); +int redcloud_get_video_palette_entry(unsigned long index, + unsigned long *palette); +int redcloud_get_video_color_key_src(void); +int redcloud_get_video_filter(void); +int redcloud_get_video_request(short *x, short *y); +int redcloud_get_video_source(VideoSourceType * source); +int redcloud_get_vbi_source(VbiSourceType * source); +unsigned long redcloud_get_vbi_lines(int odd); +unsigned long redcloud_get_vbi_total(int odd); +int redcloud_get_video_interlaced(void); +int redcloud_get_color_space_YUV(void); +int redcloud_get_vertical_scaler_offset(char *offset); +unsigned long redcloud_get_genlock_delay(void); +int redcloud_get_genlock_enable(void); +int redcloud_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, + unsigned long *color1, unsigned short *color2); +unsigned long redcloud_read_crc(void); +unsigned long redcloud_read_crc32(void); +unsigned long redcloud_read_window_crc(int source, unsigned short x, + unsigned short y, unsigned short width, + unsigned short height, int crc32); +int redcloud_get_macrovision_enable(void); + +void redcloud_get_alpha_enable(int *enable); +void redcloud_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height); +void redcloud_get_alpha_value(unsigned char *alpha, char *delta); +void redcloud_get_alpha_priority(int *priority); +void redcloud_get_alpha_color(unsigned long *color); +unsigned long redcloud_get_clock_frequency(void); +int redcloud_get_sync_polarities(void); + +/*--------------------------------------------------------------------------- + * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine is used to disable all components of video overlay before + * performing a mode switch. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_reset_video(void) +#else +void +gfx_reset_video(void) +#endif +{ + gfx_set_video_enable(0); + gfx_select_alpha_region(1); + gfx_set_alpha_enable(0); + gfx_select_alpha_region(2); + gfx_set_alpha_enable(0); + + /* SET REGION 0 AFTER RESET */ + + gfx_select_alpha_region(0); + gfx_set_alpha_enable(0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API) + * + * This routine configures the display output. + * + * "sync_polarities" is used to set the polarities of the sync pulses according + * to the following mask: + * + * Bit 0: If set to 1, negative horizontal polarity is programmed, + * otherwise positive horizontal polarity is programmed. + * Bit 1: If set to 1, negative vertical polarity is programmed, + * otherwise positive vertical polarity is programmed. + * + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_display_control(int sync_polarities) +#else +int +gfx_set_display_control(int sync_polarities) +#endif +{ + unsigned long power; + unsigned long dcfg; + + /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */ + + dcfg = READ_VID32(RCDF_DISPLAY_CONFIG); + dcfg &= ~(RCDF_DCFG_CRT_SYNC_SKW_MASK | RCDF_DCFG_PWR_SEQ_DLY_MASK | + RCDF_DCFG_CRT_HSYNC_POL | RCDF_DCFG_CRT_VSYNC_POL | + RCDF_DCFG_FP_PWR_EN | RCDF_DCFG_FP_DATA_EN); + + dcfg |= (RCDF_DCFG_CRT_SYNC_SKW_INIT | + RCDF_DCFG_PWR_SEQ_DLY_INIT | RCDF_DCFG_GV_PAL_BYP); + + if (PanelEnable) { + power = READ_VID32(RCDF_POWER_MANAGEMENT); + power |= RCDF_PM_PANEL_POWER_ON; + WRITE_VID32(RCDF_POWER_MANAGEMENT, power); + } + + /* SET APPROPRIATE SYNC POLARITIES */ + + if (sync_polarities & 0x1) + dcfg |= RCDF_DCFG_CRT_HSYNC_POL; + if (sync_polarities & 0x2) + dcfg |= RCDF_DCFG_CRT_VSYNC_POL; + + WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_clock_frequency + * + * This routine sets the clock frequency, specified as a 16.16 fixed point + * value (0x00318000 = 49.5 MHz). It will set the closest frequency found + * in the lookup table. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_set_clock_frequency(unsigned long frequency) +#else +void +gfx_set_clock_frequency(unsigned long frequency) +#endif +{ + Q_WORD msr_value; + unsigned int i, index = 0; + unsigned long value; + long timeout = 1000; + long min, diff; + RCDFPLLENTRY *PllTable; + + /* READ PLL REFERENCE FREQUENCY */ + /* The reference frequency of GX2 1.x is different from 2.x and above. */ + + if ((gfx_cpu_version & 0xFF00) >= 0x0200) + PllTable = RCDF_PLLtable48MHz; + else + PllTable = RCDF_PLLtable14MHz; + + /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ + /* Search the table for the closest frequency (16.16 format). */ + + value = PllTable[0].pll_value; + min = (long)PllTable[0].frequency - frequency; + if (min < 0L) + min = -min; + for (i = 1; i < NUM_RCDF_FREQUENCIES; i++) { + diff = (long)PllTable[i].frequency - frequency; + if (diff < 0L) + diff = -diff; + if (diff < min) { + min = diff; + index = i; + } + } + + /* PROGRAM THE SETTINGS WITH THE RESET BIT SET */ + /* Clear the bypass bit to ensure that the programmed */ + /* M, N and P values are being used. */ + + gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value); + msr_value.high = PllTable[index].pll_value; + msr_value.low |= 0x00000001; + msr_value.low &= ~MCP_DOTPLL_BYPASS; + gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value); + + /* PROGRAM THE MCP DIVIDER VALUES */ + + gfx_msr_read(RC_ID_MCP, MCP_SYS_RSTPLL, &msr_value); + if (PllTable[index].post_div3) + msr_value.low |= MCP_DOTPOSTDIV3; + else + msr_value.low &= ~MCP_DOTPOSTDIV3; + if (PllTable[index].pre_div2) + msr_value.low |= MCP_DOTPREDIV2; + else + msr_value.low &= ~MCP_DOTPREDIV2; + if (PllTable[index].pre_mul2) + msr_value.low |= MCP_DOTPREMULT2; + else + msr_value.low &= ~MCP_DOTPREMULT2; + gfx_msr_write(RC_ID_MCP, MCP_SYS_RSTPLL, &msr_value); + + /* CLEAR THE RESET BIT */ + + gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value); + msr_value.low &= 0xFFFFFFFE; + gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value); + + /* WAIT FOR LOCK BIT */ + + do { + gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value); + } while (timeout-- && !(msr_value.low & MCP_DOTPLL_LOCK)); +} + +/*--------------------------------------------------------------------------- + * gfx_set_crt_enable + * + * This routine enables or disables the CRT output from the video processor. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_crt_enable(int enable) +#else +int +gfx_set_crt_enable(int enable) +#endif +{ + unsigned long config, misc; + + config = READ_VID32(RCDF_DISPLAY_CONFIG); + misc = READ_VID32(RCDF_VID_MISC); + + switch (enable) { + case CRT_DISABLE: /* DISABLE EVERYTHING */ + + WRITE_VID32(RCDF_DISPLAY_CONFIG, + config & ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN | + RCDF_DCFG_VSYNC_EN | RCDF_DCFG_DAC_BL_EN)); + WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN); + break; + + case CRT_ENABLE: /* ENABLE CRT DISPLAY, INCLUDING DISPLAY LOGIC */ + + WRITE_VID32(RCDF_DISPLAY_CONFIG, + config | RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN | + RCDF_DCFG_VSYNC_EN | RCDF_DCFG_DAC_BL_EN); + WRITE_VID32(RCDF_VID_MISC, + misc & ~RCDF_DAC_POWER_DOWN & ~RCDF_ANALOG_POWER_DOWN); + break; + + case CRT_STANDBY: /* HSYNC:OFF VSYNC:ON */ + + WRITE_VID32(RCDF_DISPLAY_CONFIG, + (config & + ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN | + RCDF_DCFG_DAC_BL_EN)) | RCDF_DCFG_VSYNC_EN); + WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN); + break; + + case CRT_SUSPEND: /* HSYNC:ON VSYNC:OFF */ + + WRITE_VID32(RCDF_DISPLAY_CONFIG, + (config & + ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_VSYNC_EN | + RCDF_DCFG_DAC_BL_EN)) | RCDF_DCFG_HSYNC_EN); + WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN); + break; + + default: + return (GFX_STATUS_BAD_PARAMETER); + } + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_enable + * + * This routine enables or disables the video overlay functionality. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_enable(int enable) +#else +int +gfx_set_video_enable(int enable) +#endif +{ + unsigned long vcfg; + + /* WAIT FOR VERTICAL BLANK TO START */ + /* Otherwise a glitch can be observed. */ + + if (gfx_test_timing_active()) { + if (!gfx_test_vertical_active()) { + while (!gfx_test_vertical_active()) ; + } + while (gfx_test_vertical_active()) ; + } + + vcfg = READ_VID32(RCDF_VIDEO_CONFIG); + if (enable) { + /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(1); + + /* ENABLE DISPLAY FILTER VIDEO OVERLAY */ + + vcfg |= RCDF_VCFG_VID_EN; + WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg); + } else { + /* DISABLE DISPLAY FILTER VIDEO OVERLAY */ + + vcfg &= ~RCDF_VCFG_VID_EN; + WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg); + + /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_enable(0); + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_format + * + * Sets input video format type, to one of the YUV formats or to RGB. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_format(unsigned long format) +#else +int +gfx_set_video_format(unsigned long format) +#endif +{ + unsigned long ctrl, vcfg = 0; + + /* SET THE DISPLAY FILTER VIDEO INPUT FORMAT */ + + vcfg = READ_VID32(RCDF_VIDEO_CONFIG); + ctrl = READ_VID32(RCDF_VID_ALPHA_CONTROL); + ctrl &= ~(RCDF_VIDEO_INPUT_IS_RGB | RCDF_CSC_VIDEO_YUV_TO_RGB); + vcfg &= ~(RCDF_VCFG_VID_INP_FORMAT | RCDF_VCFG_4_2_0_MODE); + switch (format) { + case VIDEO_FORMAT_UYVY: + vcfg |= RCDF_VCFG_UYVY_FORMAT; + ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB; + break; + case VIDEO_FORMAT_YUYV: + vcfg |= RCDF_VCFG_YUYV_FORMAT; + ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB; + break; + case VIDEO_FORMAT_Y2YU: + vcfg |= RCDF_VCFG_Y2YU_FORMAT; + ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB; + break; + case VIDEO_FORMAT_YVYU: + vcfg |= RCDF_VCFG_YVYU_FORMAT; + ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB; + break; + case VIDEO_FORMAT_Y0Y1Y2Y3: + vcfg |= RCDF_VCFG_UYVY_FORMAT; + ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB; + vcfg |= RCDF_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y3Y2Y1Y0: + vcfg |= RCDF_VCFG_Y2YU_FORMAT; + ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB; + vcfg |= RCDF_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y1Y0Y3Y2: + vcfg |= RCDF_VCFG_YUYV_FORMAT; + ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB; + vcfg |= RCDF_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_Y1Y2Y3Y0: + vcfg |= RCDF_VCFG_YVYU_FORMAT; + ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB; + vcfg |= RCDF_VCFG_4_2_0_MODE; + break; + case VIDEO_FORMAT_RGB: + ctrl |= RCDF_VIDEO_INPUT_IS_RGB; + vcfg |= RCDF_VCFG_UYVY_FORMAT; + break; + case VIDEO_FORMAT_P2M_P2L_P1M_P1L: + ctrl |= RCDF_VIDEO_INPUT_IS_RGB; + vcfg |= RCDF_VCFG_Y2YU_FORMAT; + break; + case VIDEO_FORMAT_P1M_P1L_P2M_P2L: + ctrl |= RCDF_VIDEO_INPUT_IS_RGB; + vcfg |= RCDF_VCFG_YUYV_FORMAT; + break; + case VIDEO_FORMAT_P1M_P2L_P2M_P1L: + ctrl |= RCDF_VIDEO_INPUT_IS_RGB; + vcfg |= RCDF_VCFG_YVYU_FORMAT; + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg); + WRITE_VID32(RCDF_VID_ALPHA_CONTROL, ctrl); + + /* SET THE VIDEO FORMAT IN THE DISPLAY CONTROLLER */ + /* Use private routine to abstract display controller. */ + + gfx_set_display_video_format(format); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_size + * + * This routine specifies the size of the source data. It is used only + * to determine how much data to transfer per frame, and is not used to + * calculate the scaling value (that is handled by a separate routine). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_size(unsigned short width, unsigned short height) +#else +int +gfx_set_video_size(unsigned short width, unsigned short height) +#endif +{ + unsigned long size, vcfg, vid_420, pitch; + + /* SET THE DISPLAY FILTER VIDEO LINE SIZE */ + /* Match the DC hardware alignment requirement. The line size must */ + /* always be 32-byte aligned. However, we can manage smaller */ + /* alignments by decreasing the pitch and clipping the video window. */ + /* The VG will fetch extra data for each line, but the decreased */ + /* pitch will ensure that it always begins fetching at the start of */ + /* the video line. */ + + vcfg = READ_VID32(RCDF_VIDEO_CONFIG); + + vid_420 = vcfg & RCDF_VCFG_4_2_0_MODE; + + vcfg &= ~(RCDF_VCFG_LINE_SIZE_LOWER_MASK | RCDF_VCFG_LINE_SIZE_UPPER); + + size = ((width >> 1) + 7) & 0xFFF8; + pitch = ((width << 1) + 7) & 0xFFF8; + + vcfg |= (size & 0x00FF) << 8; + if (size & 0x0100) + vcfg |= RCDF_VCFG_LINE_SIZE_UPPER; + WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg); + + /* SET VIDEO BUFFER LINE SIZE IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_size(width, height); + + /* SET VIDEO PITCH */ + /* We are only maintaining legacy for 4:2:2 video formats. */ + /* 4:2:0 video in previous chips was inadequate for most */ + /* common video formats. */ + + if (!vid_420) + gfx_set_video_yuv_pitch(pitch, pitch << 1); + + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_offset + * + * This routine sets the starting offset for the video buffer when only + * one offset needs to be specified. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_offset(unsigned long offset) +#else +int +gfx_set_video_offset(unsigned long offset) +#endif +{ + /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ + + gfx_vid_offset = offset; + + /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_offset(offset); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_yuv_offsets + * + * This routine sets the starting offset for the video buffer when displaying + * 4:2:0 video. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset, + unsigned long voffset) +#else +int +gfx_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset, + unsigned long voffset) +#endif +{ + /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ + + gfx_vid_offset = yoffset; + gfx_vid_uoffset = uoffset; + gfx_vid_voffset = voffset; + + /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_yuv_offsets(yoffset, uoffset, voffset); + + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_video_yuv_pitch + * + * This routine sets the byte offset between consecutive scanlines of YUV video data + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch) +#else +int +gfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch) +#endif +{ + /* SET VIDEO PITCH IN DISPLAY CONTROLLER */ + /* Use private routine to abstract the display controller. */ + + gfx_set_display_video_yuv_pitch(ypitch, uvpitch); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_scale + * + * This routine sets the scale factor for the video overlay window. The + * size of the source and destination regions are specified in pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#else +int +gfx_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +#endif +{ + unsigned long xscale, yscale; + + /* SAVE PARAMETERS (unless don't-care zero destination arguments are used) */ + /* These are needed for clipping the video window later. */ + + if (dstw != 0) { + gfx_vid_srcw = srcw; + gfx_vid_dstw = dstw; + } + if (dsth != 0) { + gfx_vid_srch = srch; + gfx_vid_dsth = dsth; + } + + /* CALCULATE DISPLAY FILTER SCALE FACTORS */ + /* Zero width and height indicate don't care conditions */ + /* Downscaling is performed in a separate function. */ + + if (dstw == 0) + xscale = READ_VID32(RCDF_VIDEO_SCALE) & 0xffff; /* keep previous if don't-care argument */ + else if (dstw <= srcw) + xscale = 0x2000; /* horizontal downscaling is currently done in a separate function */ + else if ((srcw == 1) || (dstw == 1)) + return GFX_STATUS_BAD_PARAMETER; + else + xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l); + + if (dsth == 0) + yscale = (READ_VID32(RCDF_VIDEO_SCALE) & 0xffff0000) >> 16; /* keep previous if don't-care argument */ + else if (dsth <= srch) + yscale = 0x2000; /* vertical downscaling is handled in a separate function */ + else if ((srch == 1) || (dsth == 1)) + return GFX_STATUS_BAD_PARAMETER; + else + yscale = (0x2000l * (srch - 1l)) / (dsth - 1l); + + WRITE_VID32(RCDF_VIDEO_SCALE, (yscale << 16) | xscale); + + /* CALL ROUTINE TO UPDATE WINDOW POSITION */ + /* This is required because the scale values affect the number of */ + /* source data pixels that need to be clipped, as well as the */ + /* amount of data that needs to be transferred. */ + + gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width, + gfx_vid_height); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_vertical_downscale + * + * This routine sets the vertical downscale factor for the video overlay window. + * The height of the source and destination regions are specified in pixels. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_vertical_downscale(unsigned short srch, + unsigned short dsth) +#else +int +gfx_set_video_vertical_downscale(unsigned short srch, unsigned short dsth) +#endif +{ + /* SET VIDEO SCALE IN DISPLAY CONTROLLER */ + /* Use private routine to abstract hardware */ + + gfx_set_display_video_downscale(srch, dsth); + return 0; +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_vertical_downscale_enable + * + * This routine sets the vertical downscale enable for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_set_video_vertical_downscale_enable(int enable) +#else +void +gfx_set_video_vertical_downscale_enable(int enable) +#endif +{ + /* SET VIDEO SCALE IN DISPLAY CONTROLLER */ + /* Use private routine to abstract hardware */ + + gfx_set_display_video_vertical_downscale_enable(enable); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_config + * + * This routine sets the downscale type and factor for the video overlay window. + * Note: No downscaling support for RGB565 and YUV420 video formats. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_downscale_config(unsigned short type, unsigned short m) +#else +int +gfx_set_video_downscale_config(unsigned short type, unsigned short m) +#endif +{ + unsigned long downscale; + + if ((m < 1) || (m > 16)) + return GFX_STATUS_BAD_PARAMETER; + + downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL); + downscale &= + ~(RCDF_VIDEO_DOWNSCALE_FACTOR_MASK | RCDF_VIDEO_DOWNSCALE_TYPE_MASK); + downscale |= ((unsigned long)(m - 1) << RCDF_VIDEO_DOWNSCALE_FACTOR_POS); + switch (type) { + case VIDEO_DOWNSCALE_KEEP_1_OF: + downscale |= RCDF_VIDEO_DOWNSCALE_TYPE_A; + break; + case VIDEO_DOWNSCALE_DROP_1_OF: + downscale |= RCDF_VIDEO_DOWNSCALE_TYPE_B; + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + WRITE_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL, downscale); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_coefficients + * + * This routine sets the downscale filter coefficients. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4) +#else +int +gfx_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4) +#endif +{ + if ((coef1 + coef2 + coef3 + coef4) != 16) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_VID32(RCDF_VIDEO_DOWNSCALER_COEFFICIENTS, + ((unsigned long)coef1 << RCDF_VIDEO_DOWNSCALER_COEF1_POS) | + ((unsigned long)coef2 << RCDF_VIDEO_DOWNSCALER_COEF2_POS) | + ((unsigned long)coef3 << RCDF_VIDEO_DOWNSCALER_COEF3_POS) | + ((unsigned long)coef4 << RCDF_VIDEO_DOWNSCALER_COEF4_POS)); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_downscale_enable + * + * This routine enables or disables downscaling for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_downscale_enable(int enable) +#else +int +gfx_set_video_downscale_enable(int enable) +#endif +{ + unsigned long downscale; + + downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL); + if (enable) + downscale |= RCDF_VIDEO_DOWNSCALE_ENABLE; + else + downscale &= ~RCDF_VIDEO_DOWNSCALE_ENABLE; + WRITE_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL, downscale); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_window + * + * This routine sets the position and size of the video overlay window. The + * x and y positions are specified in screen relative coordinates, and may be negative. + * The size of destination region is specified in pixels. The line size + * indicates the number of bytes of source data per scanline. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_window(short x, short y, unsigned short w, + unsigned short h) +#else +int +gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) +#endif +{ + unsigned long hadjust, vadjust; + unsigned long xstart, ystart, xend, yend; + + /* SAVE PARAMETERS */ + /* These are needed to call this routine if the scale value changes. */ + + gfx_vid_xpos = x; + gfx_vid_ypos = y; + gfx_vid_width = w; + gfx_vid_height = h; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 14l; + vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l; + + /* HORIZONTAL START */ + xstart = (unsigned long)x + hadjust; + + /* HORIZONTAL END */ + /* End positions in register are non-inclusive (one more than the actual end) */ + + if ((x + w) < gfx_get_hactive()) + xend = (unsigned long)x + (unsigned long)w + hadjust; + + /* RIGHT-CLIPPING */ + else + xend = (unsigned long)gfx_get_hactive() + hadjust; + + /* VERTICAL START */ + + ystart = (unsigned long)y + vadjust; + + /* VERTICAL END */ + + if ((y + h) < gfx_get_vactive()) + yend = (unsigned long)y + (unsigned long)h + vadjust; + + /* BOTTOM-CLIPPING */ + else + yend = (unsigned long)gfx_get_vactive() + vadjust; + + /* SET VIDEO POSITION */ + + WRITE_VID32(RCDF_VIDEO_X_POS, (xend << 16) | xstart); + WRITE_VID32(RCDF_VIDEO_Y_POS, (yend << 16) | ystart); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_left_crop + * + * This routine sets the number of pixels which will be cropped from the + * beginning of each video line. The video window will begin to display only + * from the pixel following the cropped pixels, and the cropped pixels + * will be ignored. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_left_crop(unsigned short x) +#else +int +gfx_set_video_left_crop(unsigned short x) +#endif +{ + unsigned long vcfg, initread; + + vcfg = READ_VID32(RCDF_VIDEO_CONFIG); + + /* CLIPPING ON LEFT */ + /* Adjust initial read for scale, checking for divide by zero. Mask the */ + /* lower three bits when clipping 4:2:0 video. By masking the bits instead */ + /* of rounding up we ensure that we always clip less than or equal to the */ + /* desired number of pixels. This prevents visual artifacts from */ + /* over-clipping. We mask three bits to meet the HW requirement that 4:2:0 */ + /* clipping be 16-byte or 8-pixel aligned. */ + + if (gfx_vid_dstw) { + initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw; + + if (vcfg & RCDF_VCFG_4_2_0_MODE) + initread &= 0xFFF8; + } else + initread = 0; + + /* SET INITIAL READ ADDRESS */ + + vcfg &= ~RCDF_VCFG_INIT_READ_MASK; + vcfg |= (initread << 15) & RCDF_VCFG_INIT_READ_MASK; + WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_color_key + * + * This routine specifies the color key value and mask for the video overlay + * hardware. To disable color key, the color and mask should both be set to + * zero. The hardware uses the color key in the following equation: + * + * ((source data) & (color key mask)) == ((color key) & (color key mask)) + * + * If "graphics" is set to TRUE, the source data is graphics, and color key + * is an RGB value. If "graphics" is set to FALSE, the source data is the video, + * and color key is a YUV value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_color_key(unsigned long key, unsigned long mask, + int graphics) +#else +int +gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) +#endif +{ + unsigned long dcfg = 0; + + /* SET RCDF COLOR KEY VALUE */ + + WRITE_VID32(RCDF_VIDEO_COLOR_KEY, key); + WRITE_VID32(RCDF_VIDEO_COLOR_MASK, mask); + + /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */ + + dcfg = READ_VID32(RCDF_DISPLAY_CONFIG); + if (graphics & 0x01) + dcfg &= ~RCDF_DCFG_VG_CK; + else + dcfg |= RCDF_DCFG_VG_CK; + WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_filter + * + * This routine enables or disables the video overlay filters. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_filter(int xfilter, int yfilter) +#else +int +gfx_set_video_filter(int xfilter, int yfilter) +#endif +{ + unsigned long vcfg = 0; + + /* ENABLE OR DISABLE DISPLAY FILTER VIDEO OVERLAY FILTERS */ + + vcfg = READ_VID32(RCDF_VIDEO_CONFIG); + vcfg &= ~(RCDF_VCFG_X_FILTER_EN | RCDF_VCFG_Y_FILTER_EN); + if (xfilter) + vcfg |= RCDF_VCFG_X_FILTER_EN; + if (yfilter) + vcfg |= RCDF_VCFG_Y_FILTER_EN; + WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette + * + * This routine loads the video hardware palette. If a NULL pointer is + * specified, the palette is bypassed (for Redcloud, this means loading the + * palette with identity values). + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_palette(unsigned long *palette) +#else +int +gfx_set_video_palette(unsigned long *palette) +#endif +{ + unsigned long i, entry; + + /* LOAD REDCLOUD VIDEO PALETTE */ + + WRITE_VID32(RCDF_PALETTE_ADDRESS, 0); + for (i = 0; i < 256; i++) { + if (palette) + entry = palette[i]; + else + entry = i | (i << 8) | (i << 16); + WRITE_VID32(RCDF_PALETTE_DATA, entry); + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_palette_entry + * + * This routine loads a single entry of the video hardware palette. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_palette_entry(unsigned long index, unsigned long palette) +#else +int +gfx_set_video_palette_entry(unsigned long index, unsigned long palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + /* SET A SINGLE ENTRY */ + + WRITE_VID32(RCDF_PALETTE_ADDRESS, index); + WRITE_VID32(RCDF_PALETTE_DATA, palette); + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_request() + * + * This routine sets the horizontal (pixel) and vertical (line) video request + * values. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_request(short x, short y) +#else +int +gfx_set_video_request(short x, short y) +#endif +{ + /* SET DISPLAY FILTER VIDEO REQUEST */ + + x += gfx_get_htotal() - gfx_get_hsync_end() - 2; + y += gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + if ((x < 0) || (x > RCDF_VIDEO_REQUEST_MASK) || + (y < 0) || (y > RCDF_VIDEO_REQUEST_MASK)) + return GFX_STATUS_BAD_PARAMETER; + + WRITE_VID32(RCDF_VIDEO_REQUEST, + ((unsigned long)x << RCDF_VIDEO_X_REQUEST_POS) | + ((unsigned long)y << RCDF_VIDEO_Y_REQUEST_POS)); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_cursor() + * + * This routine configures the video hardware cursor. + * If the "mask"ed bits in the graphics pixel match "key", then either "color1" + * or "color2" will be used for this pixel, according to the value of bit + * number "select_color2" of the graphics pixel. + * + * key - 24 bit RGB value + * mask - 24 bit mask + * color1, color2 - RGB or YUV, depending on the current color space conversion + * select_color2 - value between 0 to 23 + * + * To disable match, a "mask" and "key" value of 0xffffff should be set, + * because the graphics pixels incoming to the video processor have maximum 16 + * bits set (0xF8FCF8). + * + * This feature is useful for disabling alpha blending of the cursor. + * Otherwise cursor image would be blurred (or completely invisible if video + * alpha is maximum value). + * Note: the cursor pixel replacements take place both inside and outside the + * video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, unsigned long color1, + unsigned long color2) +#else +int +gfx_set_video_cursor(unsigned long key, unsigned long mask, + unsigned short select_color2, unsigned long color1, + unsigned long color2) +#endif +{ + if (select_color2 > RCDF_CURSOR_COLOR_BITS) + return GFX_STATUS_BAD_PARAMETER; + key = (key & RCDF_COLOR_MASK) | ((unsigned long)select_color2 << + RCDF_CURSOR_COLOR_KEY_OFFSET_POS); + WRITE_VID32(RCDF_CURSOR_COLOR_KEY, key); + WRITE_VID32(RCDF_CURSOR_COLOR_MASK, mask); + WRITE_VID32(RCDF_CURSOR_COLOR_1, color1); + WRITE_VID32(RCDF_CURSOR_COLOR_2, color2); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_video_cursor() + * + * This routine configures the video hardware cursor. + * If the "mask"ed bits in the graphics pixel match "key", then either "color1" + * or "color2" will be used for this pixel, according to the value of bit + * number "select_color2" of the graphics pixel. + * + * key - 24 bit RGB value + * mask - 24 bit mask + * color1, color2 - RGB or YUV, depending on the current color space conversion + * select_color2 - value between 0 to 23 + * + * To disable match, a "mask" and "key" value of 0xffffff should be set, + * because the graphics pixels incoming to the video processor have maximum 16 + * bits set (0xF8FCF8). + * + * This feature is useful for disabling alpha blending of the cursor. + * Otherwise cursor image would be blurred (or completely invisible if video + * alpha is maximum value). + * Note: the cursor pixel replacements take place both inside and outside the + * video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_video_cursor_enable(int enable) +#else +int +gfx_set_video_cursor_enable(int enable) +#endif +{ + unsigned long temp = READ_VID32(RCDF_CURSOR_COLOR_KEY); + + if (enable) + temp |= RCDF_CURSOR_COLOR_KEY_ENABLE; + else + temp &= ~RCDF_CURSOR_COLOR_KEY_ENABLE; + + WRITE_VID32(RCDF_CURSOR_COLOR_KEY, temp); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_enable + * + * This routine enables or disables the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_alpha_enable(int enable) +#else +int +gfx_set_alpha_enable(int enable) +#endif +{ + unsigned long address = 0, value = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = RCDF_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 5); + value = READ_VID32(address); + if (enable) + value |= RCDF_ACTRL_WIN_ENABLE; + else + value &= ~(RCDF_ACTRL_WIN_ENABLE); + WRITE_VID32(address, value); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_window + * + * This routine sets the size of the currently selected alpha region. + * Note: "x" and "y" are signed to enable using negative values needed for + * implementing workarounds of hardware issues. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_alpha_window(short x, short y, + unsigned short width, unsigned short height) +#else +int +gfx_set_alpha_window(short x, short y, + unsigned short width, unsigned short height) +#endif +{ + unsigned long address = 0; + + /* CHECK FOR CLIPPING */ + + if ((x + width) > gfx_get_hactive()) + width = gfx_get_hactive() - x; + if ((y + height) > gfx_get_vactive()) + height = gfx_get_vactive() - y; + + /* ADJUST POSITIONS */ + + x += gfx_get_htotal() - gfx_get_hsync_end() - 2; + y += gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = RCDF_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 5); + + /* END POSITIONS IN REGISTERS ARE NON-INCLUSIVE (ONE MORE THAN ACTUAL END) */ + + WRITE_VID32(address, (unsigned long)x | + ((unsigned long)(x + width) << 16)); + WRITE_VID32(address + 8, (unsigned long)y | + ((unsigned long)(y + height) << 16)); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_value + * + * This routine sets the alpha value for the currently selected alpha + * region. It also specifies an increment/decrement value for fading. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_alpha_value(unsigned char alpha, char delta) +#else +int +gfx_set_alpha_value(unsigned char alpha, char delta) +#endif +{ + unsigned long address = 0, value = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = RCDF_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 5); + value = READ_VID32(address); + value &= RCDF_ACTRL_WIN_ENABLE; /* keep only enable bit */ + value |= (unsigned long)alpha; + value |= (((unsigned long)delta) & 0xff) << 8; + value |= RCDF_ACTRL_LOAD_ALPHA; + WRITE_VID32(address, value); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_priority + * + * This routine sets the priority of the currently selected alpha region. + * A higher value indicates a higher priority. + * Note: Priority of enabled alpha windows must be different. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_alpha_priority(int priority) +#else +int +gfx_set_alpha_priority(int priority) +#endif +{ + unsigned long pos = 0, value = 0; + + if (priority > 3) + return (GFX_STATUS_BAD_PARAMETER); + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + value = READ_VID32(RCDF_VID_ALPHA_CONTROL); + pos = 16 + (gfx_alpha_select << 1); + value &= ~(0x03l << pos); + value |= (unsigned long)priority << pos; + WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_color + * + * This routine sets the color to be displayed inside the currently selected + * alpha window when there is a color key match (when the alpha color + * mechanism is enabled). + * "color" is an RGB value (for RGB blending) or a YUV value (for YUV blending). + * In Interlaced YUV blending mode, Y/2 value should be used. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_alpha_color(unsigned long color) +#else +int +gfx_set_alpha_color(unsigned long color) +#endif +{ + unsigned long address = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = RCDF_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 5); + WRITE_VID32(address, color); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_alpha_color_enable + * + * Enable or disable the color mechanism in the alpha window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_alpha_color_enable(int enable) +#else +int +gfx_set_alpha_color_enable(int enable) +#endif +{ + unsigned long color; + unsigned long address = 0; + + if (gfx_alpha_select > 2) + return (GFX_STATUS_UNSUPPORTED); + address = RCDF_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 5); + color = READ_VID32(address); + if (enable) + color |= RCDF_ALPHA_COLOR_ENABLE; + else + color &= ~RCDF_ALPHA_COLOR_ENABLE; + WRITE_VID32(address, color); + return (GFX_STATUS_OK); +} + +/*--------------------------------------------------------------------------- + * gfx_set_no_ck_outside_alpha + * + * This function affects where inside the video window color key or chroma + * key comparison is done: + * If enable is TRUE, color/chroma key comparison is performed only inside + * the enabled alpha windows. Outside the (enabled) alpha windows, only video + * is displayed if color key is used, and only graphics is displayed if chroma + * key is used. + * If enable is FALSE, color/chroma key comparison is performed in all the + * video window area. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_set_no_ck_outside_alpha(int enable) +#else +int +gfx_set_no_ck_outside_alpha(int enable) +#endif +{ + unsigned long value; + + value = READ_VID32(RCDF_VID_ALPHA_CONTROL); + if (enable) + WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value | RCDF_NO_CK_OUTSIDE_ALPHA); + else + WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value & ~RCDF_NO_CK_OUTSIDE_ALPHA); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_clock_frequency + * + * This routine returns the current clock frequency in 16.16 format. + * It reads the current register value and finds the match in the table. + * If no match is found, this routine returns 0. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_clock_frequency(void) +#else +unsigned long +gfx_get_clock_frequency(void) +#endif +{ + Q_WORD msr_value; + RCDFPLLENTRY *PLLTable; + unsigned int index; + unsigned long value, mask = 0x00001FFF; + unsigned long post_div3 = 0, pre_mult2 = 0; + + /* READ PLL SETTING */ + + gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value); + value = msr_value.high & mask; + + /* READ DIVISOR SETTINGS */ + + if ((gfx_cpu_version & 0xFF00) == 0x200) { + PLLTable = RCDF_PLLtable48MHz; + + gfx_msr_read(RC_ID_MCP, MCP_SYS_RSTPLL, &msr_value); + post_div3 = (msr_value.low & MCP_DOTPOSTDIV3) ? 1 : 0; + pre_mult2 = (msr_value.low & MCP_DOTPREMULT2) ? 1 : 0; + } else + PLLTable = RCDF_PLLtable14MHz; + + /* SEARCH FOR A MATCH */ + + for (index = 0; index < NUM_RCDF_FREQUENCIES; index++) { + if ((PLLTable[index].pll_value & mask) == value && + post_div3 == PLLTable[index].post_div3 && + pre_mult2 == PLLTable[index].pre_mul2) + return (PLLTable[index].frequency); + } + return (0); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*--------------------------------------------------------------------------- + * gfx_get_sync_polarities + * + * This routine returns the polarities of the sync pulses: + * Bit 0: Set if negative horizontal polarity. + * Bit 1: Set if negative vertical polarity. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_sync_polarities(void) +#else +int +gfx_get_sync_polarities(void) +#endif +{ + int polarities = 0; + + if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_CRT_HSYNC_POL) + polarities |= 1; + if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_CRT_VSYNC_POL) + polarities |= 2; + return (polarities); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_palette_entry + * + * This routine returns a single palette entry. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_palette_entry(unsigned long index, unsigned long *palette) +#else +int +gfx_get_video_palette_entry(unsigned long index, unsigned long *palette) +#endif +{ + if (index > 0xFF) + return GFX_STATUS_BAD_PARAMETER; + + /* READ A SINGLE ENTRY */ + + WRITE_VID32(RCDF_PALETTE_ADDRESS, index); + *palette = READ_VID32(RCDF_PALETTE_DATA); + + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_enable + * + * This routine returns the value "one" if video overlay is currently enabled, + * otherwise it returns the value "zero". + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_enable(void) +#else +int +gfx_get_video_enable(void) +#endif +{ + if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_VID_EN) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_format + * + * This routine returns the current video overlay format. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_format(void) +#else +int +gfx_get_video_format(void) +#endif +{ + unsigned long ctrl, vcfg; + + ctrl = READ_VID32(RCDF_VID_ALPHA_CONTROL); + vcfg = READ_VID32(RCDF_VIDEO_CONFIG); + + if (ctrl & RCDF_VIDEO_INPUT_IS_RGB) { + switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) { + case RCDF_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_RGB; + case RCDF_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_P2M_P2L_P1M_P1L; + case RCDF_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_P1M_P1L_P2M_P2L; + case RCDF_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_P1M_P2L_P2M_P1L; + } + } + + if (vcfg & RCDF_VCFG_4_2_0_MODE) { + switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) { + case RCDF_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_Y0Y1Y2Y3; + case RCDF_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_Y3Y2Y1Y0; + case RCDF_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_Y1Y0Y3Y2; + case RCDF_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_Y1Y2Y3Y0; + } + } else { + switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) { + case RCDF_VCFG_UYVY_FORMAT: + return VIDEO_FORMAT_UYVY; + case RCDF_VCFG_Y2YU_FORMAT: + return VIDEO_FORMAT_Y2YU; + case RCDF_VCFG_YUYV_FORMAT: + return VIDEO_FORMAT_YUYV; + case RCDF_VCFG_YVYU_FORMAT: + return VIDEO_FORMAT_YVYU; + } + } + return (GFX_STATUS_ERROR); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_src_size + * + * This routine returns the size of the source video overlay buffer. The + * return value is (height << 16) | width. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_src_size(void) +#else +unsigned long +gfx_get_video_src_size(void) +#endif +{ + unsigned long width, height, scale, delta; + int down_enable; + + /* DETERMINE SOURCE WIDTH FROM THE DISPLAY FILTER VIDEO LINE SIZE */ + + width = (READ_VID32(RCDF_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_LINE_SIZE_UPPER) + width += 512l; + + /* DETERMINE SOURCE HEIGHT FROM THE DISPLAY FILTER HEIGHT AND SCALE VALUES */ + /* There is no true "source buffer size" in Redcloud. Instead, the VG module */ + /* provides video data as needed on a per-line basis. The source buffer size */ + /* is always assumed to equal the amount of required video data. The returned */ + /* height is equal to the height of the required video buffer data (before all */ + /* scaling.) */ + + scale = (READ_VID32(RCDF_VIDEO_SCALE) >> 16) & 0x3FFF; + height = ((READ_VID32(RCDF_VIDEO_Y_POS) >> 16) & 0x7FF) - + (READ_VID32(RCDF_VIDEO_Y_POS) & 0x7FF); + delta = gfx_get_video_downscale_delta(); + down_enable = gfx_get_video_vertical_downscale_enable(); + + /* REVERSE UPSCALING */ + + if (height) + height = ((scale * (height - 1l)) / 0x2000l) + 2l; + + /* REVERSE DOWNSCALING */ + /* Original lines = height * (0x3FFF + delta) / 0x3FFF */ + /* As this may cause rounding errors, we add 1 to the */ + /* returned source size. The return value of this */ + /* function could thus be off by 1. */ + + if (down_enable && height) + height = ((height * (0x3FFFl + delta)) / 0x3FFFl) + 1; + + return ((height << 16) | width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_line_size + * + * This routine returns the line size of the source video overlay buffer, in + * pixels. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_line_size(void) +#else +unsigned long +gfx_get_video_line_size(void) +#endif +{ + unsigned long width = 0; + + /* DETERMINE SOURCE WIDTH FROM THE RCDF VIDEO LINE SIZE */ + + width = (READ_VID32(RCDF_VIDEO_CONFIG) >> 7) & 0x000001FE; + if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_LINE_SIZE_UPPER) + width += 512l; + return (width); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_xclip + * + * This routine returns the number of bytes clipped on the left side of a + * video overlay line (skipped at beginning). + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_xclip(void) +#else +unsigned long +gfx_get_video_xclip(void) +#endif +{ + unsigned long clip = 0; + + /* DETERMINE SOURCE WIDTH FROM THE RCDF VIDEO LINE SIZE */ + + clip = (READ_VID32(RCDF_VIDEO_CONFIG) >> 14) & 0x000007FC; + return (clip); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_offset + * + * This routine returns the current offset for the video overlay buffer. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_offset(void) +#else +unsigned long +gfx_get_video_offset(void) +#endif +{ + return (gfx_get_display_video_offset()); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_yuv_offsets + * + * This routine returns the current offsets for the video overlay buffer when in 4:2:0. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset, + unsigned long *voffset) +#else +void +gfx_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset, + unsigned long *voffset) +#endif +{ + gfx_get_display_video_yuv_offsets(yoffset, uoffset, voffset); +} + +/*----------------------------------------------------------------------------- + * gfx_get_video_yuv_pitch + * + * This routine returns the current pitch values for the video overlay buffer. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch) +#else +void +gfx_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch) +#endif +{ + gfx_get_display_video_yuv_pitch(ypitch, uvpitch); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_scale + * + * This routine returns the scale factor for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_scale(void) +#else +unsigned long +gfx_get_video_scale(void) +#endif +{ + return (READ_VID32(RCDF_VIDEO_SCALE)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_delta + * + * This routine returns the vertical downscale factor for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_downscale_delta(void) +#else +unsigned long +gfx_get_video_downscale_delta(void) +#endif +{ + /* USE PRIVATE ROUTINE TO ABSTRACT THE DIPSLAY CONTROLLER */ + + return (gfx_get_display_video_downscale_delta()); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_vertical_downscale_enable + * + * This routine returns the vertical downscale enable for the video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_vertical_downscale_enable(void) +#else +int +gfx_get_video_vertical_downscale_enable(void) +#endif +{ + /* USE PRIVATE ROUTINE TO ABSTRACT THE DIPSLAY CONTROLLER */ + + return (gfx_get_display_video_downscale_enable()); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_config + * + * This routine returns the current type and value of video downscaling. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_downscale_config(unsigned short *type, unsigned short *m) +#else +int +gfx_get_video_downscale_config(unsigned short *type, unsigned short *m) +#endif +{ + unsigned long downscale; + + downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL); + *m = (unsigned short)((downscale & RCDF_VIDEO_DOWNSCALE_FACTOR_MASK) >> + RCDF_VIDEO_DOWNSCALE_FACTOR_POS) + 1; + + switch (downscale & RCDF_VIDEO_DOWNSCALE_TYPE_MASK) { + case RCDF_VIDEO_DOWNSCALE_TYPE_A: + *type = VIDEO_DOWNSCALE_KEEP_1_OF; + break; + case RCDF_VIDEO_DOWNSCALE_TYPE_B: + *type = VIDEO_DOWNSCALE_DROP_1_OF; + break; + default: + return GFX_STATUS_ERROR; + break; + } + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_coefficients + * + * This routine returns the current video downscaling coefficients. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4) +#else +void +gfx_get_video_downscale_coefficients(unsigned short *coef1, + unsigned short *coef2, + unsigned short *coef3, + unsigned short *coef4) +#endif +{ + unsigned long coef; + + coef = READ_VID32(RCDF_VIDEO_DOWNSCALER_COEFFICIENTS); + *coef1 = + (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF1_POS) & + RCDF_VIDEO_DOWNSCALER_COEF_MASK); + *coef2 = + (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF2_POS) & + RCDF_VIDEO_DOWNSCALER_COEF_MASK); + *coef3 = + (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF3_POS) & + RCDF_VIDEO_DOWNSCALER_COEF_MASK); + *coef4 = + (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF4_POS) & + RCDF_VIDEO_DOWNSCALER_COEF_MASK); + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_downscale_enable + * + * This routine returns 1 if video downscaling is currently enabled, + * or 0 if it is currently disabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_video_downscale_enable(int *enable) +#else +void +gfx_get_video_downscale_enable(int *enable) +#endif +{ + if (READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL) & + RCDF_VIDEO_DOWNSCALE_ENABLE) + *enable = 1; + else + *enable = 0; + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_dst_size + * + * This routine returns the size of the displayed video overlay window. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_dst_size(void) +#else +unsigned long +gfx_get_video_dst_size(void) +#endif +{ + unsigned long xsize, ysize; + + xsize = READ_VID32(RCDF_VIDEO_X_POS); + xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF); + ysize = READ_VID32(RCDF_VIDEO_Y_POS); + ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF); + return ((ysize << 16) | xsize); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_position + * + * This routine returns the position of the video overlay window. The + * return value is (ypos << 16) | xpos. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_position(void) +#else +unsigned long +gfx_get_video_position(void) +#endif +{ + unsigned long hadjust, vadjust; + unsigned long xpos, ypos; + + /* READ HARDWARE POSITION */ + + xpos = READ_VID32(RCDF_VIDEO_X_POS) & 0x000007FF; + ypos = READ_VID32(RCDF_VIDEO_Y_POS) & 0x000007FF; + + /* GET ADJUSTMENT VALUES */ + /* Use routines to abstract version of display controller. */ + + hadjust = + (unsigned long)gfx_get_htotal() - + (unsigned long)gfx_get_hsync_end() - 14l; + vadjust = + (unsigned long)gfx_get_vtotal() - + (unsigned long)gfx_get_vsync_end() + 1l; + xpos -= hadjust; + ypos -= vadjust; + return ((ypos << 16) | (xpos & 0x0000FFFF)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key + * + * This routine returns the current video color key value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_color_key(void) +#else +unsigned long +gfx_get_video_color_key(void) +#endif +{ + return (READ_VID32(RCDF_VIDEO_COLOR_KEY)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_mask + * + * This routine returns the current video color mask value. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_get_video_color_key_mask(void) +#else +unsigned long +gfx_get_video_color_key_mask(void) +#endif +{ + return (READ_VID32(RCDF_VIDEO_COLOR_MASK)); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_color_key_src + * + * This routine returns 0 for video data compare, 1 for graphics data. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_color_key_src(void) +#else +int +gfx_get_video_color_key_src(void) +#endif +{ + if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_VG_CK) + return (0); + return (1); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_filter + * + * This routine returns if the filters are currently enabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_filter(void) +#else +int +gfx_get_video_filter(void) +#endif +{ + int retval = 0; + + if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_X_FILTER_EN) + retval |= 1; + if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_Y_FILTER_EN) + retval |= 2; + return (retval); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_request + * + * This routine returns the horizontal (pixel) and vertical (lines) video + * request values. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_request(short *x, short *y) +#else +int +gfx_get_video_request(short *x, short *y) +#endif +{ + unsigned long request = 0; + + request = (READ_VID32(RCDF_VIDEO_REQUEST)); + *x = (short)((request >> RCDF_VIDEO_X_REQUEST_POS) & + RCDF_VIDEO_REQUEST_MASK); + *y = (short)((request >> RCDF_VIDEO_Y_REQUEST_POS) & + RCDF_VIDEO_REQUEST_MASK); + + *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2; + *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1; + + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_get_video_cursor() + * + * This routine configures the video hardware cursor. + * If the "mask"ed bits in the graphics pixel match "key", then either "color1" + * or "color2" will be used for this pixel, according to the value of the bit + * in offset "select_color2". + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +redcloud_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, + unsigned long *color1, unsigned short *color2) +#else +int +gfx_get_video_cursor(unsigned long *key, unsigned long *mask, + unsigned short *select_color2, unsigned long *color1, + unsigned short *color2) +#endif +{ + *select_color2 = + (unsigned short)(READ_VID32(RCDF_CURSOR_COLOR_KEY) >> + RCDF_CURSOR_COLOR_KEY_OFFSET_POS); + *key = READ_VID32(RCDF_CURSOR_COLOR_KEY) & RCDF_COLOR_MASK; + *mask = READ_VID32(RCDF_CURSOR_COLOR_MASK) & RCDF_COLOR_MASK; + *color1 = READ_VID32(RCDF_CURSOR_COLOR_1) & RCDF_COLOR_MASK; + *color2 = + (unsigned short)(READ_VID32(RCDF_CURSOR_COLOR_2) & RCDF_COLOR_MASK); + return (0); +} + +/*--------------------------------------------------------------------------- + * gfx_read_crc + * + * This routine returns the hardware CRC value, which is used for automated + * testing. The value is like a checksum, but will change if pixels move + * locations. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_read_crc(void) +#else +unsigned long +gfx_read_crc(void) +#endif +{ + Q_WORD msr_value; + unsigned long crc = 0xFFFFFFFF; + + /* DISABLE 32-BIT CRCS */ + /* For GX1.x, this is a reserved bit, and is assumed to be a benign access */ + + gfx_msr_read(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value); + msr_value.low &= ~RCDF_DIAG_32BIT_CRC; + gfx_msr_write(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value); + + if (gfx_test_timing_active()) { + /* WAIT UNTIL ACTIVE DISPLAY */ + + while (!gfx_test_vertical_active()) ; + + /* RESET CRC DURING ACTIVE DISPLAY */ + + WRITE_VID32(RCDF_VID_CRC, 0); + WRITE_VID32(RCDF_VID_CRC, 1); + + /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */ + + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + crc = READ_VID32(RCDF_VID_CRC) >> 8; + } + return (crc); +} + +/*--------------------------------------------------------------------------- + * gfx_read_crc32 + * + * This routine returns the 32-bit hardware CRC value, which is used for automated + * testing. The value is like a checksum, but will change if pixels move + * locations. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_read_crc32(void) +#else +unsigned long +gfx_read_crc32(void) +#endif +{ + Q_WORD msr_value; + unsigned long crc = 0xFFFFFFFF; + + /* ENABLE 32-BIT CRCS */ + /* For GX1.x, this is a reserved bit, and is assumed to be a benign access */ + + gfx_msr_read(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value); + msr_value.low |= RCDF_DIAG_32BIT_CRC; + gfx_msr_write(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value); + + if (gfx_test_timing_active()) { + /* WAIT UNTIL ACTIVE DISPLAY */ + + while (!gfx_test_vertical_active()) ; + + /* RESET CRC DURING ACTIVE DISPLAY */ + + WRITE_VID32(RCDF_VID_CRC, 0); + WRITE_VID32(RCDF_VID_CRC, 1); + + /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */ + + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + crc = READ_VID32(RCDF_VID_CRC32); + } + return (crc); +} + +/*--------------------------------------------------------------------------- + * gfx_read_window_crc + * + * This routine returns the hardware CRC value for a subsection of the display. + * This value is used to debug whole-screen CRC failures. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +redcloud_read_window_crc(int source, unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + int crc32) +#else +unsigned long +gfx_read_window_crc(int source, unsigned short x, unsigned short y, + unsigned short width, unsigned short height, int crc32) +#endif +{ + Q_WORD msr_value; + unsigned long xpos, ypos, crc = 0; + unsigned long old_fmt = 0; + unsigned int vsync_active_base, vsync_inactive_base, hsync_active_base; + unsigned int vsync_active_shift, vsync_inactive_shift, hsync_active_shift; + unsigned int vsync_bit, hsync_bit, sync_polarities = 0; + + /* CONFIGURE DISPLAY FILTER TO LOAD DATA ONTO LOWER 32-BITS */ + + msr_value.high = 0; + msr_value.low = + (source == CRC_SOURCE_GFX_DATA) ? (RCDF_MBD_DIAG_EN0 | 0x0000000F) + : (RCDF_MBD_DIAG_EN0 | 0x0000000B); + gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value); + + /* CONFIGURE DISPLAY FILTER FOR APPROPRIATE OUTPUT */ + + if (source != CRC_SOURCE_GFX_DATA) { + gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value); + old_fmt = msr_value.low; + msr_value.low &= ~(RCDF_CONFIG_FMT_MASK); + msr_value.low |= ((source == CRC_SOURCE_FP_DATA) ? RCDF_CONFIG_FMT_FP : + RCDF_CONFIG_FMT_CRT); + gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value); + } + + /* CONFIGURE MCP TO LOAD REGB DATA ONTO UPPER 32-BITS */ + + msr_value.low = MCP_MBD_DIAG_EN1 | 0x00050000; + gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value); + + /* ENABLE HW CLOCK GATING AND SET MCP CLOCK TO DOT CLOCK */ + + msr_value.low = 1l; + gfx_msr_write(RC_ID_MCP, MBD_MSR_PM, &msr_value); + msr_value.low = 0; + gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value); + msr_value.low = 3; + gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value); + + /* DISABLE MCP ACTIONS */ + + msr_value.high = 0x00000000; + msr_value.low = 0x00000000; + gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value); + + /* SET APPROPRIATE BASE ADDRESS */ + /* M-Sets use normal diag bits, while N-Sets use inverted diag bits */ + /* We thus use the M-sets when polling for a high signal and the N */ + /* sets when polling for a low signal. */ + + if (source != CRC_SOURCE_GFX_DATA) { + sync_polarities = gfx_get_sync_polarities(); + vsync_bit = 29; + hsync_bit = 30; + } else { + vsync_bit = 25; + hsync_bit = 26; + } + + if (sync_polarities & 1) { + hsync_active_base = MCP_SETM0CTL; + hsync_active_shift = 2; + } else { + hsync_active_base = MCP_SETN0CTL; + hsync_active_shift = 1; + } + if (sync_polarities & 2) { + vsync_active_base = MCP_SETM0CTL; + vsync_inactive_base = MCP_SETN0CTL; + vsync_active_shift = 2; + vsync_inactive_shift = 1; + } else { + vsync_active_base = MCP_SETN0CTL; + vsync_inactive_base = MCP_SETM0CTL; + vsync_active_shift = 1; + vsync_inactive_shift = 2; + } + + /* SET STATE TRANSITIONS */ + + /* STATE 0-1 TRANSITION (SET 0) */ + /* XState = 00 and VSync Inactive */ + /* Note: DF VSync = Diag Bus Bit 29 */ + /* VG VSync = Diag Bus Bit 25 */ + + msr_value.low = 0x000000A0; + msr_value.high = 0x00008000 | ((unsigned long)vsync_bit << 16) | + ((unsigned long)vsync_bit << 21) | ((unsigned long)vsync_bit << 26); + gfx_msr_write(RC_ID_MCP, vsync_inactive_base, &msr_value); + + /* STATE 1-2 TRANSITION (SET 4) */ + /* XState = 01 and VSync Active */ + + msr_value.low = 0x000000C0; + gfx_msr_write(RC_ID_MCP, vsync_active_base + 4, &msr_value); + + /* STATE 2-3 TRANSITION (SET 1) */ + /* XState = 10 and VSync Inactive */ + + msr_value.low = 0x00000120; + gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 1, &msr_value); + + /* HORIZONTAL COUNTER (SET 5) */ + /* XState = 10 and HSync Active */ + /* Notes: DF HSync = Diag Bus Bit 30 */ + /* VG HSync = Diag Bus Bit 26 */ + + msr_value.high = 0x00008000 | ((unsigned long)hsync_bit << 16) | + ((unsigned long)hsync_bit << 21) | ((unsigned long)hsync_bit << 26); + msr_value.low = 0x00000120; + gfx_msr_write(RC_ID_MCP, hsync_active_base + 5, &msr_value); + + /* HORIZONTAL COUNTER RESET (SET 4) */ + /* XState = 10 and H. Counter = limit */ + /* Note: H. Counter is lower 16-bits of */ + /* RegB. */ + + msr_value.high = 0x00000000; + msr_value.low = 0x00000128; + gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 4, &msr_value); + + /* CRC TRIGGER (SET 0) */ + /* Cmp0 <= xpos < Cmp1 */ + /* Cmp2 <= ypos < Cmp2 */ + + msr_value.high = 0x00000000; + msr_value.low = 0x10C20120; + gfx_msr_write(RC_ID_MCP, vsync_active_base, &msr_value); + + /* SET COMPARATOR VALUES */ + /* Note: The VG data outputs from the DF are delayed by one pixel clock. */ + /* In this mode, we thus add one to horizontal comparator limits. */ + + /* COMPARATOR 0 */ + /* Lower limit = xpos + (h_blank_pixels - 1) - 3 */ + /* Notes: */ + /* 1. 3 is the pipeline delay for MCP register */ + /* data to access the diag bus */ + /* 2. h_blank_pixels = HTOTAL - HSYNC_END */ + + xpos = (unsigned long)x + ((unsigned long)gfx_get_htotal() - + (unsigned long)gfx_get_hsync_end() - 1l) - 3l; + if (source == CRC_SOURCE_GFX_DATA) + xpos++; + msr_value.high = 0x00000000; + msr_value.low = xpos; + gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0, &msr_value); + + /* COMPARATOR 1 */ + /* Upper limit = xpos + width + (h_blank_pixels - 1) - 3 */ + + msr_value.low = xpos + (unsigned long)width; + gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 2, &msr_value); + + /* COMPARATOR 2 */ + /* Lower limit = ypos + v_blank_pixels */ + /* Notes: */ + /* 1. v_blank_pixels = VTOTAL - VSYNC_END */ + + ypos = (unsigned long)y + (unsigned long)gfx_get_vtotal() - + (unsigned long)gfx_get_vsync_end(); + msr_value.low = ypos << 16; + gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 4, &msr_value); + + /* COMPARATOR 3 */ + /* Upper limit = ypos + height + v_blank_pixels */ + + msr_value.low = (ypos + (unsigned long)height) << 16; + gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 6, &msr_value); + + /* SET COMPARATOR MASKS */ + + /* COMPARATORS 0 AND 1 REFER TO LOWER 16 BITS OF REGB */ + + msr_value.high = 0x00000000; + msr_value.low = 0x0000FFFF; + gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 2, &msr_value); + + /* COMPARATORS 2 AND 3 REFER TO UPPER 16 BITS OF REGB */ + + msr_value.low = 0xFFFF0000; + gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 4, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 6, &msr_value); + + /* SET REGA MASK TO CRC ONLY 24 BITS OF DATA */ + + msr_value.high = 0x00000000; + msr_value.low = 0x00FFFFFF; + gfx_msr_write(RC_ID_MCP, MCP_REGAMASK, &msr_value); + + /* SET REGB VALUE */ + /* Lower 16 bits use HTOTAL - SYNC TIME - 1 to set the counter rollover limit. */ + /* Upper 16 bits use 0xFFFF to remove auto-clear behavior. */ + + msr_value.high = 0x00000000; + msr_value.low = 0xFFFF0000 | + ((gfx_get_htotal() - (gfx_get_hsync_end() - gfx_get_hsync_start()) - + 1) & 0xFFFF); + gfx_msr_write(RC_ID_MCP, MCP_REGBVAL, &msr_value); + + /* PROGRAM ACTIONS */ + + /* GOTO STATE 01 */ + + msr_value.high = 0x00000000; + msr_value.low = 0x00000008 | (1l << vsync_inactive_shift); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 14, &msr_value); + + /* GOTO STATE 10 */ + + msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16)); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 15, &msr_value); + + /* GOTO STATE 11 */ + + msr_value.low = 0x00000080 | (1l << (vsync_inactive_shift + 4)); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 16, &msr_value); + + /* CLEAR REGB (COUNTERS) */ + /* RegB is cleared upon transitioning to state 10 */ + /* RegA is not cleared as the initial value must be 0x00000001 */ + + msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16)); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0, &msr_value); + + /* CRC INTO REGA */ + /* INCREMENT H. COUNTER */ + /* cmp0 <= xpos < cmp1 */ + /* cmp2 <= ypos < cmp3 */ + /* XState = 10 */ + + msr_value.low = 0x00000008 | (1l << vsync_active_shift) | + 0x00800000 | (1l << (hsync_active_shift + 20)); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 1, &msr_value); + + /* INCREMENT V. COUNTER */ + /* V. Counter is incremented when the H. Counter */ + /* rolls over. */ + + msr_value.low = 0x00080000 | (1l << (vsync_inactive_shift + 16)); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 2, &msr_value); + + /* CLEAR ALL OTHER ACTIONS */ + /* This prevents side-effects from previous accesses to the MCP */ + /* debug logic. */ + msr_value.low = 0x00000000; + msr_value.high = 0x00000000; + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 3, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 4, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 5, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 6, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 7, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 8, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 9, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 10, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 11, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 12, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 13, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 17, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 18, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 19, &msr_value); + gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 20, &msr_value); + + /* SET REGA CRC VALUE TO 1 OR 0 */ + + if (!crc32) + msr_value.low = 0x00000001; + gfx_msr_write(RC_ID_MCP, MCP_REGA, &msr_value); + + /* SET XSTATE TO 0 */ + + msr_value.low = 0; + msr_value.high = 0; + gfx_msr_write(RC_ID_MCP, MCP_XSTATE, &msr_value); + + /* CONFIGURE DIAG CONTROL */ + /* Set all four comparators to watch the upper diag bus. */ + /* Set REGA action1 to legacy CRC or 32-bit CRC. */ + /* Set REGB action1 to increment lower 16 bits and clear at limit. */ + /* Set REGB action2 to increment upper 16 bits. */ + /* Enable all actions. */ + + if (crc32) + msr_value.low = 0x9A820055; + else + msr_value.low = 0x9A840055; + msr_value.high = 0x00000000; + gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value); + + /* DELAY TWO FRAMES */ + + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + while (gfx_test_vertical_active()) ; + while (!gfx_test_vertical_active()) ; + + /* VERIFY THAT XSTATE = 11 */ + + gfx_msr_read(RC_ID_MCP, MCP_XSTATE, &msr_value); + if ((msr_value.low & 3) == 3) { + gfx_msr_read(RC_ID_MCP, MCP_REGA, &msr_value); + + crc = msr_value.low; + if (!crc32) + crc &= 0xFFFFFF; + } + + /* DISABLE MCP AND DF DIAG BUS OUTPUTS */ + + msr_value.low = 0x00000000; + msr_value.high = 0x00000000; + gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value); + gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value); + + /* DISABLE MCP ACTIONS */ + + msr_value.high = 0x00000000; + msr_value.low = 0x00000000; + gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value); + + /* RESTORE PREVIOUS OUTPUT FORMAT */ + + if (source != CRC_SOURCE_GFX_DATA) { + gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value); + msr_value.low = old_fmt; + gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value); + } + return crc; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_enable + * + * This routine returns 1 if the selected alpha window is currently + * enabled, or 0 if it is currently disabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_alpha_enable(int *enable) +#else +void +gfx_get_alpha_enable(int *enable) +#endif +{ + unsigned long value = 0; + + *enable = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(RCDF_ALPHA_CONTROL_1 + + ((unsigned long)gfx_alpha_select << 5)); + if (value & RCDF_ACTRL_WIN_ENABLE) + *enable = 1; + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_size + * + * This routine returns the size of the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height) +#else +void +gfx_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height) +#endif +{ + unsigned long value = 0; + + *x = 0; + *y = 0; + *width = 0; + *height = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(RCDF_ALPHA_XPOS_1 + + ((unsigned long)gfx_alpha_select << 5)); + *x = (unsigned short)(value & 0x000007FF); + *width = (unsigned short)((value >> 16) & 0x000007FF) - *x; + value = + READ_VID32(RCDF_ALPHA_YPOS_1 + + ((unsigned long)gfx_alpha_select << 5)); + *y = (unsigned short)(value & 0x000007FF); + *height = (unsigned short)((value >> 16) & 0x000007FF) - *y; + } + *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2; + *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1; + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_value + * + * This routine returns the alpha value and increment/decrement value of + * the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_alpha_value(unsigned char *alpha, char *delta) +#else +void +gfx_get_alpha_value(unsigned char *alpha, char *delta) +#endif +{ + unsigned long value = 0; + + *alpha = 0; + *delta = 0; + if (gfx_alpha_select <= 2) { + value = + READ_VID32(RCDF_ALPHA_CONTROL_1 + + ((unsigned long)gfx_alpha_select << 5)); + *alpha = (unsigned char)(value & 0x00FF); + *delta = (char)((value >> 8) & 0x00FF); + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_priority + * + * This routine returns the priority of the currently selected alpha region. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_alpha_priority(int *priority) +#else +void +gfx_get_alpha_priority(int *priority) +#endif +{ + unsigned long pos = 0, value = 0; + + *priority = 0; + if (gfx_alpha_select <= 2) { + value = READ_VID32(RCDF_VID_ALPHA_CONTROL); + pos = 16 + (gfx_alpha_select << 1); + *priority = (int)((value >> pos) & 3); + } + return; +} + +/*--------------------------------------------------------------------------- + * gfx_get_alpha_color + * + * This routine returns the color register value for the currently selected + * alpha region. Bit 24 is set if the color register is enabled. + *--------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +void +redcloud_get_alpha_color(unsigned long *color) +#else +void +gfx_get_alpha_color(unsigned long *color) +#endif +{ + *color = 0; + if (gfx_alpha_select <= 2) { + *color = + READ_VID32(RCDF_ALPHA_COLOR_1 + + ((unsigned long)gfx_alpha_select << 5)); + } + return; +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vip_1200.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vip_1200.c new file mode 100644 index 000000000..f2458f64a --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vip_1200.c @@ -0,0 +1,793 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vip_1200.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ +/* + * $Workfile: vip_1200.c $ + * + * This file contains routines to control the SC1200 video input port (VIP) hardware. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +int sc1200_set_vip_enable(int enable); +int sc1200_set_vip_capture_run_mode(int mode); +int sc1200_set_vip_base(unsigned long even, unsigned long odd); +int sc1200_set_vip_pitch(unsigned long pitch); +int sc1200_set_vip_mode(int mode); +int sc1200_set_vbi_enable(int enable); +int sc1200_set_vbi_mode(int mode); +int sc1200_set_vbi_base(unsigned long even, unsigned long odd); +int sc1200_set_vbi_pitch(unsigned long pitch); +int sc1200_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines); +int sc1200_set_vbi_interrupt(int enable); +int sc1200_set_vip_bus_request_threshold_high(int enable); +int sc1200_set_vip_last_line(int last_line); +int sc1200_test_vip_odd_field(void); +int sc1200_test_vip_bases_updated(void); +int sc1200_test_vip_fifo_overflow(void); +int sc1200_get_vip_line(void); + +/* READ ROUTINES IN GFX_VIP.C */ + +int sc1200_get_vip_enable(void); +unsigned long sc1200_get_vip_base(int odd); +unsigned long sc1200_get_vip_pitch(void); +int sc1200_get_vip_mode(void); +int sc1200_get_vbi_enable(void); +int sc1200_get_vbi_mode(void); +unsigned long sc1200_get_vbi_base(int odd); +unsigned long sc1200_get_vbi_pitch(void); +unsigned long sc1200_get_vbi_direct(int odd); +int sc1200_get_vbi_interrupt(void); +int sc1200_get_vip_bus_request_threshold_high(void); + +/*----------------------------------------------------------------------------- + * gfx_set_vip_enable + * + * This routine enables or disables the writes to memory from the video port. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vip_enable(int enable) +#else +int +gfx_set_vip_enable(int enable) +#endif +{ + unsigned long value; + + value = READ_VIP32(SC1200_VIP_CONTROL); + if (enable) + value |= SC1200_VIP_DATA_CAPTURE_EN; + else + value &= ~SC1200_VIP_DATA_CAPTURE_EN; + WRITE_VIP32(SC1200_VIP_CONTROL, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_capture_run_mode + * + * This routine selects VIP capture run mode. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vip_capture_run_mode(int mode) +#else +int +gfx_set_vip_capture_run_mode(int mode) +#endif +{ + unsigned long value; + + value = READ_VIP32(SC1200_VIP_CONTROL); + value &= ~SC1200_CAPTURE_RUN_MODE_MASK; + switch (mode) { + case VIP_CAPTURE_STOP_LINE: + value |= SC1200_CAPTURE_RUN_MODE_STOP_LINE; + break; + case VIP_CAPTURE_STOP_FIELD: + value |= SC1200_CAPTURE_RUN_MODE_STOP_FIELD; + break; + case VIP_CAPTURE_START_FIELD: + value |= SC1200_CAPTURE_RUN_MODE_START; + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + WRITE_VIP32(SC1200_VIP_CONTROL, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_base + * + * This routine sets the odd and even base address values for the VIP memory + * buffer. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vip_base(unsigned long even, unsigned long odd) +#else +int +gfx_set_vip_base(unsigned long even, unsigned long odd) +#endif +{ + /* TRUE OFFSET IS SPECIFIED, NEED TO SET BIT 23 FOR HARDWARE */ + + if (even) + WRITE_VIP32(SC1200_VIP_EVEN_BASE, even + (unsigned long)gfx_phys_fbptr); + if (odd) + WRITE_VIP32(SC1200_VIP_ODD_BASE, odd + (unsigned long)gfx_phys_fbptr); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_pitch + * + * This routine sets the number of bytes between scanlines for the VIP data. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vip_pitch(unsigned long pitch) +#else +int +gfx_set_vip_pitch(unsigned long pitch) +#endif +{ + WRITE_VIP32(SC1200_VIP_PITCH, pitch & SC1200_VIP_PITCH_MASK); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_mode + * + * This routine sets the VIP operating mode. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vip_mode(int mode) +#else +int +gfx_set_vip_mode(int mode) +#endif +{ + unsigned long config; + + config = READ_VIP32(SC1200_VIP_CONFIG); + config &= ~SC1200_VIP_MODE_MASK; + switch (mode) { + case VIP_MODE_C: + WRITE_VIP32(SC1200_VIP_CONFIG, config | SC1200_VIP_MODE_C); + break; + default: + return GFX_STATUS_BAD_PARAMETER; + } + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_enable + * + * This routine enables or disables the VBI data capture. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vbi_enable(int enable) +#else +int +gfx_set_vbi_enable(int enable) +#endif +{ + unsigned long value; + + value = READ_VIP32(SC1200_VIP_CONTROL); + if (enable) + value |= SC1200_VIP_VBI_CAPTURE_EN; + else + value &= ~SC1200_VIP_VBI_CAPTURE_EN; + WRITE_VIP32(SC1200_VIP_CONTROL, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_mode + * + * This routine sets the VBI data types captured to memory. + * It receives a mask of all enabled types. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vbi_mode(int mode) +#else +int +gfx_set_vbi_mode(int mode) +#endif +{ + unsigned long config; + + config = READ_VIP32(SC1200_VIP_CONFIG); + config &= + ~(SC1200_VBI_ANCILLARY_TO_MEMORY | SC1200_VBI_TASK_A_TO_MEMORY | + SC1200_VBI_TASK_B_TO_MEMORY); + + if (mode & VBI_ANCILLARY) + config |= SC1200_VBI_ANCILLARY_TO_MEMORY; + if (mode & VBI_TASK_A) + config |= SC1200_VBI_TASK_A_TO_MEMORY; + if (mode & VBI_TASK_B) + config |= SC1200_VBI_TASK_B_TO_MEMORY; + WRITE_VIP32(SC1200_VIP_CONFIG, config); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_base + * + * This routine sets the odd and even base address values for VBI capture. + * + * "even" and "odd" should contain 16-byte aligned physical addresses. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vbi_base(unsigned long even, unsigned long odd) +#else +int +gfx_set_vbi_base(unsigned long even, unsigned long odd) +#endif +{ + /* VIP HW REQUIRES THAT BASE ADDRESSES BE 16-BYTE ALIGNED */ + + if (even) + WRITE_VIP32(SC1200_VBI_EVEN_BASE, even & ~0xf); + if (odd) + WRITE_VIP32(SC1200_VBI_ODD_BASE, odd & ~0xf); + + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_pitch + * + * This routine sets the number of bytes between scanlines for VBI capture. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vbi_pitch(unsigned long pitch) +#else +int +gfx_set_vbi_pitch(unsigned long pitch) +#endif +{ + WRITE_VIP32(SC1200_VBI_PITCH, pitch & SC1200_VBI_PITCH_MASK); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_direct + * + * This routine sets the VBI lines to be passed to the Direct VIP. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines) +#else +int +gfx_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines) +#endif +{ + WRITE_VIP32(SC1200_EVEN_DIRECT_VBI_LINE_ENABLE, + even_lines & SC1200_DIRECT_VBI_LINE_ENABLE_MASK); + WRITE_VIP32(SC1200_ODD_DIRECT_VBI_LINE_ENABLE, + odd_lines & SC1200_DIRECT_VBI_LINE_ENABLE_MASK); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_interrupt + * + * This routine enables or disables the VBI field interrupt. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vbi_interrupt(int enable) +#else +int +gfx_set_vbi_interrupt(int enable) +#endif +{ + unsigned long value; + + value = READ_VIP32(SC1200_VIP_CONTROL); + if (enable) + value |= SC1200_VIP_VBI_FIELD_INTERRUPT_EN; + else + value &= ~SC1200_VIP_VBI_FIELD_INTERRUPT_EN; + WRITE_VIP32(SC1200_VIP_CONTROL, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_bus_request_threshold_high + * + * This routine sets the VIP FIFO bus request threshold. + * If enable is TRUE, VIP FIFO will be set to issue a bus request when it filled with 64 bytes. + * If enable is FALSE, VIP FIFO will be set to issue a bus request when it filled with 32 bytes. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vip_bus_request_threshold_high(int enable) +#else +int +gfx_set_vip_bus_request_threshold_high(int enable) +#endif +{ + unsigned long value; + + value = READ_VIP32(SC1200_VIP_CONFIG); + if (enable) + value &= ~SC1200_VIP_BUS_REQUEST_THRESHOLD; + else + value |= SC1200_VIP_BUS_REQUEST_THRESHOLD; + WRITE_VIP32(SC1200_VIP_CONFIG, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_last_line + * + * This routine sets the maximum number of lines captured in each field. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_set_vip_last_line(int last_line) +#else +int +gfx_set_vip_last_line(int last_line) +#endif +{ + unsigned long value; + + /* This feature is implemented in Rev C1 */ + if (gfx_chip_revision < SC1200_REV_C1) + return (GFX_STATUS_OK); + + value = READ_VIP32(SC1200_VIP_LINE_TARGET); + value &= ~SC1200_VIP_LAST_LINE_MASK; + value |= ((last_line & 0x3FF) << 16); + WRITE_VIP32(SC1200_VIP_LINE_TARGET, value); + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_test_vip_odd_field + * + * This routine returns 1 if the current VIP field is odd. Otherwise returns 0. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_test_vip_odd_field(void) +#else +int +gfx_test_vip_odd_field(void) +#endif +{ + if (READ_VIP32(SC1200_VIP_STATUS) & SC1200_VIP_CURRENT_FIELD_ODD) + return (1); + else + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_test_vip_bases_updated + * + * This routine returns 1 if all of the VIP base registers have been updated, + * i.e. there is no base register which has been written with a new address, + * that VIP has not already captured or started capturing into the new address. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_test_vip_bases_updated(void) +#else +int +gfx_test_vip_bases_updated(void) +#endif +{ + if (READ_VIP32(SC1200_VIP_STATUS) & SC1200_VIP_BASE_NOT_UPDATED) + return (0); + else + return (1); +} + +/*----------------------------------------------------------------------------- + * gfx_test_vip_fifo_overflow + * + * This routine returns 1 if an overflow occurred on the FIFO between the VIP + * and the fast X-bus, 0 otherwise. + * If an overflow occurred, the overflow status indication is reset. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_test_vip_fifo_overflow(void) +#else +int +gfx_test_vip_fifo_overflow(void) +#endif +{ + if (READ_VIP32(SC1200_VIP_STATUS) & SC1200_VIP_FIFO_OVERFLOW) { + /* Bits in vip status register are either read only or reset by writing 1 */ + WRITE_VIP32(SC1200_VIP_STATUS, SC1200_VIP_FIFO_OVERFLOW); + return (1); + } else { + return (0); + } +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_line + * + * This routine returns the number of the current video line being + * received by the VIP interface. + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_get_vip_line(void) +#else +int +gfx_get_vip_line(void) +#endif +{ + return (int)(READ_VIP32(SC1200_VIP_CURRENT_LINE) & + SC1200_VIP_CURRENT_LINE_MASK); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_base + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +unsigned long +sc1200_get_vip_base(int odd) +#else +unsigned long +gfx_get_vip_base(int odd) +#endif +{ + /* MASK BIT 23 AND ABOVE TO MAKE IT A TRUE OFFSET */ + + if (odd) + return (READ_VIP32(SC1200_VIP_ODD_BASE)); + return (READ_VIP32(SC1200_VIP_EVEN_BASE)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_pitch + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +unsigned long +sc1200_get_vbi_pitch(void) +#else +unsigned long +gfx_get_vbi_pitch(void) +#endif +{ + return (READ_VIP32(SC1200_VBI_PITCH) & SC1200_VBI_PITCH_MASK); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*----------------------------------------------------------------------------- + * gfx_get_vip_enable + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_get_vip_enable(void) +#else +int +gfx_get_vip_enable(void) +#endif +{ + if (READ_VIP32(SC1200_VIP_CONTROL) & SC1200_VIP_DATA_CAPTURE_EN) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_pitch + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +unsigned long +sc1200_get_vip_pitch(void) +#else +unsigned long +gfx_get_vip_pitch(void) +#endif +{ + return (READ_VIP32(SC1200_VIP_PITCH) & SC1200_VIP_PITCH_MASK); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_mode + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_get_vip_mode(void) +#else +int +gfx_get_vip_mode(void) +#endif +{ + switch (READ_VIP32(SC1200_VIP_CONFIG) & SC1200_VIP_MODE_MASK) { + case SC1200_VIP_MODE_C: + return VIP_MODE_C; + default: + return (0); + } +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_enable + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_get_vbi_enable(void) +#else +int +gfx_get_vbi_enable(void) +#endif +{ + if (READ_VIP32(SC1200_VIP_CONTROL) & SC1200_VIP_VBI_CAPTURE_EN) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_mode + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_get_vbi_mode(void) +#else +int +gfx_get_vbi_mode(void) +#endif +{ + int config; + int mode = 0; + + config = + (int)(READ_VIP32(SC1200_VIP_CONFIG) & + (SC1200_VBI_ANCILLARY_TO_MEMORY | SC1200_VBI_TASK_A_TO_MEMORY | + SC1200_VBI_TASK_B_TO_MEMORY)); + if (config & SC1200_VBI_ANCILLARY_TO_MEMORY) + mode |= VBI_ANCILLARY; + if (config & SC1200_VBI_TASK_A_TO_MEMORY) + mode |= VBI_TASK_A; + if (config & SC1200_VBI_TASK_B_TO_MEMORY) + mode |= VBI_TASK_B; + return mode; +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_base + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +unsigned long +sc1200_get_vbi_base(int odd) +#else +unsigned long +gfx_get_vbi_base(int odd) +#endif +{ + /* MASK BIT 23 AND ABOVE TO MAKE IT A TRUE OFFSET */ + + if (odd) + return (READ_VIP32(SC1200_VBI_ODD_BASE)); + return (READ_VIP32(SC1200_VBI_EVEN_BASE)); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_direct + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +unsigned long +sc1200_get_vbi_direct(int odd) +#else +unsigned long +gfx_get_vbi_direct(int odd) +#endif +{ + /* MASK BIT 23 AND ABOVE TO MAKE IT A TRUE OFFSET */ + + if (odd) + return (READ_VIP32(SC1200_ODD_DIRECT_VBI_LINE_ENABLE) & + SC1200_DIRECT_VBI_LINE_ENABLE_MASK); + return (READ_VIP32(SC1200_EVEN_DIRECT_VBI_LINE_ENABLE) & + SC1200_DIRECT_VBI_LINE_ENABLE_MASK); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_interrupt + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_get_vbi_interrupt(void) +#else +int +gfx_get_vbi_interrupt(void) +#endif +{ + if (READ_VIP32(SC1200_VIP_CONTROL) & SC1200_VIP_VBI_FIELD_INTERRUPT_EN) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_bus_request_threshold_high + *----------------------------------------------------------------------------- + */ +#if GFX_VIP_DYNAMIC +int +sc1200_get_vip_bus_request_threshold_high(void) +#else +int +gfx_get_vip_bus_request_threshold_high(void) +#endif +{ + if (READ_VIP32(SC1200_VIP_CONFIG) & SC1200_VIP_BUS_REQUEST_THRESHOLD) + return (1); + return (0); +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vip_1400.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vip_1400.c new file mode 100644 index 000000000..789628885 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vip_1400.c @@ -0,0 +1,271 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vip_1400.c,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/*----------------------------------------------------------------------------- + * VIP_1400.C + * + * Version 2.0 - February 21, 2000. + * + * This file routines to control the SC1400 video input port (VIP) hardware. + * + * History: + * Versions 0.1 through 2.0 by Brian Falardeau. + * + * Copyright (c) 1999-2000 National Semiconductor. + *----------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------- + * gfx_set_vip_enable + * + * This routine enables or disables the writes to memory from the video port. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_vip_enable(int enable) +#else +int +gfx_set_vip_enable(int enable) +#endif +{ + unsigned long mcr, value; + + value = READ_VIP32(SC1400_VIP_CONTROL); + + if (enable) { + /* CONFIGURE MCR FOR VIDEO INPUT MODE */ + + mcr = IND(SC1400_CB_BASE_ADDR + SC1400_CB_MISC_CONFIG); + mcr |= (SC1400_MCR_VPOUT_CK_SELECT | SC1400_MCR_VPOUT_CK_SOURCE); + mcr &= ~SC1400_MCR_VPOUT_MODE; + mcr |= SC1400_MCR_VPIN_CCIR656; + mcr &= ~SC1400_MCR_GENLOCK_CONTINUE; + OUTD(SC1400_CB_BASE_ADDR + SC1400_CB_MISC_CONFIG, mcr); + + /* ENABLE CAPTURE */ + /* Hardcode config values for now. */ + + WRITE_VIP32(SC1400_VIP_CONFIG, 0x30012); + value |= 0x103; + } else { + value &= ~(0x102); + } + + WRITE_VIP32(SC1400_VIP_CONTROL, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_base + * + * This routine sets the odd and even base address values for the VIP memory + * buffer. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_vip_base(unsigned long even, unsigned long odd) +#else +int +gfx_set_vip_base(unsigned long even, unsigned long odd) +#endif +{ + // TRUE OFFSET IS SPECIFIED, NEED TO SET BIT 23 FOR HARDWARE + + WRITE_VIP32(SC1400_VIP_EVEN_BASE, even | 0x00800000); + WRITE_VIP32(SC1400_VIP_ODD_BASE, odd | 0x00800000); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vip_pitch + * + * This routine sets the number of bytes between scanlines for the VIP data. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_vip_pitch(unsigned long pitch) +#else +int +gfx_set_vip_pitch(unsigned long pitch) +#endif +{ + WRITE_VIP32(SC1400_VIP_PITCH, pitch & 0x0000FFFC); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_enable + * + * This routine enables or disables the VBI data capture. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_vbi_enable(int enable) +#else +int +gfx_set_vbi_enable(int enable) +#endif +{ + unsigned long value; + + value = READ_VIP32(SC1400_VIP_CONTROL); + if (enable) + value |= SC1400_VIP_VBI_CAPTURE_EN; + else + value &= ~SC1400_VIP_VBI_CAPTURE_EN; + WRITE_VIP32(SC1400_VIP_CONTROL, value); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_base + * + * This routine sets the odd and even base address values for VBI capture. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_vbi_base(unsigned long even, unsigned long odd) +#else +int +gfx_set_vbi_base(unsigned long even, unsigned long odd) +#endif +{ + // TRUE OFFSET IS SPECIFIED, NEED TO SET BIT 23 FOR HARDWARE + + WRITE_VIP32(SC1400_VBI_EVEN_BASE, even | 0x00800000); + WRITE_VIP32(SC1400_VBI_ODD_BASE, odd | 0x00800000); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_set_vbi_pitch + * + * This routine sets the number of bytes between scanlines for VBI capture. + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_set_vbi_pitch(unsigned long pitch) +#else +int +gfx_set_vbi_pitch(unsigned long pitch) +#endif +{ + WRITE_VIP32(SC1400_VBI_PITCH, pitch & 0x0000FFFC); + return (0); +} + +/*************************************************************/ +/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ +/*************************************************************/ + +#if GFX_READ_ROUTINES + +/*----------------------------------------------------------------------------- + * gfx_get_vip_enable + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_get_vip_enable(void) +#else +int +gfx_get_vip_enable(void) +#endif +{ + if (READ_VIP32(SC1400_VIP_CONTROL) & 0x00000100) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_base + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_vip_base(int odd) +#else +unsigned long +gfx_get_vip_base(int odd) +#endif +{ + // MASK BIT 23 AND ABOVE TO MAKE IT A TRUE OFFSET + + if (odd) + return (READ_VIP32(SC1400_VIP_ODD_BASE) & 0x007FFFFF); + return (READ_VIP32(SC1400_VIP_EVEN_BASE) & 0x007FFFFF); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vip_pitch + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_vip_pitch(void) +#else +unsigned long +gfx_get_vip_pitch(void) +#endif +{ + return (READ_VIP32(SC1400_VIP_PITCH) & 0x0000FFFF); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_enable + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +int +sc1400_get_vbi_enable(void) +#else +int +gfx_get_vbi_enable(void) +#endif +{ + if (READ_VIP32(SC1400_VIP_CONTROL) & 0x00000200) + return (1); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_base + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_vbi_base(int odd) +#else +unsigned long +gfx_get_vbi_base(int odd) +#endif +{ + // MASK BIT 23 AND ABOVE TO MAKE IT A TRUE OFFSET + + if (odd) + return (READ_VIP32(SC1400_VBI_ODD_BASE) & 0x007FFFFF); + return (READ_VIP32(SC1400_VBI_EVEN_BASE) & 0x007FFFFF); +} + +/*----------------------------------------------------------------------------- + * gfx_get_vbi_pitch + *----------------------------------------------------------------------------- + */ +#if GFX_VIDEO_DYNAMIC +unsigned long +sc1400_get_vbi_pitch(void) +#else +unsigned long +gfx_get_vbi_pitch(void) +#endif +{ + return (READ_VIP32(SC1400_VBI_PITCH) & 0x0000FFFF); +} + +#endif /* GFX_READ_ROUTINES */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc.h new file mode 100644 index 000000000..32b769e8b --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc.h @@ -0,0 +1,433 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc.h,v 1.5 2003/02/21 16:51:09 alanh Exp $ */ +/* + * $Workfile: nsc.h $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file contains the data structures Geode driver. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Geode Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef _NSC_GEODE_H_ +#define _NSC_GEODE_H_ + +#include "xaa.h" +#include "xf86Cursor.h" +#if !defined(STB_X) +#include "vgaHW.h" +#endif +#include "xf86int10.h" +#include "xf86xv.h" + +#if defined(STB_X) +#define GFX(func) Gal_##func +#define GFX2(func) Gal2_##func +#define OPTACCEL(func) func +#else /* STB_X */ +#define GFX(func) gfx_##func +#define GFX2(func) gfx2_##func + +#if defined(OPT_ACCEL) +#define OPTACCEL(func) OPT##func +#else /* OPT_ACCEL */ +#define OPTACCEL(func) func +#endif /* OPT_ACCEL */ + +#endif /* STB_X */ + +#define GEODEPTR(p) ((GeodePtr)((p)->driverPrivate)) + +#define DebugPort(_Val) gfx_outb(0x84, (_Val)); + +#define DEFAULT_NUM_OF_BUF 20 /* default # of buffers */ + +#if defined(MYDBG) +#define DEBUGMSG(cond, drv_msg) if((cond)) xf86DrvMsg drv_msg +#else +#define DEBUGMSG(cond, drv_msg) +#endif + +/* Overlay Transparency Key */ +#define TRANSPARENCY_KEY 255 + +#if defined(EXTERN) +unsigned char DCount = 0; + +#if defined(STB_X) +void +gfx_outb(unsigned short port, unsigned char data) +{ + __asm__ volatile ("outb %0,%1"::"a" (data), "d"(port)); +} +#endif +#else +extern unsigned char DCount; + +#if defined(STB_X) +extern void gfx_outb(unsigned short port, unsigned char data); +extern unsigned char gfx_inb(unsigned short port); +#endif +#endif + +#if defined(STB_X) +#include "nsc_galproto.h" +#else +extern void gfx_write_reg32(int offset, int data); +extern void gfx_write_reg16(int offset, short data); +extern void gfx_write_reg8(int offset, char data); +extern int gfx_read_reg32(int offset); +extern short gfx_read_reg16(int offset); +extern void gfx_write_vid32(int offset, int data); +extern int gfx_read_vid32(int offset); +extern unsigned char gfx_inb(unsigned short port); +extern void gfx_outb(unsigned short port, unsigned char data); +extern unsigned short gfx_inw(unsigned short port); +extern void gfx_outw(unsigned short port, unsigned short data); +extern unsigned long gfx_ind(unsigned short port); +extern void gfx_outd(unsigned short port, unsigned long data); + +#include "gfx_rtns.h" +#include "gfx_defs.h" +#include "gfx_regs.h" +#include "panel.h" + +typedef struct __TVPARAMS +{ + unsigned int dwFlags; + unsigned short wWidth; + unsigned short wHeight; + unsigned short wStandard; + unsigned short wType; + unsigned short wOutput; + unsigned short wResolution; + Bool bState; +} +TVPARAMS, *PTVPARAMS; + +typedef struct __DISPLAYTIMING +{ + unsigned int dwDotClock; + unsigned short wPitch; + unsigned short wBpp; + unsigned short wHTotal; + unsigned short wHActive; + unsigned short wHSyncStart; + unsigned short wHSyncEnd; + unsigned short wHBlankStart; + unsigned short wHBlankEnd; + unsigned short wVTotal; + unsigned short wVActive; + unsigned short wVSyncStart; + unsigned short wVSyncEnd; + unsigned short wVBlankStart; + unsigned short wVBlankEnd; + unsigned short wPolarity; +} +DISPLAYTIMING, *PDISPLAYTIMING; + +/* TV Timings */ +typedef struct __TVTIMING +{ + unsigned long HorzTim; + unsigned long HorzSync; + unsigned long VertSync; + unsigned long LineEnd; + unsigned long VertDownscale; + unsigned long HorzScaling; + unsigned long TimCtrl1; + unsigned long TimCtrl2; + unsigned long Subfreq; + unsigned long DispPos; + unsigned long DispSize; + unsigned long Debug; + unsigned long DacCtrl; + unsigned int DotClock; +} +TVTIMING, *PTVTIMING; + +#endif /* STB_X */ + +typedef struct _VESARec +{ + xf86Int10InfoPtr pInt; +} +VESARec, *VESAPtr; + +typedef struct +{ + /* Private struct for the server */ + unsigned long cpu_version; /* [7:0] Type:1=GXLV,2=SC1400 */ + /* [15:8] Major version */ + /* [23:16] Minor version */ + unsigned long vid_version; /* [7:0] Type:1=CS5530,2=SC1400 */ + + EntityInfoPtr pEnt; + ScreenBlockHandlerProcPtr BlockHandler; /* needed for video */ + int DetectedChipSet; + int Chipset; + unsigned long FBLinearAddr; + unsigned char *FBBase; + unsigned long FBSize; + unsigned int cpu_reg_size; + unsigned int gp_reg_size; + unsigned int vid_reg_size; + int Pitch; + Bool HWCursor; + Bool NoAccel; + unsigned long VideoKey; + + Bool TVSupport; +#if defined(STB_X) + GAL_TVPARAMS TvParam; +#else + TVPARAMS TvParam; +#endif /* STB_X */ + + int TVOx, TVOy, TVOw, TVOh; + Bool TV_Overscan_On; + + Bool Panel; + + /* Flatpanel support from Bios */ + int FPBX; /* xres */ + int FPBY; /* yres */ + int FPBB; /* bpp */ + int FPBF; /* freq */ + + int Rotate; + Bool ShadowFB; + unsigned char *ShadowPtr; + int ShadowPitch; + void (*PointerMoved) (int index, int x, int y); + /* CloseScreen function. */ + CloseScreenProcPtr CloseScreen; + + Bool Compression; + unsigned int CBOffset; + unsigned int CBPitch; + unsigned int CBSize; + unsigned long CursorStartOffset; + unsigned int CursorSize; + xf86CursorInfoPtr CursorInfo; + int CursorXHot; + int CursorYHot; + unsigned long OffscreenStartOffset; + unsigned int OffscreenSize; + + /***Image Write structures ***/ + + /* offset in video memory for ImageWrite Buffers */ + unsigned char **AccelImageWriteBufferOffsets; + int NoOfImgBuffers; + FBAreaPtr CompressionArea; + FBAreaPtr AccelImgArea; +/*****************************************/ +/* Saved Console State */ +#if defined(STB_X) + GAL_VGAMODEDATA FBgfxVgaRegs; + GAL_DISPLAYTIMING FBgfxdisplaytiming; + GAL_TVTIMING FBgfxtvtiming; +#else + gfx_vga_struct FBgfxVgaRegs; + DISPLAYTIMING FBgfxdisplaytiming; + TVTIMING FBtvtiming; +#endif /* STB_X */ + int FBVGAActive; + unsigned int FBTVActive; + unsigned int FBTVEnabled; + unsigned long FBDisplayOffset; + + VESAPtr vesa; + + /* compression */ + int FBCompressionEnable; + unsigned long FBCompressionOffset; + unsigned short FBCompressionPitch; + unsigned short FBCompressionSize; + + /* Save the Cursor offset of the FB */ + unsigned long FBCursorOffset; +/*****************************************/ + + XAAInfoRecPtr AccelInfoRec; + + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; +/*****************************************/ + int video_x; + int video_y; + short video_w; + short video_h; + short video_srcw; + short video_srch; + short video_dstw; + short video_dsth; + int video_id; + int video_offset; + ScrnInfoPtr video_scrnptr; + BOOL OverlayON; + + int videoKey; + XF86VideoAdaptorPtr adaptor; + int OverlaySkewX; + int OverlaySkewY; + int VideoZoomMax; +} +GeodeRec, *GeodePtr; + +/* option flags are self-explanatory */ +enum +{ + OPTION_SW_CURSOR, + OPTION_HW_CURSOR, + OPTION_NOCOMPRESSION, + OPTION_NOACCEL, + OPTION_TV_SUPPORT, + OPTION_TV_OUTPUT, + OPTION_TV_OVERSCAN, + OPTION_SHADOW_FB, + OPTION_ROTATE, + OPTION_FLATPANEL, + OPTION_FLATPANEL_INFO, + OPTION_FLATPANEL_IN_BIOS, + OPTION_COLOR_KEY, + OPTION_OSM, + OPTION_OSM_IMG_BUFS, + OPTION_DONT_PROGRAM +} +GeodeOpts; + +#endif /* _NSC_GEODE_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc.man b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc.man new file mode 100644 index 000000000..c9df3c0c5 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc.man @@ -0,0 +1,134 @@ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc.man,v 1.1 2002/12/10 15:12:23 alanh Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH NSC __drivermansuffix__ __vendorversion__ +.SH NAME +nsc \- Nsc video driver +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qnsc\*q" +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B nsc +is an XFree86 driver for National Semiconductors GEODE processor family. +It uses the DURANGO kit provided by National Semiconductor. +The driver is accelerated, and provides support for the following +framebuffer depths: 8, 16 and 24. +.SH SUPPORTED HARDWARE +The +.B nsc +driver supports GXLV (5530 companion chip), SC1200, SC1400 and +GX2 (5535 companion chip). +.SH CONFIGURATION DETAILS +Please refer to XF86Config(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.PP +The driver will auto-detect the amount of video memory present for all +chips. If the amount of memory is detected incorrectly, the actual amount +of video memory should be specified with a +.B VideoRam +entry in the config file +.B \*qDevice\*q +section. +.PP +The following driver +.B Options +are supported: +.TP +.BI "Option \*qSWCursor\*q \*q" boolean \*q +Enable or disable the SW cursor. +Default: off. +.TP +.BI "Option \*qHWCursor\*q \*q" boolean \*q +Enable or disable the HW cursor. +Default: on. +.TP +.BI "Option \*qNoAccel\*q \*q" boolean \*q +Disable or enable acceleration. +Default: acceleration is enabled. +.TP +.BI "Option \*qNoCompression\*q \*q" boolean \*q +Disable or enable compression. +Default: compression is enabled. +.TP +.BI "Option \*qShadowFB\*q \*q" boolean \*q +Enable or disable use of the shadow framebuffer layer. +Default: off. +.TP +.BI "Option \*qRotate\*q \*qCW\*q" +Rotate the display clockwise. This mode is unaccelerated, and uses +the Shadow Frame Buffer layer. +Default: no rotation. +.TP +.BI "Option \*qRotate\*q \*qCCW\*q" +Rotate the display counterclockwise. This mode is unaccelerated, and +uses the Shadow Frame Buffer layer. +Default: no rotation. +.TP +.BI "Option \*qFlatPanel\*q \*q" boolean \*q +This enables the FlatPanel display unit. The FlatPanel depends on the +BIOS to do the Pnale h/w initialization. +In GX2 based platforms with TFT part Flatpanel is enabled, and on CRT +part is disabled. +Default: off. +.TP +.BI "Option \*qOSMImageBuffers\*q \*q" integer \*q +This sets the number of scanline buffers to be allocated in offscreen +memory for acceleration. This can take any value 0 will disable the +allocation. Disabled if cannot alocate requested scanline memory. +Default: 20. +.TP +.BI "Option \*qColorKey\*q \*q" integer \*q +This sets the default pixel value for the YUV video overlay key. +Default: 0. +.PP +The following +.B Options +are supported only on SC1200 based platforms: +.TP +.BI "Option \*qTV\*q \*qPAL-768x576\*q" +Selects the PAL TV display mode 768x576 and the depth is forced to 16 bpp. +Default: no TV. +.TP +.BI "Option \*qTV\*q \*qPAL-720x576\*q" +Selects the PAL TV display mode 720x576 and the depth is forced to 16 bpp. +Default: no TV. +.TP +.BI "Option \*qTV\*q \*qNTSC-720x480\*q" +Selects the NTSC TV display mode 720x480 and the depth is forced to 16 bpp. +Default: no TV. +.TP +.BI "Option \*qTV\*q \*qNTSC-640x480\*q" +Selects the NTSC TV display mode 640x480 and the depth is forced to 16 bpp. +Default: no TV. +.TP +.BI "Option \*qTV_Output\*q \*qCOMPOSITE\*q" +The selected TV mode output is coded for Composite signal. +Default: no TV. +.TP +.BI "Option \*qTV_Output\*q \*qSVIDEO\*q" +The selected TV mode output is coded for SVIDEO signal. +Default: no TV. +.TP +.BI "Option \*qTV_Output\*q \*qYUV\*q" +The selected TV mode output is coded for YUV signal. +Default: no TV. +.TP +.BI "Option \*qTV_Output\*q \*qSCART\*q" +The selected TV mode output is coded for SCART signal. +Default: no TV. +.TP +.BI "Option \*qTVOverscan\*q \*xx:yy:ww:hh\*q" +This option will let only the viewable display area smaller to be able to +view on TV. The parameters xx: X-offset, yy: Y-offset, ww: Viewable width, +hh: Viewable height. +Default: no TV. +.SH "SEE ALSO" +XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) +.SH AUTHOR +Author: Sarma V. Kolluru diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_driver.c new file mode 100644 index 000000000..39b0a4ff2 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_driver.c @@ -0,0 +1,614 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_driver.c,v 1.4 2003/02/12 13:08:54 alanh Exp $ */ +/* + * $Workfile: nsc_driver.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This is the main module configures the interfacing + * with the X server. The individual modules will be + * loaded based upon the options selected from the + * XF86Config. This file also has modules for finding + * supported modes, turning on the modes based on options. + * + * Project: Nsc Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#define DEBUG(x) +#define NSC_TRACE 0 +#define CFB 0 +#define HWVGA 1 + +/* Includes that are used by all drivers */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Resources.h" + +/* We may want inb() and outb() */ +#include "compiler.h" + +/* We may want to access the PCI config space */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +/* Colormap handling stuff */ +#include "xf86cmap.h" + +#define RC_MAX_DEPTH 24 + +/* Frame buffer stuff */ +#if CFB +/* + * If using cfb, cfb.h is required. Select the others for the bpp values + * the driver supports. + */ +#define PSZ 8 /* needed for cfb.h */ +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#else +#include "fb.h" +#endif + +#include "shadowfb.h" + +/* Machine independent stuff */ +#include "mipointer.h" +#include "mibank.h" +#include "micmap.h" +/* All drivers implementing backing store need this */ +#include "mibstore.h" +#include "vgaHW.h" +#include "vbe.h" + +/* Check for some extensions */ +#ifdef XFreeXDGA +#define _XF86_DGA_SERVER_ +#include "extensions/xf86dgastr.h" +#endif /* XFreeXDGA */ + +#ifdef DPMSExtension +#include "globals.h" +#include "opaque.h" +#define DPMS_SERVER +#include "extensions/dpms.h" +#endif /* DPMSExtension */ + +#define EXTERN +/* Our private include file (this also includes the durango headers) */ +#include "nsc.h" + +#if NSC_TRACE +/* ANSI C does not allow var arg macros */ +#define GeodeDebug(args) DebugPort(DCount++);ErrorF args +#else +#define GeodeDebug(args) +#endif + +/* A few things all drivers should have */ +#define NSC_NAME "NSC" +#define NSC_DRIVER_NAME "nsc" + +/* This should match the durango code version. + * The patchlevel may be used to indicate changes in geode.c + */ +#define NSC_VERSION_NAME "2.7.6" +#define NSC_VERSION_MAJOR 2 +#define NSC_VERSION_MINOR 7 +#define NSC_PATCHLEVEL 6 + +#define NSC_VERSION_CURRENT ((NSC_VERSION_MAJOR << 24) | \ + (NSC_VERSION_MINOR << 16) | NSC_PATCHLEVEL) + +/* Forward definitions */ +static const OptionInfoRec *NscAvailableOptions(int chipid, int busid); +static void NscIdentify(int); +static Bool NscProbe(DriverPtr, int); +static int CPUDetected; + +extern void GX1SetupChipsetFPtr(ScrnInfoPtr pScrn); +extern void GX2SetupChipsetFPtr(ScrnInfoPtr pScrn); + +#if !defined(STB_X) +extern unsigned char *XpressROMPtr; +#endif /* STB_X */ + +/* driver record contains the functions needed by the server after loading + * the driver module. + */ +DriverRec NSC = { + NSC_VERSION_CURRENT, + NSC_DRIVER_NAME, + NscIdentify, + NscProbe, + NscAvailableOptions, + NULL, + 0 +}; + +/* Existing Processor Models */ +#define GX1 0x1 +#define GX2 0x2 +#define GX2_CRT 0x6 +#define GX2_TFT 0xA + +#define PCI_VENDOR_ID_CYRIX 0x1078 +#define PCI_VENDOR_ID_NS 0x100B + +#define PCI_CHIP_5530 0x0104 +#define PCI_CHIP_SC1200 0x0504 +#define PCI_CHIP_SC1400 0x0104 +#define PCI_CHIP_REDCLOUD 0x0030 + +/* National Chip Models */ +typedef struct _DEVICE_MODEL +{ + int DeviceId; + int Model; +} +DeviceModel; + +DeviceModel ChipModel[] = { + {PCI_CHIP_5530, GX1}, + {PCI_CHIP_SC1200, GX1}, + {PCI_CHIP_SC1400, GX1}, + {PCI_CHIP_REDCLOUD, GX2}, + {-1, 0} +}; + +/* Supported chipsets */ +SymTabRec GeodeChipsets[] = { + {PCI_CHIP_5530, "5530"}, + {PCI_CHIP_SC1200, "SC1200"}, + {PCI_CHIP_SC1400, "SC1400"}, + {PCI_CHIP_REDCLOUD, "REDCLOUD"}, + {-1, NULL} +}; + +PciChipsets GeodePCIchipsets[] = { + {PCI_CHIP_5530, PCI_CHIP_5530, RES_SHARED_VGA}, + {PCI_CHIP_SC1200, PCI_CHIP_SC1200, RES_SHARED_VGA}, + {PCI_CHIP_SC1400, PCI_CHIP_SC1400, RES_SHARED_VGA}, + {PCI_CHIP_REDCLOUD, PCI_CHIP_REDCLOUD, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED}, +}; + +OptionInfoRec GeodeOptions[] = { + {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_FLATPANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, + {OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + +/* List of symbols from other modules that this module references.The purpose +* is that to avoid unresolved symbol warnings +*/ +const char *nscVgahwSymbols[] = { + "vgaHWGetHWRec", + "vgaHWUnlock", + "vgaHWInit", + "vgaHWSave", + "vgaHWRestore", + "vgaHWProtect", + "vgaHWGetIOBase", + "vgaHWMapMem", + "vgaHWLock", + "vgaHWFreeHWRec", + "vgaHWSaveScreen", + NULL +}; + +const char *nscVbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + "vbeFree", + NULL +}; + +const char *nscInt10Symbols[] = { + "xf86ExecX86int10", + "xf86InitInt10", + "xf86Int10AllocPages", + "xf86Int10Addr", + NULL +}; + +#if CFB +const char *nscCfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + NULL +}; +#else +const char *nscFbSymbols[] = { + "fbScreenInit", + "fbPictureInit", + NULL +}; +#endif + +const char *nscXaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAScreenIndex", + NULL +}; + +const char *nscRamdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +const char *nscShadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +#ifdef XFree86LOADER + +/* Module loader interface */ + +static MODULESETUPPROTO(NscSetup); + +static XF86ModuleVersionInfo NscVersionRec = { + "nsc", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + NSC_VERSION_MAJOR, NSC_VERSION_MINOR, NSC_PATCHLEVEL, + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +/* + * This data is accessed by the loader. The name must be the module name + * followed by "ModuleInit". + */ +XF86ModuleData nscModuleData = { &NscVersionRec, NscSetup, NULL }; + +/*------------------------------------------------------------------------- + * NscSetup. + * + * Description :This function sets up the driver in X list and load the + * module symbols through xf86loader routines.. + * + * Parameters. + * Module :Pointer to the geode module + * options :Driver module options. + * ErrorMajor:Major no + * ErrorMinor:Minor no. + * + * Returns :NULL on success + * + * Comments :Module setup is done by this function + * + *------------------------------------------------------------------------- +*/ +static pointer +NscSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) +{ + static Bool Initialised = FALSE; + + if (!Initialised) { + Initialised = TRUE; + xf86AddDriver(&NSC, Module, 0); + /* Tell the loader about symbols from other modules that this + * module might refer to. + */ + LoaderRefSymLists(nscVgahwSymbols, nscVbeSymbols, +#if CFB + nscCfbSymbols, +#else + nscFbSymbols, +#endif + nscXaaSymbols, + nscInt10Symbols, nscRamdacSymbols, nscShadowSymbols, + NULL); + return (pointer) TRUE; + } + /*The return value must be non-NULL on success */ + if (ErrorMajor) + *ErrorMajor = LDR_ONCEONLY; + return NULL; +} +#endif /*End of XFree86Loader */ + +/*------------------------------------------------------------------------- + * NscIdentify. + * + * Description : This function identify an Nscfamily version. + * + * + * Parameters. + * flags : flags may be used in PreInit* + * + * Returns : none + * + * Comments : none + * +*------------------------------------------------------------------------ +*/ +static void +NscIdentify(int flags) +{ + xf86PrintChipsets(NSC_NAME, + "Nsc family driver (version " NSC_VERSION_NAME ") " + "for chipsets", GeodeChipsets); +} + +/*---------------------------------------------------------------------------- + * NscAvailableOptions. + * + * Description :This function returns the geodeoptions set geodeoption + * + * Parameters. + * chipid :This will identify the chipset. + * busid :This will identify the PCI busid + * + * Returns :ptr to GeodeOptions. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static const OptionInfoRec * +NscAvailableOptions(int chipid, int busid) +{ + return GeodeOptions; +} + +/*---------------------------------------------------------------------------- + * NscProbe. + * + * Description :This is to find that hardware is claimed by another + * driver if not claim the slot & allocate ScreenInfoRec. + * + * Parameters. + * drv :a pointer to the geode driver + * flags :flags may passed to check the config and probe detect + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :This should ne minimal probe and it should under no + * circumstances change the state of the hardware.Don't do + * any intiallizations other than the required + * ScreenInforec. +*---------------------------------------------------------------------------- +*/ + +static Bool +NscProbe(DriverPtr drv, int flags) +{ + Bool foundScreen = FALSE; + int numDevSections, numUsed; + GDevPtr *devSections = NULL; + int *usedChips = NULL; + int i; + + GeodeDebug(("NscProbe: Probing for supported devices!\n")); + /* + * * Find the config file Device sections that match this + * * driver, and return if there are none. + */ + if ((numDevSections = xf86MatchDevice(NSC_NAME, &devSections)) <= 0) { + GeodeDebug(("NscProbe: failed 1!\n")); + return FALSE; + } + GeodeDebug(("NscProbe: Before MatchPciInstances!\n")); + /* PCI BUS */ + if (xf86GetPciVideoInfo()) { + numUsed = xf86MatchPciInstances(NSC_NAME, PCI_VENDOR_ID_NS, + GeodeChipsets, GeodePCIchipsets, + devSections, numDevSections, + drv, &usedChips); + if (numUsed <= 0) { + /* Check for old CYRIX vendor ID (5530) */ + numUsed = xf86MatchPciInstances(NSC_NAME, + PCI_VENDOR_ID_CYRIX, + GeodeChipsets, GeodePCIchipsets, + devSections, numDevSections, + drv, &usedChips); + } + + GeodeDebug(("NscProbe: MatchPCI (%d)!\n", numUsed)); + + if (numUsed > 0) { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else { + /* Durango only supports one instance, */ + /* so take the first one */ + for (i = 0; i < numUsed; i++) { + /* Allocate a ScrnInfoRec */ + ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); + + EntityInfoPtr pEnt = xf86GetEntityInfo(usedChips[i]); + PciChipsets *p_id; + + for (p_id = GeodePCIchipsets; p_id->numChipset != -1; p_id++) { + if (pEnt->chipset == p_id->numChipset) { + CPUDetected = GX1; + if (pEnt->chipset == PCI_CHIP_REDCLOUD) + CPUDetected = GX2; + break; + } + } + xfree(pEnt); + GeodeDebug(("NscProbe: CPUDetected %d!\n", CPUDetected)); + + pScrn->driverName = NSC_DRIVER_NAME; + pScrn->name = NSC_NAME; + pScrn->Probe = NscProbe; + + if (CPUDetected == GX1) { + GX1SetupChipsetFPtr(pScrn); + } else { /* GX2 */ + GX2SetupChipsetFPtr(pScrn); + } + + foundScreen = TRUE; + xf86ConfigActivePciEntity(pScrn, + usedChips[i], + GeodePCIchipsets, + NULL, NULL, NULL, NULL, NULL); + } + } + } + } + + if (usedChips) + xfree(usedChips); + if (devSections) + xfree(devSections); + GeodeDebug(("NscProbe: result (%d)!\n", foundScreen)); + return foundScreen; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_fourcc.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_fourcc.h new file mode 100644 index 000000000..5e5755630 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_fourcc.h @@ -0,0 +1,200 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_fourcc.h,v 1.2 2003/01/14 09:34:30 alanh Exp $ */ +/* + * $Workfile: nsc_fourcc.h $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file consists of main Xfree video macro definitions. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Geode Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Geode Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Geode Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#define FOURCC_Y2YU 0x55593259 +#define XVIMAGE_Y2YU \ + { \ + FOURCC_Y2YU, \ + XvYUV, \ + LSBFirst, \ + {'Y','2','Y','U', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 16, \ + XvPacked, \ + 1, \ + 0, 0, 0, 0, \ + 8, 8, 8, \ + 1, 2, 2, \ + 1, 1, 1, \ + {'Y','V','Y','U', \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \ + XvTopToBottom \ + } + +#define FOURCC_YVYU 0x55595659 +#define XVIMAGE_YVYU \ + { \ + FOURCC_YVYU, \ + XvYUV, \ + LSBFirst, \ + {'Y','V','Y','U', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 16, \ + XvPacked, \ + 1, \ + 0, 0, 0, 0, \ + 8, 8, 8, \ + 1, 2, 2, \ + 1, 1, 1, \ + {'Y','V','Y','U', \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \ + XvTopToBottom \ + } + +#define FOURCC_Y800 0x30303859 +#define XVIMAGE_Y800 \ + { \ + FOURCC_Y800, \ + XvYUV, \ + LSBFirst, \ + {'Y','8','0','0', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 8, \ + XvPacked, \ + 1, \ + 0, 0, 0, 0, \ + 8, 0, 0, \ + 1, 0, 0, \ + 1, 0, 0, \ + {'Y','8','0','0', \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \ + XvTopToBottom \ + } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_galfns.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_galfns.c new file mode 100644 index 000000000..baf1fc9da --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_galfns.c @@ -0,0 +1,4876 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_galfns.c,v 1.3 2003/02/05 18:38:42 alanh Exp $ */ +/* + * $Workfile: nsc_galfns.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file contains the main functions of the Geode + * frame buffer device drivers GAL function definitions. + * + * Project: Geode Frame buffer device driver + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Geode frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Geode frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Geode frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef XFree86LOADER +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> +#endif + +#include "nsc_galproto.h" + +/* + * Compile time constants + */ +#define FBDEV_NAME "/dev/nscgal" + +/* + * Cool Macros to access the structures + */ +#define INIT_GAL(x) \ + ((GAL_BASE *)(x))->dwSignature = FBGAL_SIGNATURE;\ + ((GAL_BASE *)(x))->dwSize = sizeof(x);\ + ((GAL_BASE *)(x))->dwVersion = FBGAL_VERSION; +/* + * Variables public for this file + */ +static int ifbdev_handle; + +/*------------------------------------------------------------------------ + * create_devicenode + * + * Description: This function creates nscgal device node in the device + * directory. + * parameters : none + * + * return: '0' was return on creating the galdevice node. + *----------------------------------------------------------------------*/ +int +create_devicenode() +{ + +#if 1 + FILE *pfdevices; + char line[200], devname[200]; + int majdev; + + /* remove fails if device is open */ + remove("/dev/nscgal"); + + if ((pfdevices = fopen("/proc/devices", "r"))) { + while (fgets(line, sizeof(line), pfdevices)) { + if (sscanf(line, "%d%*[ \t]%s", &majdev, devname) == 2) { + if (strstr(devname, "nscgal")) + mknod("/dev/nscgal", S_IFCHR | S_IRUSR | S_IWUSR, + makedev(majdev, 0)); + } + } + fclose(pfdevices); + } + return 1; +#endif + +} + +/*------------------------------------------------------------------------ + * Gal_initialize_interface + * + * Description: This function intializes the nscgal device . + * parameters : none + * + * return: '1' was returned on intialization of the galdevice + * otherwise '0' was returned on failure. + *----------------------------------------------------------------------*/ +BOOLEAN +Gal_initialize_interface() +{ +/* create_devicenode(); */ + + if ((ifbdev_handle = open("/dev/fb0", O_RDONLY)) == -1) +/* if ((ifbdev_handle = open("FBDEV_NAME", O_RDONLY)) == -1) */ + return 0; + return 1; +} + +/*------------------------------------------------------------------------ + * Gal_cleanup_interface + * + * Description: This function closes the nscgal device . + * parameters : none + * + * return: '1' was returned on closing the galdevice. + *----------------------------------------------------------------------*/ +BOOLEAN +Gal_cleanup_interface() +{ + if (ifbdev_handle != -1) + close(ifbdev_handle); + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_write_register + * + * Description: This function writes the data to the hardware register + * of the nscgal device . + * parameters: + * type: It specifies the hardware access type. + * offset: It specifies the offset address the register to be accessed. + * value: It specifies the data value to be written into the register. + * size: It specifies the size of the data to be written. + * + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_write_register(int type, unsigned long offset, unsigned long value, + int size) +{ + GAL_HWACCESS hwAccess; + + INIT_GAL(&hwAccess); + hwAccess.dwSubfunction = GALFN_WRITEREG; + hwAccess.dwType = type; + hwAccess.dwOffset = offset; + hwAccess.dwValue = value; + hwAccess.dwByteCount = size; + if (ioctl(ifbdev_handle, FBIOGAL_API, &hwAccess)) + return 0; + else { + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_read_register + * + * Description: This function reads the data from the hardware register + * of the nscgal device . + * parameters: + * type: It specifies the hardware access type. + * offset: It specifies the offset address of the register to be accessed. + * value: It specifies the pointer to hold the data to be read from + * the gal hardware register. + * size: It specifies the size of the data to be read + * + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_read_register(int type, unsigned long offset, unsigned long *value, + int size) +{ + GAL_HWACCESS hwAccess; + + INIT_GAL(&hwAccess); + hwAccess.dwSubfunction = GALFN_READREG; + hwAccess.dwType = type; + hwAccess.dwOffset = offset; + hwAccess.dwByteCount = size; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &hwAccess)) + return 0; + else { + *value = hwAccess.dwValue; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_get_adapter_info + * + * Description: This function gets the adapter information of the + * nscgal device . + * parameters: + *pAdapterInfo: It specifies the adapter information structure. + * + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_adapter_info(PGAL_ADAPTERINFO pAdapterInfo) +{ + INIT_GAL(pAdapterInfo); + + pAdapterInfo->dwSubfunction = GALFN_GETADAPTERINFO; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pAdapterInfo)) + return 0; + else { + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_set_softvga_state + * + * Description: This function sets the softvga state of the platform device . + * parameters: + * bEnable: It specifies the softvga state enable state. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_softvga_state(BOOLEAN bEnable) +{ + GAL_SOFTVGASTATE sSoftVgaState; + + INIT_GAL(&sSoftVgaState); + sSoftVgaState.dwSubfunction = GALFN_SETSOFTVGASTATE; + sSoftVgaState.bSoftVgaEnable = bEnable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSoftVgaState)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_get_softvga_state + * + * Description: This function gets the softvga state of the platform device . + * parameters: + * bEnable: get the softvga state. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_softvga_state(int *bState) +{ + GAL_SOFTVGASTATE sSoftVgaState; + + INIT_GAL(&sSoftVgaState); + sSoftVgaState.dwSubfunction = GALFN_GETSOFTVGASTATE; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSoftVgaState)) + return 0; + else { + *bState = sSoftVgaState.bSoftVgaEnable; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_vga_test_pci + * + * Description: This function tests the vga pci. + * parameters: + * softvga: It is pointer to the softvga state. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_test_pci(int *softvga) +{ + GAL_VGATESTPCI sVgatestpci; + + INIT_GAL(&sVgatestpci); + sVgatestpci.dwSubfunction = GALFN_GETSOFTVGASTATE; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sVgatestpci)) + return 0; + else { + *softvga = sVgatestpci.softvga; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_vga_get_pci_command + * + * Description: This function gets the vga pci command. + * parameters: + * value: It is pointer to pci command value. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_get_pci_command(unsigned char *value) +{ + GAL_VGAGETPCICOMMAND sVgagetpcicommand; + + INIT_GAL(&sVgagetpcicommand); + sVgagetpcicommand.dwSubfunction = GALFN_VGAGETPCICOMMAND; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sVgagetpcicommand)) + return 0; + else { + *value = sVgagetpcicommand.value; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_vga_seq_reset + * + * Description: This function resets the vga seq. + * parameters: + * reset: It gives the reset value. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_seq_reset(int reset) +{ + GAL_VGASEQRESET sVgaseqreset; + + INIT_GAL(&sVgaseqreset); + sVgaseqreset.dwSubfunction = GALFN_VGASEQRESET; + sVgaseqreset.reset = reset; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sVgaseqreset)) + return 0; + else { + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_vga_set_graphics_bits + * + * Description: This function resets the vga seq. + * parameters: None. + * + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_set_graphics_bits(void) +{ + GAL_VGASETGRAPHICSBITS sVgasetgraphics; + + INIT_GAL(&sVgasetgraphics); + sVgasetgraphics.dwSubfunction = GALFN_VGASETGRAPHICSBITS; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sVgasetgraphics)) + return 0; + else { + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_set_crt_enable + * + * Description: This function sets the crt state of the device . + * parameters: + * crtState: It specifies the crt state of the galdevice. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_crt_enable(int crtEnable) +{ + GAL_CRTENABLE sCrtEnable; + + INIT_GAL(&sCrtEnable); + sCrtEnable.dwSubfunction = GALFN_SETCRTENABLE; + sCrtEnable.wCrtEnable = crtEnable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCrtEnable)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_is_display_mode_supported + * + * Description: This function checks the display mode is supported or not. + * parameters: + * xres: It specifies x co-ordinate resolution. + * Yres: It specifies y co-ordinate resolution. + * bpp: It specifies the bits per pixel (8/16 bits). + * hz: It specifies the frequency of the display mode. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_is_display_mode_supported(int xres, int yres, int bpp, int hz, + int *supported) +{ + GAL_DISPLAYMODE sDisplayMode; + + *supported = 0; + INIT_GAL(&sDisplayMode); + sDisplayMode.dwSubfunction = GALFN_ISDISPLAYMODESUPPORTED; + sDisplayMode.wXres = xres; + sDisplayMode.wYres = yres; + sDisplayMode.wBpp = bpp; + sDisplayMode.wRefresh = hz; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayMode)) + return 0; + else { + *supported = sDisplayMode.dwSupported; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_set_display_mode + * + * Description: This function sets the display mode of the galdevice. + * parameters: + * xres: It specifies x co-ordinate resolution. + * Yres: It specifies y co-ordinate resolution. + * bpp: It specifies the bits per pixel (8/16 bits). + * hz: It specifies the frequency of the display mode. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_display_mode(int xres, int yres, int bpp, int hz) +{ + GAL_DISPLAYMODE sDisplayMode; + + INIT_GAL(&sDisplayMode); + sDisplayMode.dwSubfunction = GALFN_SETDISPLAYMODE; + sDisplayMode.wXres = xres; + sDisplayMode.wYres = yres; + sDisplayMode.wBpp = bpp; + sDisplayMode.wRefresh = hz; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayMode)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_get_display_mode + * + * Description: This function gets the display mode of the galdevice. + * parameters: + * xres: It specifies x co-ordinate resolution. + * Yres: It specifies y co-ordinate resolution. + * bpp: It specifies the bits per pixel (8/16 bits). + * hz: It specifies the frequency of the display mode. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_display_mode(int *xres, int *yres, int *bpp, int *hz) +{ + GAL_DISPLAYMODE sDisplayMode; + + INIT_GAL(&sDisplayMode); + sDisplayMode.dwSubfunction = GALFN_GETDISPLAYMODE; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayMode)) + return 0; + else { + *xres = sDisplayMode.wXres; + *yres = sDisplayMode.wYres; + *bpp = sDisplayMode.wBpp; + *hz = sDisplayMode.wRefresh; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_set_display_bpp + * + * Description: This function sets the number bits per pixel in the display + * mode of the galdevice. + * parameters: + * bpp: It specifies the bits per pixel (8/16 bits). + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_display_bpp(unsigned short bpp) +{ + GAL_DISPLAYPARAMS sDisplayParams; + + INIT_GAL(&sDisplayParams); + sDisplayParams.dwSubfunction = GALFN_SETDISPLAYBPP; + sDisplayParams.wBpp = bpp; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayParams)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_set_bpp + * + * Description: This function sets the number bits per pixel in the display + * mode of the galdevice. + * parameters: + * bpp: It specifies the bits per pixel (8/16 bits). + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_bpp(unsigned short bpp) +{ + GAL_DISPLAYPARAMS sDisplayParams; + + INIT_GAL(&sDisplayParams); + sDisplayParams.dwSubfunction = GALFN_SETBPP; + sDisplayParams.wBpp = bpp; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayParams)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_get_display_bpp + * + * Description: This function gets the number bits per pixel in the display + * mode of the galdevice. + * parameters: + * bpp: It specifies the bits per pixel (8/16 bits). + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_display_bpp(unsigned short *bpp) +{ + GAL_DISPLAYPARAMS sDisplayParams; + + INIT_GAL(&sDisplayParams); + sDisplayParams.dwSubfunction = GALFN_GETDISPLAYBPP; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayParams)) + return 0; + else { + *bpp = sDisplayParams.wBpp; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_set_display_pitch + * + * Description: This function sets the display pitch of the galdevice. + * parameters: + * pitch: It specifies pitch of the display mode. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_display_pitch(unsigned short pitch) +{ + GAL_DISPLAYPARAMS sDisplayParams; + + INIT_GAL(&sDisplayParams); + sDisplayParams.dwSubfunction = GALFN_SETDISPLAYPITCH; + sDisplayParams.wPitch = pitch; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayParams)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_get_display_pitch + * + * Description: This function gets the display pitch of the galdevice. + * parameters: + * pitch: It specifies pitch of the display mode. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_display_pitch(unsigned short *pitch) +{ + GAL_DISPLAYPARAMS sDisplayParams; + + INIT_GAL(&sDisplayParams); + sDisplayParams.dwSubfunction = GALFN_GETDISPLAYPITCH; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayParams)) + return 0; + else { + *pitch = sDisplayParams.wPitch; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_set_display_offset + * + * Description: This function sets the offset of display parameters. + * parameters: + * offset: It specifies the offset address of display parameters. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_display_offset(unsigned long offset) +{ + GAL_DISPLAYPARAMS sDisplayParams; + + INIT_GAL(&sDisplayParams); + sDisplayParams.dwSubfunction = GALFN_SETDISPLAYOFFSET; + sDisplayParams.dwOffset = offset; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayParams)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_get_display_offset + * + * Description: This function gets the offset of display parameters. + * parameters: + * offset: It specifies the offset address of display parameters. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_display_offset(unsigned long *offset) +{ + GAL_DISPLAYPARAMS sDisplayParams; + + INIT_GAL(&sDisplayParams); + sDisplayParams.dwSubfunction = GALFN_GETDISPLAYOFFSET; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDisplayParams)) + return 0; + else { + *offset = sDisplayParams.dwOffset; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_get_refreshrate_from_dotclock + * + * Description: This function gets the refreshrate from dotclock. + * parameters: + * xres: It specifies x co-ordinate resolution. + * Yres: It specifies y co-ordinate resolution. + * bpp: It specifies the bits per pixel (8/16 bits). + * hz: It is a pointer which holds the refresh rate of the display. + * frequency: It spcifies the frequency of the dotclock. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_refreshrate_from_dotclock(int xres, int yres, int bpp, int *hz, + unsigned long frequency) +{ + GAL_DOTCLKTOREFRESH sDclkToRefresh; + + INIT_GAL(&sDclkToRefresh); + sDclkToRefresh.dwSubfunction = GALFN_DOTCLKTOREFRESH; + sDclkToRefresh.wXres = xres; + sDclkToRefresh.wYres = yres; + sDclkToRefresh.wBpp = bpp; + sDclkToRefresh.dwDotClock = frequency; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sDclkToRefresh)) + return 0; + else { + *hz = sDclkToRefresh.wRefreshRate; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_get_display_timing + * + * Description: This function gets the display timing from galdevice. + * parameters: + * pDisplayTiming: It specifies the display timing of the galdevice. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_display_timing(PGAL_DISPLAYTIMING pDisplayTiming) +{ + INIT_GAL(pDisplayTiming); + pDisplayTiming->dwSubfunction = GALFN_GETDISPLAYTIMINGS; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pDisplayTiming)) + return 0; + else { + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_set_display_timing + * + * Description: This function sets the display timing of the galdevice. + * parameters: + * pDisplayTiming: It specifies the display timing of the galdevice. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_display_timing(PGAL_DISPLAYTIMING pDisplayTiming) +{ + INIT_GAL(pDisplayTiming); + pDisplayTiming->dwSubfunction = GALFN_SETDISPLAYTIMINGS; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pDisplayTiming)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_set_fixed_timings + * + * Description: This function sets the fixed display timings of the + * galdevice. + * parameters: + * pnlXres: It specifies the panel X resolution. + * pnlYres: It specifies the panel Y resolution. + * totXres: It specifies the total X resolution. + * totYres: It specifies the total Y resolution. + * bpp: It specifies the bits per pixel (8/16 bits). + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_fixed_timings(int pnlXres, int pnlYres, int totXres, + int totYres, int bpp) +{ + GAL_DISPLAYTIMING DisplayTiming; + + INIT_GAL(&DisplayTiming); + DisplayTiming.dwSubfunction = GALFN_SETFIXEDTIMINGS; + DisplayTiming.wHActive = pnlXres; /* panel Xres */ + DisplayTiming.wVActive = pnlYres; /* panel Yres */ + DisplayTiming.wHTotal = totXres; /* Total Xres */ + DisplayTiming.wVTotal = totYres; /* Total Yres */ + DisplayTiming.wBpp = bpp; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &DisplayTiming)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_set_display_palette_entry + * + * Description: This function sets the display palette entry of the + * galdevice. + * parameters: + * index: It specifies the palette index, + * palette: It specifies the palette of the galdevice. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_display_palette_entry(unsigned long index, unsigned long palette) +{ + GAL_PALETTE_ENTRY sPalette; + + INIT_GAL(&sPalette); + sPalette.dwSubfunction = GALFN_SETPALETTE_ENTRY; + sPalette.dwIndex = index; + sPalette.dwPalette = palette; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sPalette)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_get_display_palette_entry + * + * Description: This function gets the display palette entry of the + * galdevice. + * parameters: + * index: It specifies the palette index, + * palette: It is a pointer to the palette of the galdevice. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_display_palette_entry(unsigned long index, unsigned long *palette) +{ + GAL_PALETTE_ENTRY sPalette; + + INIT_GAL(&sPalette); + sPalette.dwSubfunction = GALFN_GETPALETTE_ENTRY; + sPalette.dwIndex = index; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sPalette)) + return 0; + else { + *palette = sPalette.dwPalette; + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_set_display_palette_entry + * + * Description: This function sets the display palette entry of the + * galdevice. + * parameters: + * pPalette: It specifies the palette structure of the galdevice. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_display_palette(PGAL_PALETTE pPalette) +{ + INIT_GAL(pPalette); + pPalette->dwSubfunction = GALFN_SETPALETTE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pPalette)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_get_display_palette_entry + * + * Description: This function gets the display palette entry of the + * galdevice. + * parameters: + * pPalette: It specifies the palette structure of the galdevice. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_display_palette(PGAL_PALETTE pPalette) +{ + INIT_GAL(pPalette); + pPalette->dwSubfunction = GALFN_GETPALETTE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pPalette)) + return 0; + else { + return 1; + } +} + +/*--------------------------------------------------------------------------- + * Gal_wait_until_idle + * + * Description: This function waits until the graphics engine is idle. + * parameters: none. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_wait_until_idle(void) +{ + GAL_WAITUNTILIDLE sWaitIdle; + + INIT_GAL(&sWaitIdle); + sWaitIdle.dwSubfunction = GALFN_WAITUNTILIDLE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sWaitIdle)) + return 0; + else + return 1; +} + +/*--------------------------------------------------------------------------- + * Gal_wait_vertical_blank + * + * Description: This function wait until start of vertical blank. + * parameters: none. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_wait_vertical_blank(void) +{ + GAL_WAITVERTICALBLANK sWaitVerticalBlank; + + INIT_GAL(&sWaitVerticalBlank); + sWaitVerticalBlank.dwSubfunction = GALFN_WAITVERTICALBLANK; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sWaitVerticalBlank)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_cursor_enable + * + * Description: This function enable or disable the hardware cursor. + * parameters: + * enable: This specifies the enable value of the cursor. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_cursor_enable(int enable) +{ + GAL_CURSORENABLE sCursorEnable; + + INIT_GAL(&sCursorEnable); + sCursorEnable.dwSubfunction = GALFN_SETCURSORENABLE; + sCursorEnable.bCursorEnable = enable ? 1 : 0; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCursorEnable)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_cursor_position + * + * Description: This function sets the position of the cursor. + * parameters: + * memoffset: It specifies the memory offset of the cursor position. + * xpos: It specifies the X co-ordinate position of the cursor. + * ypos: It specifies the Y co-ordinate position of the cursor. + * xhotspot: It specifies the X hotspot location for current cursor shape. + * yhotspot: It specifies the Y hotspot location for current cursor shape. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_cursor_position(unsigned long memoffset, + unsigned short xpos, unsigned short ypos, + unsigned short xhotspot, unsigned short yhotspot) +{ + GAL_CURSORPOSITION sCursorPos; + + INIT_GAL(&sCursorPos); + sCursorPos.dwSubfunction = GALFN_SETCURSORPOSITION; + sCursorPos.dwMemOffset = memoffset; + sCursorPos.wXPos = xpos; + sCursorPos.wYPos = ypos; + sCursorPos.wXHot = xhotspot; + sCursorPos.wYHot = yhotspot; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCursorPos)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_get_cursor_position + * + * Description: This function gets the cursor position. + * parameters: + * memoffset: It points the memory offset of the cursor position. + * xpos: It points the X co-ordinate position of the cursor. + * ypos: It points the Y co-ordinate position of the cursor. + * xhotspot: It points the X hotspot location for current cursor shape. + * yhotspot: It points the Y hotspot location for current cursor shape. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_cursor_position(unsigned long *memoffset, + unsigned short *xpos, unsigned short *ypos, + unsigned short *xhotspot, unsigned short *yhotspot) +{ + GAL_CURSORPOSITION sCursorPos; + + INIT_GAL(&sCursorPos); + sCursorPos.dwSubfunction = GALFN_GETCURSORPOSITION; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCursorPos)) + return 0; + else { + *memoffset = sCursorPos.dwMemOffset; + *xpos = sCursorPos.wXPos; + *ypos = sCursorPos.wYPos; + *xhotspot = sCursorPos.wXHot; + *yhotspot = sCursorPos.wYHot; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_cursor_shape32 + * + * Description: This function loads 32x32 cursor pattern. + * parameters: + * memoffset: It specifies the graphics memory offset for cursor shape. + * andmask: It is a pointer to 32 DWORD of AND data. + * xormask: It is a pointer to 32 DWORD of XOR data. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_cursor_shape32(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +{ + GAL_SETCURSORSHAPE sCursorShape; + + INIT_GAL(&sCursorShape); + sCursorShape.dwSubfunction = GALFN_SETCURSORSHAPE; + sCursorShape.dwMemOffset = memoffset; + + memcpy(sCursorShape.dwAndMask, andmask, sizeof(sCursorShape.dwAndMask)); + + memcpy(sCursorShape.dwXorMask, xormask, sizeof(sCursorShape.dwXorMask)); + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCursorShape)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_cursor_shape64 + * + * Description: This function loads 64x64 cursor pattern. + * parameters: + * memoffset: It specifies the graphics memory offset for cursor shape. + * andmask: It is a pointer to 64 DWORD of AND data. + * xormask: It is a pointer to 64 DWORD of XOR data. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ BOOLEAN +Gal_set_cursor_shape64(unsigned long memoffset, + unsigned long *andmask, unsigned long *xormask) +{ + GAL_SETCURSORSHAPE sCursorShape; + + INIT_GAL(&sCursorShape); + sCursorShape.dwSubfunction = GALFN_SETCURSORSHAPE_RCLD; + sCursorShape.dwMemOffset = memoffset; + + memcpy(sCursorShape.dwAndMask, andmask, sizeof(sCursorShape.dwAndMask)); + + memcpy(sCursorShape.dwXorMask, xormask, sizeof(sCursorShape.dwXorMask)); + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCursorShape)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_cursor_colors + * + * Description: This function sets the colors of the hardware cursor. + * parameters: + * bkcolor:It specifies the RGB value for the background color. + * fgcolor:It specifies the RGB value for the foreground color. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) +{ + GAL_CURSORCOLORS sCursorColor; + + INIT_GAL(&sCursorColor); + sCursorColor.dwSubfunction = GALFN_SETCURSORCOLORS; + sCursorColor.dwBgColor = bkcolor; + sCursorColor.dwFgColor = fgcolor; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCursorColor)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_get_cursor_colors + * + * Description: This function gets the colors of the hardware cursor. + * parameters: + * bkcolor:It points the RGB value for the background color. + * fgcolor:It points the RGB value for the foreground color. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_cursor_colors(unsigned long *bkcolor, unsigned long *fgcolor) +{ + GAL_CURSORCOLORS sCursorColor; + + INIT_GAL(&sCursorColor); + sCursorColor.dwSubfunction = GALFN_GETCURSORCOLORS; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCursorColor)) + return 0; + else { + *bkcolor = sCursorColor.dwBgColor; + *fgcolor = sCursorColor.dwFgColor; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_solid_pattern + * + * Description: This function sets a solid pattern color for future rendering. + * parameters: + * color: It specifies the pattern color in proper format for current + * display mode. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_solid_pattern(unsigned long color) +{ + GAL_SETSOLIDPATTERN sSetSoildPat; + + INIT_GAL(&sSetSoildPat); + sSetSoildPat.dwSubfunction = GALFN_SETSOLIDPATTERN; + sSetSoildPat.dwColor = color; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetSoildPat)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_solid_source + * + * Description: This function specifies a constant source data value for + * raster operations that use both pattern + * and source data. + * parameters: + * color: It specifies the source color. + * return: '1' was returned on success otherwise '0' was returned. + *-------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_solid_source(unsigned long color) +{ + GAL_SETSOLIDSOURCE sSetSolidSrc; + + INIT_GAL(&sSetSolidSrc); + sSetSolidSrc.dwSubfunction = GALFN_SETSOLIDSOURCE; + sSetSolidSrc.dwColor = color; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetSolidSrc)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_mono_source + * + * Description: + * parameters: + * bkcolor: It specifies the background color. + * fgcolor: It specifies the foreground color. + *transparency: It specifies the transparency flag. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, + unsigned char transparency) +{ + GAL_SETMONOSOURCE sSetMonoSrc; + + INIT_GAL(&sSetMonoSrc); + sSetMonoSrc.dwSubfunction = GALFN_SETMONOSOURCE; + sSetMonoSrc.dwFgColor = fgcolor; + sSetMonoSrc.dwBgColor = bgcolor; + sSetMonoSrc.cTransparency = transparency; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetMonoSrc)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_mono_pattern + * + * Description: This function specifies an 8x8 monochrome pattern + * used in future rendering operations. + * parameters: + * bkcolor: It specifies the background color. + * fgcolor: It specifies the foreground color. + * data0: It specifies the bits of 8x8 monochrome pattern. + * data1: It specifies the bits of 8x8 monochrome pattern. + *transparency: It specifies the transparency flag. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, + unsigned long data0, unsigned long data1, + unsigned char transparency) +{ + GAL_SETMONOPATTERN sSetMonoPat; + + INIT_GAL(&sSetMonoPat); + sSetMonoPat.dwSubfunction = GALFN_SETMONOPATTERN; + sSetMonoPat.dwFgColor = fgcolor; + sSetMonoPat.dwBgColor = bgcolor; + sSetMonoPat.dwData0 = data0; + sSetMonoPat.dwData1 = data1; + sSetMonoPat.cTransparency = transparency; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetMonoPat)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_raster_operation + * + * Description: This function specifies the raster operation for + * future rendering. + * parameters: + * rop: It specifies the ternary raster operation + * (pattern/source/destination). + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_raster_operation(unsigned char rop) +{ + GAL_RASTEROPERATION sSetRop; + + INIT_GAL(&sSetRop); + sSetRop.dwSubfunction = GALFN_SETRASTEROPERATION; + sSetRop.cRop = rop; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetRop)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_pattern_fill + * + * Description: This function renders pattern data to a rectangular + * region. + * parameters: + * x: It specifies the screen X position, in pixels. + * y: It specifies the screen Y position, in pixels. + * width: It specifies the width of rectangle, in pixels. + * height: It specifies the height of rectangle, in pixels. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height) +{ + GAL_PATTERNFILL sPatternFill; + + INIT_GAL(&sPatternFill); + sPatternFill.dwSubfunction = GALFN_PATTERNFILL; + sPatternFill.wXPos = x; + sPatternFill.wYPos = y; + sPatternFill.wWidth = width; + sPatternFill.wHeight = height; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sPatternFill)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_screen_to_screen_blt + * + * Description: This function is used to perform a screen to screen + * BLT operation. + * parameters: + * srcx: It specifies the source X position. + * srcy: It specifies the source Y position. + * dstx: It specifies the destination X position. + * dsty: It specifies the destination Y position. + * width: It specifies the width of BLT, in pixels. + * height: It specifies the height of BLT, in pixels. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height) +{ + GAL_SCREENTOSCREENBLT sScreenBlt; + + INIT_GAL(&sScreenBlt); + sScreenBlt.dwSubfunction = GALFN_SCREENTOSCREENBLT; + sScreenBlt.wXStart = srcx; + sScreenBlt.wYStart = srcy; + sScreenBlt.wXEnd = dstx; + sScreenBlt.wYEnd = dsty; + sScreenBlt.wWidth = width; + sScreenBlt.wHeight = height; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sScreenBlt)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_screen_to_screen_xblt + * + * Description: This function is used to perform a screen to screen + * BLT operation using a transparency color. + * parameters: + * srcx: It specifies the source X position. + * srcy: It specifies the source Y position. + * dstx: It specifies the destination X position. + * dsty: It specifies the destination Y position. + * width: It specifies the width of BLT, in pixels. + * height: It specifies the height of BLT, in pixels. + * color: It specifies the transparency color. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long color) +{ + GAL_SCREENTOSCREENXBLT sScreenXBlt; + + INIT_GAL(&sScreenXBlt); + sScreenXBlt.dwSubfunction = GALFN_SCREENTOSCREENXBLT; + sScreenXBlt.wXStart = srcx; + sScreenXBlt.wYStart = srcy; + sScreenXBlt.wXEnd = dstx; + sScreenXBlt.wYEnd = dsty; + sScreenXBlt.wWidth = width; + sScreenXBlt.wHeight = height; + sScreenXBlt.dwColor = color; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sScreenXBlt)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_bresenham_line + * + * Description: This function is used to draw a single pixel line + * using the specified Bresenham parameters. + * parameters: + * x: It specifies the starting X position. + * y: It specifies the starting Y position. + * length: It specifies the length of the vector, in pixels. + * initerr: It specifies the Bresenham initial error term. + * axialerr: It specifies the Bresenham axial error term + * (moving in major direction only). + * diagerr: It specifies Bresenham diagonal error term + * (moving in major and minor direction. + * flags: It specifies the flag. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_bresenham_line(unsigned short x, unsigned short y, + unsigned short length, unsigned short initerr, + unsigned short axialerr, unsigned short diagerr, + unsigned short flags) +{ + GAL_BRESENHAMLINE sBresenhamLine; + + INIT_GAL(&sBresenhamLine); + sBresenhamLine.dwSubfunction = GALFN_BRESENHAMLINE; + sBresenhamLine.wX1 = x; + sBresenhamLine.wY1 = y; + sBresenhamLine.wLength = length; + sBresenhamLine.wErr = initerr; + sBresenhamLine.wE1 = axialerr; + sBresenhamLine.wE2 = diagerr; + sBresenhamLine.wFlags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sBresenhamLine)) + return 0; + else + return 1; +} + +BOOLEAN +Gal_color_pattern_fill(unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + unsigned long pattern) +{ + GAL_COLOR_PATTERNFILL sColorPat; + + INIT_GAL(&sColorPat); + sColorPat.dwSubfunction = GALFN_COLOR_PATTERNFILL; + sColorPat.wDstx = x; + sColorPat.wDsty = y; + sColorPat.wWidth = width; + sColorPat.wHeight = height; + sColorPat.dwPattern = pattern; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sColorPat)) + return 0; + else + return 1; +} + +BOOLEAN +Gal_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long data, long pitch) +{ + GAL_COLOR_BITMAP_TO_SCREEN_BLT sBmp2Scr; + + INIT_GAL(&sBmp2Scr); + sBmp2Scr.dwSubfunction = GALFN_COLOR_BITMAP_TO_SCREEN_BLT; + sBmp2Scr.wSrcx = srcx; + sBmp2Scr.wSrcy = srcy; + sBmp2Scr.wDstx = dstx; + sBmp2Scr.wDsty = dsty; + sBmp2Scr.wWidth = width; + sBmp2Scr.wHeight = height; + sBmp2Scr.dwData = data; + sBmp2Scr.wPitch = pitch; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sBmp2Scr)) + return 0; + else + return 1; +} + +BOOLEAN +Gal_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long data, long pitch, + unsigned long color) +{ + GAL_COLOR_BITMAP_TO_SCREEN_XBLT sBmp2Scr; + + INIT_GAL(&sBmp2Scr); + sBmp2Scr.dwSubfunction = GALFN_COLOR_BITMAP_TO_SCREEN_XBLT; + sBmp2Scr.wSrcx = srcx; + sBmp2Scr.wSrcy = srcy; + sBmp2Scr.wDstx = dstx; + sBmp2Scr.wDsty = dsty; + sBmp2Scr.wWidth = width; + sBmp2Scr.wHeight = height; + sBmp2Scr.dwData = data; + sBmp2Scr.wPitch = pitch; + sBmp2Scr.dwColor = color; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sBmp2Scr)) + return 0; + else + return 1; +} + +BOOLEAN +Gal_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned long data, short pitch) +{ + GAL_MONO_BITMAP_TO_SCREEN_BLT sBmp2Scr; + + INIT_GAL(&sBmp2Scr); + sBmp2Scr.dwSubfunction = GALFN_MONO_BITMAP_TO_SCREEN_BLT; + sBmp2Scr.wSrcx = srcx; + sBmp2Scr.wSrcy = srcy; + sBmp2Scr.wDstx = dstx; + sBmp2Scr.wDsty = dsty; + sBmp2Scr.wWidth = width; + sBmp2Scr.wHeight = height; + sBmp2Scr.dwData = data; + sBmp2Scr.wPitch = pitch; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sBmp2Scr)) + return 0; + else + return 1; +} + +BOOLEAN +Gal_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, + unsigned short height, unsigned long data) +{ + GAL_TEXT_BLT sTextBlt; + + INIT_GAL(&sTextBlt); + sTextBlt.dwSubfunction = GALFN_TEXT_BLT; + sTextBlt.wDstx = dstx; + sTextBlt.wDsty = dsty; + sTextBlt.wWidth = width; + sTextBlt.wHeight = height; + sTextBlt.dwData = data; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sTextBlt)) + return 0; + else + return 1; +} + +/*------------------------------------------------------------------------ + * Gal_set_compression_enable + * + * Description: This function enables or disables display + * compression. + * parameters: + * bCompressionState: It specifies the display compression state. + * return: '1' was returned on success otherwise + * '0' was returned. + *----------------------------------------------------------------------*/ +BOOLEAN +Gal_set_compression_enable(BOOLEAN bCompressionState) +{ + GAL_COMPRESSIONSTATE sCompState; + + INIT_GAL(&sCompState); + sCompState.dwSubfunction = GALFN_SETCOMPRESSIONSTATE; + sCompState.bCompressionState = bCompressionState; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCompState)) + return 0; + else + return 1; +} + +/*------------------------------------------------------------------------ + * Gal_get_compression_enable + * + * Description: This function gets the compression state. + * + * parameters: + * bCompressionState: gets the display compression state. + * return: '1' was returned on success otherwise + * '0' was returned. + *----------------------------------------------------------------------*/ +BOOLEAN +Gal_get_compression_enable(int *bCompressionState) +{ + GAL_COMPRESSIONSTATE sCompState; + + INIT_GAL(&sCompState); + sCompState.dwSubfunction = GALFN_GETCOMPRESSIONSTATE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCompState)) + return 0; + else { + *bCompressionState = sCompState.bCompressionState; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_compression_parameters + * + * Description: This function sets the compression parameters of the + * frame buffer device. + * parameters: + * flags: It specifies the flag. + * offset: It specifies the base offset in graphics memory for the + * compression buffer. + * pitch: It specifies the pitch of compression buffer, in bytes. + * size: It specifies the maximum line size of the compression buffer + * in bytes. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_compression_parameters(unsigned long flags, + unsigned long offset, unsigned short pitch, + unsigned short size) +{ + GAL_COMPRESSIONPARAMS sCompParams; + + INIT_GAL(&sCompParams); + sCompParams.dwSubfunction = GALFN_SETCOMPRESSIONPARAMS; + sCompParams.dwFlags = flags; + sCompParams.dwCompOffset = offset; + sCompParams.dwCompPitch = pitch; + sCompParams.dwCompSize = size; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCompParams)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_get_compression_parameters + * + * Description: This function gets the compression parameters of the + * frame buffer device. + * parameters: + * flags: It specifies the flag. + * offset: gets the base offset in graphics memory for the + * compression buffer. + * pitch: gets the pitch of compression buffer, in bytes. + * size: gets the maximum line size of the compression buffer + * in bytes. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_compression_parameters(unsigned long flags, + unsigned long *offset, + unsigned short *pitch, unsigned short *size) +{ + GAL_COMPRESSIONPARAMS sCompParams; + + INIT_GAL(&sCompParams); + sCompParams.dwSubfunction = GALFN_GETCOMPRESSIONPARAMS; + sCompParams.dwFlags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sCompParams)) + return 0; + else { + *offset = sCompParams.dwCompOffset; + *pitch = sCompParams.dwCompPitch; + *size = sCompParams.dwCompSize; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_vga_mode_switch + * + * Description:This function signals the beginning or end of a + * mode switch. + * parameters: + * active: It specifies the mode switch. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_mode_switch(int active) +{ + GAL_VGAMODEDATA sVgaData; + + INIT_GAL(&sVgaData); + sVgaData.dwSubfunction = GALFN_VGAMODESWITCH; + sVgaData.dwFlags = active; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sVgaData)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_vga_clear_extended + * + * Description: This will clear the Svga data. + * parameters: none. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_clear_extended(void) +{ + GAL_VGAMODEDATA sVgaData; + + INIT_GAL(&sVgaData); + sVgaData.dwSubfunction = GALFN_VGACLEARCRTEXT; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sVgaData)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_vga_pitch + * + * Description: This function sets VGA register values in VGA + * structure for specified pitch. + * parameters: + * pVgaData: It specifies the vga structure. + * pitch: It specifies the number of bytes between scanlines. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_pitch(PGAL_VGAMODEDATA pVgaData, unsigned short pitch) +{ + INIT_GAL(pVgaData); + pVgaData->dwSubfunction = GALFN_VGASETPITCH; + pVgaData->dwFlags = pitch; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pVgaData)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_vga_restore + * + * Description: This function sets the VGA state to the values in the + * VGA structure. + * parameters: + * pVgaData: It specifies the vga structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_restore(PGAL_VGAMODEDATA pVgaData) +{ + INIT_GAL(pVgaData); + pVgaData->dwSubfunction = GALFN_VGARESTORE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pVgaData)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_vga_save + * + * Description: This function saves the current VGA state in the + * VGA structure. + * parameters: + * pVgaData: It specifies the vga structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_save(PGAL_VGAMODEDATA pVgaData) +{ + INIT_GAL(pVgaData); + pVgaData->dwSubfunction = GALFN_VGASAVE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pVgaData)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_vga_mode + * + * Description: This function sets VGA register values in VGA + * structure for specified mode. + * parameters: + * pVgaData: It specifies the vga structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_vga_mode(PGAL_VGAMODEDATA pVgaData) +{ + INIT_GAL(pVgaData); + pVgaData->dwSubfunction = GALFN_VGASETMODE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pVgaData)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_enabled_in_bios + * + * Description: This function gets the status of the FP in BIOS. + * parameters: + * status: returns the state of FP in Bios. + * pParam: It specifies the panel parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_enabled_in_bios(int *state) +{ + GAL_PNLBIOS pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLBIOSENABLE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else { + *state = pStat.state; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_info_from_bios + * + * Description: This function gets the parameters of the FP in BIOS. + * parameters: + * status: returns the state of FP in Bios. + * pParam: It specifies the panel parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_info_from_bios(int *xres, int *yres, int *bpp, int *hz) +{ + GAL_PNLBIOS pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLBIOSINFO; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else { + *xres = pStat.XRes; + *yres = pStat.YRes; + *bpp = pStat.Bpp; + *hz = pStat.Freq; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_set_params + * + * Description: This function sets the panel parameters. + * parameters: + * flags: + * pParam: It specifies the panel parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_set_params(unsigned long flags, PPnl_PanelParams pParam) +{ + GAL_PNLPARAMS pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLSETPARAMS; + pParam->Flags = flags; + memcpy(&(pStat.PanelParams), pParam, sizeof(Pnl_PanelParams)); + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_get_params + * + * Description: This function gets the panel parameters. + * parameters: + * flags: + * pParam: It specifies the panel parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_get_params(unsigned long flags, PPnl_PanelParams pParam) +{ + GAL_PNLPARAMS pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLGETPARAMS; + memcpy(&(pStat.PanelParams), pParam, sizeof(Pnl_PanelParams)); + pStat.PanelParams.Flags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else { + memcpy(pParam, &(pStat.PanelParams), sizeof(Pnl_PanelParams)); + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_init + * + * Description: This function initializes the panel parameters. + * parameters: + * pParam: It specifies the panel parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_init(PPnl_PanelParams pParam) +{ + GAL_PNLPARAMS pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLINITPANEL; + memcpy(&(pStat.PanelParams), pParam, sizeof(Pnl_PanelParams)); + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else + return 1; + +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_save + * + * Description: This function saves the current panel parameters. + * parameters: none. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_save(void) +{ + GAL_PNLPARAMS pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLSAVESTATE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_restore + * + * Description: This function restores the current panel parameters. + * parameters: none. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_restore(void) +{ + GAL_PNLPARAMS pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLRESTORESTATE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_powerup + * + * Description: This function powers up the panel. + * parameters: none. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_powerup(void) +{ + GAL_BASE pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLPOWERUP; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_pnl_powerdown + * + * Description: This function powers down the panel. + * parameters: none. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_pnl_powerdown(void) +{ + GAL_BASE pStat; + + INIT_GAL(&pStat); + pStat.dwSubfunction = GALFN_PNLPOWERDOWN; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pStat)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_tv_set_params + * + * Description: This function sets the tv parameters of + * tvparameters structure. + * parameters: + * flags: + * pTV: It specifies the tv parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_tv_set_params(unsigned long flags, PGAL_TVPARAMS pTV) +{ + INIT_GAL(pTV); + pTV->dwSubfunction = GALFN_SETTVPARAMS; + pTV->dwFlags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pTV)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_tv_get_params + * + * Description: This function gets the tv parameters of + * tvparameters structure. + * parameters: + * flags: Dummy flag + * pTV: It specifies the tv parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_tv_get_params(unsigned long flags, PGAL_TVPARAMS pTV) +{ + INIT_GAL(pTV); + pTV->dwSubfunction = GALFN_GETTVPARAMS; + pTV->dwFlags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pTV)) + return 0; + else + return 1; + +} + +/*-------------------------------------------------------------------------- + * Gal_tv_set_timings + * + * Description: This function sets the tv timing registers. + * parameters: + * flags: Dummy flag. + * pTV: It specifies the tv parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_tv_set_timings(unsigned long flags, PGAL_TVTIMING pTV) +{ + INIT_GAL(pTV); + pTV->dwSubfunction = GALFN_SETTVTIMING; + pTV->dwFlags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pTV)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_tv_get_timings + * + * Description: This function gets the tv timing registers. + * parameters: + * flags: Dummy flag. + * pTV: It specifies the tv parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_tv_get_timings(unsigned long flags, PGAL_TVTIMING pTV) +{ + INIT_GAL(pTV); + pTV->dwSubfunction = GALFN_GETTVTIMING; + pTV->dwFlags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pTV)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_tv_enable + * + * Description: This function sets the tv state of the device . + * parameters: + * bState : set the tv state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_tv_enable(int bState) +{ + GAL_TVPARAMS pTV; + + INIT_GAL(&pTV); + pTV.dwSubfunction = GALFN_SETENABLE; + pTV.bState = bState; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pTV)) + return 0; + else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_tv_enable + * + * Description: This function gets the tv state of the device . + * parameters: + * bState : get the tv state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_tv_enable(unsigned int *bState) +{ + GAL_TVPARAMS pTV; + + INIT_GAL(&pTV); + pTV.dwSubfunction = GALFN_GETENABLE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &pTV)) { + *bState = 0; + return 0; + } else { + *bState = pTV.bState; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_is_tv_mode_supported + * + * Description: This function checks the tv mode is supported or not. + * parameters: + * flags: Dummy flag + * pTV: It specifies the tv parameters structure. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_is_tv_mode_supported(unsigned long flags, PGAL_TVPARAMS pTV, int *bState) +{ + INIT_GAL(pTV); + pTV->dwSubfunction = GALFN_ISTVMODESUPPORTED; + pTV->dwFlags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, pTV)) { + return 0; + } else { + *bState = pTV->bState; + return 1; + } +} + +/** Video **********************************************************/ + +/*-------------------------------------------------------------------------- + * Gal_set_video_enable + * + * Description: This function sets the video enable state. + * parameters: + * enable: Its value is '1' to enable video and '0' to disable video. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_enable(int enable) +{ + GAL_VIDEOENABLE sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOENABLE; + sSetVideo.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_format + * + * Description: This function sets the video format. + * parameters: + * format: Its video format value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_format(int format) +{ + GAL_VIDEOFORMAT sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOFORMAT; + sSetVideo.format = format; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_size + * + * Description: This function sets the video size. + * parameters: + * width: Width of the video. + * height: Height of the video. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_size(unsigned short width, unsigned short height) +{ + GAL_VIDEOSIZE sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOSIZE; + sSetVideo.width = width; + sSetVideo.height = height; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_offset + * + * Description: This function sets the video size. + * parameters: + * offset: Offset of the video. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_offset(unsigned long offset) +{ + GAL_VIDEOOFFSET sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOOFFSET; + sSetVideo.offset = offset; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_window + * + * Description: This function sets the video window. + * parameters: + * x: X co-ordinate of the Video screen. + * y: Y co-ordinate of the Video screen. + * w: Width of the Video screen. + * h: Height of the Video screen. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_window(short x, short y, short w, short h) +{ + GAL_VIDEOWINDOW sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOWINDOW; + sSetVideo.x = x; + sSetVideo.y = y; + sSetVideo.w = w; + sSetVideo.h = h; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_scale + * + * Description: This function sets the video scale. + * parameters: + * srcw: Source width. + * srch: Source height. + * dstw: Destination width. + * dsth: Destination height. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_scale(unsigned short srcw, unsigned short srch, + unsigned short dstw, unsigned short dsth) +{ + GAL_VIDEOSCALE sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOSCALE; + sSetVideo.srcw = srcw; + sSetVideo.srch = srch; + sSetVideo.dstw = dstw; + sSetVideo.dsth = dsth; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_filter. + * + * Description: This function sets the video filter. + * parameters: + * xfilter: X-co-ordinate filter. + * yfilter: Y-co-ordinate filter. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_filter(int xfilter, int yfilter) +{ + GAL_VIDEOFILTER sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOFILTER; + sSetVideo.xfilter = xfilter; + sSetVideo.yfilter = yfilter; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_color_key. + * + * Description: This function sets the video color key. + * parameters: + * key: Color key. + * mask: Color mask. + * bluescreen: Value for bluescreen. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_color_key(unsigned long key, unsigned long mask, int bluescreen) +{ + GAL_VIDEOCOLORKEY sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOCOLORKEY; + sSetVideo.key = key; + sSetVideo.mask = mask; + sSetVideo.bluescreen = bluescreen; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_downscale_enable. + * + * Description: This function sets the video downscale enable state. + * parameters: + * enable: Value for enable or disable the video downscale. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_downscale_enable(int enable) +{ + GAL_VIDEODOWNSCALEENABLE sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEODOWNSCALEENABLE; + sSetVideo.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_downscale_config. + * + * Description: This function sets the video downscale configuration. + * parameters: + * type: Video down scale type. + * m: Factor for the Video overlay window. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_downscale_config(unsigned short type, unsigned short m) +{ + GAL_VIDEODOWNSCALECONFIG sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEODOWNSCALECONFIG; + sSetVideo.type = type; + sSetVideo.m = m; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_downscale_coefficients. + * + * Description: This function sets the video downscale coefficients. + * parameters: + * coef1: Video downscale filter coefficient. + * coef2: Video downscale filter coefficient. + * coef3: Video downscale filter coefficient. + * coef4: Video downscale filter coefficient. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_downscale_coefficients(unsigned short coef1, + unsigned short coef2, + unsigned short coef3, + unsigned short coef4) +{ + GAL_VIDEODOWNSCALECOEFF sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEODOWNSCALECOEFF; + sSetVideo.coef1 = coef1; + sSetVideo.coef2 = coef2; + sSetVideo.coef3 = coef3; + sSetVideo.coef4 = coef4; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_source. + * + * Description: This function sets the video source to either memory or Direct + * VIP + * parameters: + * source: Video source. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_source(int source) +{ + GAL_VIDEOSOURCE sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOSOURCE; + sSetVideo.source = source; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_interlaced + * + * Description: This function configures the Video processor video overlay mode + * to be interlaced YUV. + * parameters: + * enable: Value used to enable or disalbe the Video interlaced. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ + +BOOLEAN +Gal_set_video_interlaced(int enable) +{ + GAL_SETVIDEOINTERLACED sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOINTERLACED; + sSetVideo.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_color_space + * + * Description: This function configures the Video processor to prcoess + * graphics and video in either YUV or RGB color space. + * + * parameters: + * enable: Value used to enable or disalbe the Video color space. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_color_space_YUV(int colorspace) +{ + GAL_COLORSPACEYUV sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOCOLORSPACE; + sSetVideo.colorspace = colorspace; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_cursor. + * + * Description: This function configures the Video Hardware cursor. + * + * + * parameters: + * key: color key. + * mask: color mask. + *select_color2: selected for color2. + * color1: color1 value. + * color2: color2 value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_cursor(unsigned long key, + unsigned long mask, + unsigned short select_color2, + unsigned long color1, unsigned long color2) +{ + GAL_VIDEOCURSOR sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOCURSOR; + sSetVideo.key = key; + sSetVideo.mask = mask; + sSetVideo.select_color2 = select_color2; + sSetVideo.color1 = color1; + sSetVideo.color2 = color2; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_request. + * + * Description: This function sets the horizontal(pixel) and vertical(line) + * video request values. + * + * parameters: + * x: X video request value. + * y: Y video request value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_request(short x, short y) +{ + GAL_VIDEOREQUEST sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOREQUEST; + sSetVideo.x = x; + sSetVideo.y = y; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_alpha_enable. + * + * Description: This function enables or disables the currently selected + * alpha region. + * + * parameters: + * enable: Value to enalbe or disable alha region. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_alpha_enable(int enable) +{ + GAL_ALPHAENABLE sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETALPHAENABLE; + sSetVideo.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_get_alpha_enable. + * + * Description: This function gets the alpha enable state. + * + * parameters: + * enable: Pointer to get the enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_alpha_enable(int *enable) +{ + GAL_ALPHAENABLE sGetalphaenable; + + INIT_GAL(&sGetalphaenable); + sGetalphaenable.dwSubfunction = GALFN_GETALPHAENABLE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetalphaenable)) + return 0; + else + + *enable = sGetalphaenable.enable; + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_alpha_window + * + * Description: This function sets the size of the currently selected + * alpha region. + * parameters: + * x: X co-ordinate of the alpha region. + * y: Y co-ordinate of the alpha region. + * width: Width of the alpha region. + * height: Height of the alpha region. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_alpha_window(short x, short y, + unsigned short width, unsigned short height) +{ + GAL_ALPHAWINDOW sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETALPHAWINDOW; + sSetVideo.x = x; + sSetVideo.y = y; + sSetVideo.width = width; + sSetVideo.height = height; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_get_alpha_size + * + * Description: This function gets the size of the currently selected + * alpha region. + * parameters: + * x: X co-ordinate of the alpha region. + * y: Y co-ordinate of the alpha region. + * width: Width of the alpha region. + * height: Height of the alpha region. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_alpha_size(unsigned short *x, unsigned short *y, + unsigned short *width, unsigned short *height) +{ + GAL_ALPHASIZE sGetalphasize; + + INIT_GAL(&sGetalphasize); + sGetalphasize.dwSubfunction = GALFN_GETALPHASIZE; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetalphasize)) + return 0; + else { + *x = *(sGetalphasize.x); + *y = *(sGetalphasize.y); + *width = *(sGetalphasize.width); + *height = *(sGetalphasize.height); + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_alpha_value + * + * Description: This function sets the alpha value for the selected alpha + * region. It also specifies an increment/decrement value for + * fading. + * parameters: + * alpha: Alpha value for the currently selected alpha region. + * delta: Gives the increment/decrement fading value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_alpha_value(unsigned char alpha, char delta) +{ + GAL_ALPHAVALUE sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETALPHAVALUE; + sSetVideo.alpha = alpha; + sSetVideo.delta = delta; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_get_alpha_value + * + * Description: This function gets the alpha value for the selected alpha + * region. It also gets increment/decrement value for + * fading. + * parameters: + * alpha: Alpha value for the currently selected alpha region. + * delta: Gives the increment/decrement fading value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_alpha_value(unsigned char *alpha, char *delta) +{ + GAL_ALPHAVALUE sGetalphavalue; + + INIT_GAL(&sGetalphavalue); + sGetalphavalue.dwSubfunction = GALFN_GETALPHAVALUE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetalphavalue)) + return 0; + else { + *alpha = sGetalphavalue.alpha; + *delta = sGetalphavalue.delta; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_alpha_priority + * + * Description: This function sets the priority of the selected alpha + * region. + * parameters: + * priority: Gives the priority value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_alpha_priority(int priority) +{ + GAL_ALPHAPRIORITY sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETALPHAPRIORITY; + sSetVideo.priority = priority; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_get_alpha_priority + * + * Description: This function gets the priority of the selected alpha + * region. + * parameters: + * priority: Gives the priority value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_alpha_priority(int *priority) +{ + GAL_ALPHAPRIORITY sGetalphapriority; + + INIT_GAL(&sGetalphapriority); + sGetalphapriority.dwSubfunction = GALFN_GETALPHAPRIORITY; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetalphapriority)) + return 0; + else { + *priority = sGetalphapriority.priority; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_alpha_color + * + * Description: This function sets the color to be displayed inside the + * currently of the selected alpha window. + * parameters: + * color: Gives the color value to be displayed. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_alpha_color(unsigned long color) +{ + GAL_ALPHACOLOR sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETALPHACOLOR; + sSetVideo.color = color; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_get_alpha_color + * + * Description: This function gets the color to be displayed inside the + * currently of the selected alpha window. + * parameters: + * color: Gives the color value to be displayed. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_alpha_color(unsigned long *color) +{ + GAL_ALPHACOLOR sGetalphacolor; + + INIT_GAL(&sGetalphacolor); + sGetalphacolor.dwSubfunction = GALFN_GETALPHACOLOR; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetalphacolor)) + return 0; + else { + *color = sGetalphacolor.color; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_select_alpha_region + * + * Description: This function selects the alpha region should be used for + * future updates. + * parameters: + * region: Gives the alpha window number. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_select_alpha_region(int region) +{ + GAL_ALPHAREGION sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETALPHAREGION; + sSetVideo.region = region; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_outside_alpha + * + * Description: This function enable/disable the video outside alpha region. + * parameters: + * enable: Gives the value for enable/disable. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_outside_alpha(int enable) +{ + GAL_VIDEOOUTSIDEALPHA sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOOUTSIDEALPHA; + sSetVideo.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_palette + * + * Description: This function loads the video hardware palette. + * parameters: + * palette: Gives value for hardware palette. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_palette(unsigned long *palette) +{ + GAL_VIDEOPALETTE sSetVideo; + + INIT_GAL(&sSetVideo); + sSetVideo.dwSubfunction = GALFN_SETVIDEOPALETTE; + + if (palette == NULL) { + sSetVideo.identity = 1; + } else { + sSetVideo.identity = 0; + memcpy(sSetVideo.palette, palette, 256 * sizeof(*palette)); + } + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideo)) + return 0; + else + return 1; +} + +/** Video **********************************************************/ + +/*-------------------------------------------------------------------------- + * Gal_set_icon_enable + * + * Description: This function enable/disables the hardware icon. The icon + * position and colors should be programmed prior to calling + * this routine. + * parameters: + * enable: Gives value for enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_icon_enable(int enable) +{ + GAL_ICONENABLE sSetIconenable; + + INIT_GAL(&sSetIconenable); + sSetIconenable.dwSubfunction = GALFN_SETICONENABLE; + sSetIconenable.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetIconenable)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_icon_colors + * + * Description: This function sets the three hardware icon colors. + * parameters: + * color0: Gives first color value. + * color1: Gives second color value. + * color2: Gives third color value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_icon_colors(unsigned long color0, unsigned long color1, + unsigned long color2) +{ + GAL_ICONCOLORS sSetIconcolors; + + INIT_GAL(&sSetIconcolors); + sSetIconcolors.dwSubfunction = GALFN_SETICONCOLORS; + sSetIconcolors.color0 = color0; + sSetIconcolors.color1 = color1; + sSetIconcolors.color2 = color2; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetIconcolors)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_icon_position. + * + * Description: This function sets the hardware icon position. + * parameters: + * memoffset: Memory offset of the icon buffer. + * xpos: Starting X co-ordinate for the hardware icon. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_icon_position(unsigned long memoffset, unsigned short xpos) +{ + GAL_ICONPOSITION sSetIconposi; + + INIT_GAL(&sSetIconposi); + sSetIconposi.dwSubfunction = GALFN_SETICONPOSITION; + sSetIconposi.memoffset = memoffset; + sSetIconposi.xpos = xpos; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetIconposi)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_icon_shape64. + * + * Description: This function initializes the icon buffer according to + * the current mode. + * parameters: + * memoffset: Memory offset of the icon buffer. + * andmask: Andmask of the icon buffer. + * xormask: Xormask of the icon buffer. + * lines: Lines of the icon buffer. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_icon_shape64(unsigned long memoffset, unsigned long *andmask, + unsigned long *xormask, unsigned int lines) +{ + GAL_ICONSHAPE64 sSetIconshape64; + + INIT_GAL(&sSetIconshape64); + sSetIconshape64.dwSubfunction = GALFN_SETICONSHAPE64; + sSetIconshape64.memoffset = memoffset; + *(sSetIconshape64.andmask) = *andmask; + *(sSetIconshape64.xormask) = *xormask; + sSetIconshape64.lines = lines; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetIconshape64)) { + return 0; + } else { + return 1; + } +} + +/* VIP Functions */ + +/*-------------------------------------------------------------------------- + * Gal_set_vip_enable + * + * Description: This function enable/disables the writes to memory from the + * video port. + * position and colors should be programmed prior to calling + * this routine. + * parameters: + * enable: Gives value for enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vip_enable(int enable) +{ + GAL_VIPENABLE sSetVipenable; + + INIT_GAL(&sSetVipenable); + sSetVipenable.dwSubfunction = GALFN_SETVIPENABLE; + sSetVipenable.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVipenable)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vip_enable + * + * Description: This function gets the enable state of the + * video port. + * parameters: + * enable: Gives value for enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vip_enable(int *enable) +{ + GAL_VIPENABLE sGetVipenable; + + INIT_GAL(&sGetVipenable); + sGetVipenable.dwSubfunction = GALFN_GETVIPENABLE; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVipenable)) { + return 0; + } else { + + *enable = sGetVipenable.enable; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vip_capture_run_mode + * + * Description: This function selects the VIP capture run mode. + * + * parameters: + * mode: VIP capture run mode. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vip_capture_run_mode(int mode) +{ + GAL_VIPCAPTURERUNMODE sSetVipcapturerunmode; + + INIT_GAL(&sSetVipcapturerunmode); + sSetVipcapturerunmode.dwSubfunction = GALFN_SETVIPCAPTURERUNMODE; + sSetVipcapturerunmode.mode = mode; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVipcapturerunmode)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vip_base + * + * Description: This routine sets the odd and even base address values for + * the VIP memory buffer. + * parameters: + * even: Even base address. + * odd: odd base address. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vip_base(unsigned long even, unsigned long odd) +{ + GAL_VIPBASE sSetVipBase; + + INIT_GAL(&sSetVipBase); + sSetVipBase.dwSubfunction = GALFN_SETVIPBASE; + sSetVipBase.even = even; + sSetVipBase.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVipBase)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vip_base + * + * Description: This routine gets the base address value for + * the VIP memory buffer. + * parameters: + * address: VIP base address. + * odd: odd base address. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vip_base(unsigned long *address, int odd) +{ + GAL_VIPBASE sGetVipBase; + + INIT_GAL(&sGetVipBase); + sGetVipBase.dwSubfunction = GALFN_GETVIPBASE; + sGetVipBase.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVipBase)) { + return 0; + } else { + *address = sGetVipBase.address; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vip_pitch + * + * Description: This routine sets the number of bytes between scanlines + * for the VIP data. + * parameters: + * pitch: VIP pitch. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vip_pitch(unsigned long pitch) +{ + GAL_VIPPITCH sSetVipPitch; + + INIT_GAL(&sSetVipPitch); + sSetVipPitch.dwSubfunction = GALFN_SETVIPPITCH; + sSetVipPitch.pitch = pitch; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVipPitch)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vip_pitch + * + * Description: This routine gets the number of bytes between scanlines + * for the VIP data. + * parameters: + * pitch: VIP pitch. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vip_pitch(unsigned long *pitch) +{ + GAL_VIPPITCH sGetVipPitch; + + INIT_GAL(&sGetVipPitch); + sGetVipPitch.dwSubfunction = GALFN_GETVIPPITCH; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVipPitch)) { + return 0; + } else { + *pitch = sGetVipPitch.pitch; + return 1; + + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vip_mode + * + * Description: This routine sets the VIP operating mode. + * parameters: + * mode: VIP operating mode. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vip_mode(int mode) +{ + GAL_VIPMODE sSetVipMode; + + INIT_GAL(&sSetVipMode); + sSetVipMode.dwSubfunction = GALFN_SETVIPMODE; + sSetVipMode.mode = mode; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVipMode)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vip_mode + * + * Description: This routine gets the VIP operating mode. + * parameters: + * mode: VIP operating mode. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vip_mode(int *mode) +{ + GAL_VIPMODE sGetVipMode; + + INIT_GAL(&sGetVipMode); + sGetVipMode.dwSubfunction = GALFN_GETVIPMODE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVipMode)) { + return 0; + } else { + + *mode = sGetVipMode.mode; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vip_bus_request_threshold_high + * + * Description: This function sets the VIP FIFO bus request threshold. + * + * parameters: + * enable: Enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vip_bus_request_threshold_high(int enable) +{ + GAL_VIPBUS_RTH sSetVipBRTH; + + INIT_GAL(&sSetVipBRTH); + sSetVipBRTH.dwSubfunction = GALFN_SETVIPBRTH; + sSetVipBRTH.enable = enable; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVipBRTH)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vip_bus_request_threshold_high + * + * Description: This function gets the VIP FIFO bus request threshold. + * + * parameters: + * enable: Enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vip_bus_request_threshold_high(int *enable) +{ + GAL_VIPBUS_RTH sGetVipBRTH; + + INIT_GAL(&sGetVipBRTH); + sGetVipBRTH.dwSubfunction = GALFN_GETVIPBRTH; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVipBRTH)) { + return 0; + } else { + + *enable = sGetVipBRTH.enable; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vip_last_line + * + * Description: This function sets the maximum number of lines captured + * in each field. + * + * parameters: + * last_line: Maximum number of lines captured in each field. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vip_last_line(int last_line) +{ + GAL_VIPLASTLINE sSetViplastline; + + INIT_GAL(&sSetViplastline); + sSetViplastline.dwSubfunction = GALFN_SETVIPLASTLINE; + sSetViplastline.last_line = last_line; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetViplastline)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vip_line + * + * Description: This function gets the number of the current video line being + * recieved by the VIP interface. + * + * parameters: + * vip_line: Number of the current video line. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vip_line(int *vip_line) +{ + GAL_VIPLINE sGetVipline; + + INIT_GAL(&sGetVipline); + sGetVipline.dwSubfunction = GALFN_GETVIPLINE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVipline)) { + return 0; + } else { + *vip_line = sGetVipline.status; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_test_vip_odd_field + * + * Description: This function tests the VIP odd field. + * + * parameters: + * status: Status of the odd field. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_test_vip_odd_field(int *status) +{ + GAL_TESTVIPODDFIELD sTestVipoddfield; + + INIT_GAL(&sTestVipoddfield); + sTestVipoddfield.dwSubfunction = GALFN_TESTVIPODDFIELD; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sTestVipoddfield)) { + return 0; + } else { + *status = sTestVipoddfield.status; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_test_vip_bases_updated + * + * Description: This function tests the VIP bases updated. + * + * parameters: + * status: Status of the VIP bases updated. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_test_vip_bases_updated(int *status) +{ + GAL_TESTVIPBASESUPDATED sTestVipbasesupdated; + + INIT_GAL(&sTestVipbasesupdated); + sTestVipbasesupdated.dwSubfunction = GALFN_TESTVIPBASESUPDATED; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sTestVipbasesupdated)) { + return 0; + } else { + *status = sTestVipbasesupdated.status; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_test_vip_fifo_overflow + * + * Description: This function tests the VIP FIFO overflow. + * + * parameters: + * status: Status of the VIP FIFO overflow. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_test_vip_fifo_overflow(int *status) +{ + GAL_TESTVIPOVERFLOW sTestVipoverflow; + + INIT_GAL(&sTestVipoverflow); + sTestVipoverflow.dwSubfunction = GALFN_TESTVIPFIFOOVERFLOW; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sTestVipoverflow)) { + return 0; + } else { + *status = sTestVipoverflow.status; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_enable + * + * Description: This function enable/disables the VBI data capture. + * + * parameters: + * enable: VBI enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vbi_enable(int enable) +{ + GAL_VBIENABLE sSetVbienable; + + INIT_GAL(&sSetVbienable); + sSetVbienable.dwSubfunction = GALFN_SETVBIENABLE; + sSetVbienable.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbienable)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vbi_enable + * + * Description: This function gets the enable state of the VBI data capture. + * + * parameters: + * enable: VBI enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vbi_enable(int *enable) +{ + GAL_VBIENABLE sGetVbienable; + + INIT_GAL(&sGetVbienable); + sGetVbienable.dwSubfunction = GALFN_GETVBIENABLE; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbienable)) { + return 0; + } else { + + *enable = sGetVbienable.enable; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_base + * + * Description: This function sets the VBI base addresses. + * + * parameters: + * even: Even base address. + * odd: Odd base address. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vbi_base(unsigned long even, unsigned long odd) +{ + GAL_VBIBASE sSetVbiBase; + + INIT_GAL(&sSetVbiBase); + sSetVbiBase.dwSubfunction = GALFN_SETVBIBASE; + sSetVbiBase.even = even; + sSetVbiBase.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbiBase)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vbi_base + * + * Description: This function gets the VBI base address. + * + * parameters: + * address: VBI base address. + * odd: Odd base address. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vbi_base(unsigned long *address, int odd) +{ + GAL_VBIBASE sGetVbiBase; + + INIT_GAL(&sGetVbiBase); + sGetVbiBase.dwSubfunction = GALFN_GETVBIBASE; + sGetVbiBase.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbiBase)) { + return 0; + } else { + *address = sGetVbiBase.address; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_pitch + * + * Description: This function sets the number of bytes between scanlines for + * VBI capture. + * + * parameters: + * pitch: VBI pitch. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vbi_pitch(unsigned long pitch) +{ + GAL_VBIPITCH sSetVbiPitch; + + INIT_GAL(&sSetVbiPitch); + sSetVbiPitch.dwSubfunction = GALFN_SETVBIPITCH; + sSetVbiPitch.pitch = pitch; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbiPitch)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vbi_pitch + * + * Description: This function gets the number of bytes between scanlines for + * VBI capture. + * + * parameters: + * pitch: VBI pitch. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vbi_pitch(unsigned long *pitch) +{ + GAL_VBIPITCH sGetVbiPitch; + + INIT_GAL(&sGetVbiPitch); + sGetVbiPitch.dwSubfunction = GALFN_GETVBIPITCH; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbiPitch)) { + return 0; + } else { + *pitch = sGetVbiPitch.pitch; + return 1; + + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_mode + * + * Description: This function sets the VBI data types captured to memory. + * + * parameters: + * mode: VBI mode. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vbi_mode(int mode) +{ + GAL_VBIMODE sSetVbiMode; + + INIT_GAL(&sSetVbiMode); + sSetVbiMode.dwSubfunction = GALFN_SETVBIMODE; + sSetVbiMode.mode = mode; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbiMode)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vbi_mode + * + * Description: This function gets the VBI data types captured to memory. + * + * parameters: + * mode: VBI mode. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vbi_mode(int *mode) +{ + GAL_VBIMODE sGetVbiMode; + + INIT_GAL(&sGetVbiMode); + sGetVbiMode.dwSubfunction = GALFN_GETVBIMODE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbiMode)) { + return 0; + } else { + + *mode = sGetVbiMode.mode; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_direct + * + * Description: This function sets the VBI lines to be passed to the + * Direct VIP. + * + * parameters: + * even_lines: VBI even lines. + * odd_lines: VBI odd lines. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines) +{ + GAL_SETVBIDIRECT sSetVbidirect; + + INIT_GAL(&sSetVbidirect); + sSetVbidirect.dwSubfunction = GALFN_SETVBIDIRECT; + sSetVbidirect.even_lines = even_lines; + sSetVbidirect.odd_lines = odd_lines; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbidirect)) { + return 0; + } else { + return 1; + } +} +BOOLEAN +Gal2_set_destination_stride(unsigned short stride) +{ + GAL_STRIDE sSetStride; + + INIT_GAL(&sSetStride); + sSetStride.dwSubfunction = GALFN_SETDESTINATIONSTRIDE; + + sSetStride.stride = stride; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetStride)) + return 0; + else + return 1; +} + +BOOLEAN +Gal2_set_pattern_origin(int x, int y) +{ + GAL_PATTERNORIGIN sSetPatOrigin; + + INIT_GAL(&sSetPatOrigin); + sSetPatOrigin.dwSubfunction = GALFN_SETPATTERNORIGIN; + + sSetPatOrigin.x = x; + sSetPatOrigin.y = y; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetPatOrigin)) + return 0; + else + return 1; +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_direct + * + * Description: This function gets the VBI lines to be passed to the + * Direct VIP. + * + * parameters: + * odd: VBI odd lines. + * direct_lines: VBI direct lines. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vbi_direct(int odd, unsigned long *direct_lines) +{ + GAL_GETVBIDIRECT sGetVbidirect; + + INIT_GAL(&sGetVbidirect); + sGetVbidirect.dwSubfunction = GALFN_GETVBIDIRECT; + sGetVbidirect.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbidirect)) { + return 0; + } else { + *direct_lines = sGetVbidirect.direct_lines; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_interrupt + * + * Description: This function enable/disables the VBI field interrupt. + * + * parameters: + * enable: Value to enable/disable VBI interrupt. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vbi_interrupt(int enable) +{ + GAL_VBIINTERRUPT sSetVbiinterrupt; + + INIT_GAL(&sSetVbiinterrupt); + sSetVbiinterrupt.dwSubfunction = GALFN_SETVBIINTERRUPT; + sSetVbiinterrupt.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbiinterrupt)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vbi_interrupt + * + * Description: This function gets the VBI field interrupt. + * + * parameters: + * enable: Value of enable/disable VBI interrupt. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vbi_interrupt(int *enable) +{ + GAL_VBIINTERRUPT sGetVbiinterrupt; + + INIT_GAL(&sGetVbiinterrupt); + sGetVbiinterrupt.dwSubfunction = GALFN_GETVBIINTERRUPT; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbiinterrupt)) { + return 0; + } else { + *enable = sGetVbiinterrupt.enable; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_source_stride + * + * Description: This function sets the stride to be used in successive screen + * to screen BLTs. + * + * parameters: + * enable: Value of enable/disable VBI interrupt. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_set_source_stride(unsigned short stride) +{ + GAL_STRIDE sSetsourcestride; + + INIT_GAL(&sSetsourcestride); + sSetsourcestride.dwSubfunction = GALFN_SETSOURCESTRIDE; + + sSetsourcestride.stride = stride; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetsourcestride)) { + return 0; + } else { + + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_source_transparency + * + * Description: This function sets the source transparency color and + * mask to be used in future rendering routines. + * to screen BLTs. + * + * parameters: + * color: Source color. + * mask: Source mask. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_set_source_transparency(unsigned long color, unsigned long mask) +{ + GAL_SOURCETRANSPARENCY sSetsourcetransparency; + + INIT_GAL(&sSetsourcetransparency); + sSetsourcetransparency.dwSubfunction = GALFN_SETSOURCETRANSPARENCY; + + sSetsourcetransparency.color = color; + sSetsourcetransparency.mask = mask; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetsourcetransparency)) { + return 0; + } else { + + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_alpha_mode + * + * Description: This function sets the alpha blending mode. + * parameters: + * mode: Alpha blending mode. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_set_alpha_mode(int mode) +{ + GAL_GFX2ALPHAMODE sSetalphamode; + + INIT_GAL(&sSetalphamode); + sSetalphamode.dwSubfunction = GALFN_GFX2SETALPHAMODE; + + sSetalphamode.mode = mode; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetalphamode)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_gfx2_set_alpha_value + * + * Description: This function sets the alpha value to be used with certain + * alpha blending modes. + * parameters: + * value: Alpha blending value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_set_alpha_value(unsigned char value) +{ + GAL_GFX2ALPHAVALUE sSetalphavalue; + + INIT_GAL(&sSetalphavalue); + sSetalphavalue.dwSubfunction = GALFN_GFX2SETALPHAVALUE; + + sSetalphavalue.value = value; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetalphavalue)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_gfx2_pattern_fill + * + * Description: This function used to fill the pattern of GX2. + * It allows the arbitary destination stride. The rendering + * position is also specified as an offset instead of (x,y) + * position. + * parameters: + * dstoffset: Rendering offset. + * width: Width of the pattern. + * height: Height of the pattern. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_gfx2_pattern_fill(unsigned long dstoffset, unsigned short width, + unsigned short height) +{ + GAL_GFX2PATTERNFILL sPatternfill; + + INIT_GAL(&sPatternfill); + sPatternfill.dwSubfunction = GALFN_GFX2PATTERNFILL; + + sPatternfill.dstoffset = dstoffset; + sPatternfill.width = width; + sPatternfill.height = height; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sPatternfill)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_gfx2_screen_to_screen_blt + * + * Description: This function used for screen to screen BLTs of GX2. + * It allows the arbitary source and destination strides and + * alpha blending. + * parameters: + * srcoffset: Source Rendering offset. + * dstoffset: Destination Rendering offset. + * width: Width of the screen. + * height: Height of the screen. + * flags: Flags of the screen to screen BLT. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_screen_to_screen_blt(unsigned long srcoffset, + unsigned long dstoffset, unsigned short width, + unsigned short height, int flags) +{ + GAL_GFX2SCREENTOSCREENBLT sScreentoScreenblt; + + INIT_GAL(&sScreentoScreenblt); + sScreentoScreenblt.dwSubfunction = GALFN_GFX2SCREENTOSCREENBLT; + + sScreentoScreenblt.srcoffset = srcoffset; + sScreentoScreenblt.dstoffset = dstoffset; + sScreentoScreenblt.width = width; + sScreentoScreenblt.height = height; + sScreentoScreenblt.flags = flags; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sScreentoScreenblt)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal2_mono_expand_blt + * + * Description: This function used to expand monochrome data stored in + * graphics memory for screen to screen BLTs. + * parameters: + * srcbase: Source Rendering base address. + * srcx: Source X offset. + * srcy: Source Y offset. + * dstoffset: Destination Rendering offset. + * width: Width of the screen. + * height: Height of the screen. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_mono_expand_blt(unsigned long srcbase, unsigned short srcx, + unsigned short srcy, unsigned long dstoffset, + unsigned short width, unsigned short height, + int byte_packed) +{ + GAL_GFX2MONOEXPANDBLT sMonoexpandblt; + + INIT_GAL(&sMonoexpandblt); + sMonoexpandblt.dwSubfunction = GALFN_GFX2MONOEXPANDBLT; + sMonoexpandblt.srcbase = srcbase; + sMonoexpandblt.srcx = srcx; + sMonoexpandblt.srcy = srcy; + sMonoexpandblt.dstoffset = dstoffset; + sMonoexpandblt.width = width; + sMonoexpandblt.height = height; + sMonoexpandblt.byte_packed = byte_packed; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sMonoexpandblt)) { + return 0; + } else { + return 1; + + } +} + +/*-------------------------------------------------------------------------- + * Gal2_color_bitmap_to_screen_blt + * + * Description: This function used for color bmp to screen BLTs. + * parameters: + * srcx: Source X offset. + * srcy: Source Y offset. + * dstoffset: Destination Rendering offset. + * width: Width of the screen. + * height: Height of the screen. + * *data: Color bmp data. + * pitch: Pitch of the dispaly mode. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_color_bitmap_to_screen_blt(unsigned short srcx, + unsigned short srcy, + unsigned long dstoffset, + unsigned short width, + unsigned short height, + unsigned char *data, unsigned short pitch) +{ + GAL_GFX2COLORBMPTOSCRBLT sColorbmptoscrblt; + + INIT_GAL(&sColorbmptoscrblt); + sColorbmptoscrblt.dwSubfunction = GALFN_GFX2COLORBMPTOSCRBLT; + sColorbmptoscrblt.srcx = srcx; + sColorbmptoscrblt.srcy = srcy; + sColorbmptoscrblt.dstoffset = dstoffset; + sColorbmptoscrblt.width = width; + sColorbmptoscrblt.height = height; + sColorbmptoscrblt.data = *data; + sColorbmptoscrblt.pitch = pitch; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sColorbmptoscrblt)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal2_mono_bitmap_to_screen_blt + * + * Description: This function used for mono bmp to screen BLTs. + * parameters: + * srcx: Source X offset. + * srcy: Source Y offset. + * dstoffset: Destination Rendering offset. + * width: Width of the screen. + * height: Height of the screen. + * *data: mono bmp data. + * pitch: Pitch of the display mode. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_mono_bitmap_to_screen_blt(unsigned short srcx, + unsigned short srcy, + unsigned long dstoffset, + unsigned short width, + unsigned short height, + unsigned char *data, unsigned short pitch) +{ + GAL_GFX2MONOBMPTOSCRBLT sMonobmptoscrblt; + + INIT_GAL(&sMonobmptoscrblt); + sMonobmptoscrblt.dwSubfunction = GALFN_GFX2MONOBMPTOSCRBLT; + sMonobmptoscrblt.srcx = srcx; + sMonobmptoscrblt.srcy = srcy; + sMonobmptoscrblt.dstoffset = dstoffset; + sMonobmptoscrblt.width = width; + sMonobmptoscrblt.height = height; + sMonobmptoscrblt.data = *data; + sMonobmptoscrblt.pitch = pitch; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sMonobmptoscrblt)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal2_bresenham_line + * + * Description: This function used to draw bresenham line. It allows the + * arbitary destination stride. + * parameters: + * dstoffset: Destination offset. + * length: Length of the line. + * initerr: Intial error. + * axialerr: + * diagerr: + * flags: + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_bresenham_line(unsigned long dstoffset, unsigned short length, + unsigned short initerr, unsigned short axialerr, + unsigned short diagerr, unsigned short flags) +{ + GAL_GFX2BRESENHAMLINE sBresenhamline; + + INIT_GAL(&sBresenhamline); + sBresenhamline.dwSubfunction = GALFN_GFX2BRESENHAMLINE; + sBresenhamline.dstoffset = dstoffset; + sBresenhamline.length = length; + sBresenhamline.initerr = initerr; + sBresenhamline.axialerr = axialerr; + sBresenhamline.diagerr = diagerr; + sBresenhamline.flags = flags; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sBresenhamline)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal2_sync_to_vblank + * + * Description: This function sets the a flag to synchronize the next + * rendering routine to VBLANK. + * parameters: none. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal2_sync_to_vblank(void) +{ + GAL_GFX2SYNCTOVBLANK sSynctovblank; + + INIT_GAL(&sSynctovblank); + sSynctovblank.dwSubfunction = GALFN_GFX2SYNCTOVBLANK; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSynctovblank)) { + return 0; + } else { + return 1; + } +} + +/* Video routines */ + +/*-------------------------------------------------------------------------- + * Gal_set_video_yuv_pitch + * + * Description: This function sets the Video YUV pitch. + * + * parameters: + * y_pitch: Y pitch. + * uv_pitch: UV pitch. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_yuv_pitch(unsigned long y_pitch, unsigned long uv_pitch) +{ + GAL_VIDEOYUVPITCH sSetVideoyuvpitch; + + INIT_GAL(&sSetVideoyuvpitch); + sSetVideoyuvpitch.dwSubfunction = GALFN_SETVIDEOYUVPITCH; + sSetVideoyuvpitch.y_pitch = y_pitch; + sSetVideoyuvpitch.uv_pitch = uv_pitch; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideoyuvpitch)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_video_yuv_pitch + * + * Description: This function gets the Video YUV pitch. + * + * parameters: + * y_pitch: Y pitch. + * uv_pitch: UV pitch. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_video_yuv_pitch(unsigned long *y_pitch, unsigned long *uv_pitch) +{ + GAL_VIDEOYUVPITCH sGetVideoyuvpitch; + + INIT_GAL(&sGetVideoyuvpitch); + sGetVideoyuvpitch.dwSubfunction = GALFN_GETVIDEOYUVPITCH; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVideoyuvpitch)) { + return 0; + } else { + *y_pitch = sGetVideoyuvpitch.y_pitch; + *uv_pitch = sGetVideoyuvpitch.uv_pitch; + + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_yuv_offsets + * + * Description: This function sets the Video YUV offsets. + * + * parameters: + * y_offset: Y offset. + * u_offset: U offset. + * v_offset: V offset. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_video_yuv_offsets(unsigned long y_offset, unsigned long u_offset, + unsigned long v_offset) +{ + GAL_VIDEOYUVOFFSETS sSetVideoyuvoffsets; + + INIT_GAL(&sSetVideoyuvoffsets); + sSetVideoyuvoffsets.dwSubfunction = GALFN_SETVIDEOYUVOFFSETS; + sSetVideoyuvoffsets.dwYoffset = y_offset; + sSetVideoyuvoffsets.dwUoffset = u_offset; + sSetVideoyuvoffsets.dwVoffset = v_offset; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideoyuvoffsets)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_video_yuv_offsets + * + * Description: This function gets the Video YUV offsets. + * + * parameters: + * y_offset: Y offset. + * u_offset: U offset. + * v_offset: V offset. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ BOOLEAN +Gal_get_video_yuv_offsets(unsigned long *y_offset, + unsigned long *u_offset, unsigned long *v_offset) +{ + GAL_VIDEOYUVOFFSETS sGetVideoyuvoffsets; + + INIT_GAL(&sGetVideoyuvoffsets); + sGetVideoyuvoffsets.dwSubfunction = GALFN_GETVIDEOYUVOFFSETS; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVideoyuvoffsets)) { + return 0; + } else { + *y_offset = sGetVideoyuvoffsets.dwYoffset; + *u_offset = sGetVideoyuvoffsets.dwUoffset; + *v_offset = sGetVideoyuvoffsets.dwVoffset; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_left_crop + * + * Description: This function sets the number of pixels which will be cropped + * from the beginning of each video line. + * + * parameters: + * x: + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ BOOLEAN +Gal_set_video_left_crop(unsigned short x) +{ + GAL_VIDEOLEFTCROP sSetVideoleftcrop;; + + INIT_GAL(&sSetVideoleftcrop); + sSetVideoleftcrop.dwSubfunction = GALFN_SETVIDEOLEFTCROP; + sSetVideoleftcrop.x = x; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideoleftcrop)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_video_vertical_downscale + * + * Description: This function sets the vertical downscale factor for the video + * overlay window. + * + * parameters: + * srch: Height of the source. + * dsth: Height of the destination. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ BOOLEAN +Gal_set_video_vertical_downscale(unsigned short srch, unsigned short dsth) +{ + GAL_VIDEOVERTICALDOWNSCALE sSetVideoverticaldownscale; + + INIT_GAL(&sSetVideoverticaldownscale); + sSetVideoverticaldownscale.dwSubfunction = GALFN_SETVIDEOVERTICALDOWNSCALE; + sSetVideoverticaldownscale.srch = srch; + sSetVideoverticaldownscale.dsth = dsth; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVideoverticaldownscale)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_source + * + * Description: This function sets the VBI source. + * + * parameters: + * source: VBI Source type. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ BOOLEAN +Gal_set_vbi_source(VbiSourceType source) +{ + GAL_VBISOURCE sSetVbisource; + + INIT_GAL(&sSetVbisource); + sSetVbisource.dwSubfunction = GALFN_SETVBISOURCE; + sSetVbisource.source = source; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbisource)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vbi_source + * + * Description: This function gets the VBI source. + * + * parameters: + * source: VBI Source type. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_vbi_source(VbiSourceType * source) +{ + GAL_VBISOURCE sGetVbisource; + + INIT_GAL(&sGetVbisource); + sGetVbisource.dwSubfunction = GALFN_GETVBISOURCE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbisource)) { + return 0; + } else { + + *source = sGetVbisource.source; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_lines + * + * Description: This function sets the VBI lines. + * + * parameters: + * even: VBI even lines. + * odd: VBI odd lines. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vbi_lines(unsigned long even, unsigned long odd) +{ + GAL_VBILINES sSetVbilines; + + INIT_GAL(&sSetVbilines); + sSetVbilines.dwSubfunction = GALFN_SETVBILINES; + sSetVbilines.even = even; + sSetVbilines.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbilines)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vbi_lines + * + * Description: This function gets the VBI lines. + * + * parameters: + * lines: VBI lines. + * odd: VBI odd lines. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ BOOLEAN +Gal_get_vbi_lines(int odd, unsigned long *lines) +{ + GAL_VBILINES sGetVbilines; + + INIT_GAL(&sGetVbilines); + sGetVbilines.dwSubfunction = GALFN_GETVBILINES; + sGetVbilines.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbilines)) { + return 0; + } else { + *lines = sGetVbilines.lines; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_total + * + * Description: This function sets the total number of VBI bytes for each + * field. + * + * parameters: + * even: + * odd: + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_vbi_total(unsigned long even, unsigned long odd) +{ + GAL_VBITOTAL sSetVbitotal; + + INIT_GAL(&sSetVbitotal); + sSetVbitotal.dwSubfunction = GALFN_SETVBITOTAL; + sSetVbitotal.even = even; + sSetVbitotal.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVbitotal)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vbi_total + * + * Description: This function gets the total number of VBI bytes in the + * field. + * + * parameters: + * even: + * odd: + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ BOOLEAN +Gal_get_vbi_total(int odd, unsigned long *total) +{ + GAL_VBITOTAL sGetVbitotal; + + INIT_GAL(&sGetVbitotal); + sGetVbitotal.dwSubfunction = GALFN_GETVBITOTAL; + sGetVbitotal.odd = odd; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVbitotal)) { + return 0; + } else { + *total = sGetVbitotal.total; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_vertical_scaler_offset + * + * Description: This function sets the Video vertical scaler offset. + * + * parameters: + * offset: Vertical Scaler offset. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ BOOLEAN +Gal_set_vertical_scaler_offset(char offset) +{ + GAL_VSCALEROFFSET sSetVscaleroffset; + + INIT_GAL(&sSetVscaleroffset); + sSetVscaleroffset.dwSubfunction = GALFN_SETVSCALEROFFSET; + sSetVscaleroffset.offset = offset; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetVscaleroffset)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_vertical_scaler_offset + * + * Description: This function gets the Video vertical scaler offset. + * + * parameters: + * offset: Vertical Scaler offset. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ BOOLEAN +Gal_get_vertical_scaler_offset(char *offset) +{ + GAL_VSCALEROFFSET sGetVscaleroffset; + + INIT_GAL(&sGetVscaleroffset); + sGetVscaleroffset.dwSubfunction = GALFN_GETVSCALEROFFSET; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetVscaleroffset)) { + return 0; + } else { + + *offset = sGetVscaleroffset.offset; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_video_interlaced + * + * Description: This function gets the video interlaced mode. + * parameters: + * interlaced: ptr to the interlaced status. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_video_interlaced(int *interlaced) +{ + GAL_GETVIDEOINTERLACED sGetvideointerlaced; + + INIT_GAL(&sGetvideointerlaced); + sGetvideointerlaced.dwSubfunction = GALFN_GETVIDEOINTERLACED; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetvideointerlaced)) { + return 0; + } else { + *interlaced = sGetvideointerlaced.interlaced; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_color_space_YUV + * + * Description: This function gets the video color space YUV. + * parameters: + * colorspace: ptr to the color space. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_color_space_YUV(int *colorspace) +{ + GAL_COLORSPACEYUV sGetcolorspaceyuv; + + INIT_GAL(&sGetcolorspaceyuv); + sGetcolorspaceyuv.dwSubfunction = GALFN_GETCOLORSPACEYUV; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetcolorspaceyuv)) { + return 0; + } else { + *colorspace = sGetcolorspaceyuv.colorspace; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_genlock_enable + * + * Description: This function gets the enable state of the genlock. + * parameters: + * enable: ptr to the enable state of the genlock. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_genlock_enable(int *enable) +{ + GAL_GENLOCKENABLE sGetgenlockenable; + + INIT_GAL(&sGetgenlockenable); + sGetgenlockenable.dwSubfunction = GALFN_GETGENLOCKENABLE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetgenlockenable)) { + return 0; + } else { + *enable = sGetgenlockenable.enable; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_genlock_enable + * + * Description: This function enable/disables and configure the genlock + * according to the parameters. + * parameters: + * enable: enable state of the genlock. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_genlock_enable(int enable) +{ + GAL_GENLOCKENABLE sSetgenlockenable; + + INIT_GAL(&sSetgenlockenable); + sSetgenlockenable.dwSubfunction = GALFN_SETGENLOCKENABLE; + + sSetgenlockenable.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetgenlockenable)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_genlock_delay + * + * Description: This function gets the genlock delay. + * parameters: + * delay: Ptr to the genlock delay. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_genlock_delay(unsigned long *delay) +{ + GAL_GENLOCKDELAY sGetgenlockdelay; + + INIT_GAL(&sGetgenlockdelay); + sGetgenlockdelay.dwSubfunction = GALFN_GETGENLOCKDELAY; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetgenlockdelay)) { + return 0; + } else { + *delay = sGetgenlockdelay.delay; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_genlock_delay + * + * Description: This function sets the genlock delay. + * parameters: + * delay: genlock delay. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_genlock_delay(unsigned long delay) +{ + GAL_GENLOCKDELAY sSetgenlockdelay; + + INIT_GAL(&sSetgenlockdelay); + sSetgenlockdelay.dwSubfunction = GALFN_SETGENLOCKDELAY; + + sSetgenlockdelay.delay = delay; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetgenlockdelay)) { + return 0; + } else { + return 1; + } +} + +BOOLEAN +Gal_set_top_line_in_odd(int enable) +{ + GAL_TOPLINEINODD sSettoplineinodd; + + INIT_GAL(&sSettoplineinodd); + sSettoplineinodd.dwSubfunction = GALFN_SETTOPLINEINODD; + + sSettoplineinodd.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSettoplineinodd)) { + return 0; + } else { + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_video_cursor. + * + * Description: This function gets configuration of the Video Hardware + * cursor. + * parameters: + * key: color key. + * mask: color mask. + *select_color2: selected for color2. + * color1: color1 value. + * color2: color2 value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_video_cursor(unsigned long *key, + unsigned long *mask, + unsigned short *select_color2, + unsigned long *color1, unsigned long *color2) +{ + GAL_VIDEOCURSOR sGetvideocursor; + + INIT_GAL(&sGetvideocursor); + sGetvideocursor.dwSubfunction = GALFN_GETVIDEOCURSOR; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetvideocursor)) { + return 0; + } else { + *key = sGetvideocursor.key; + *mask = sGetvideocursor.mask; + *select_color2 = sGetvideocursor.select_color2; + *color1 = sGetvideocursor.color1; + *color2 = sGetvideocursor.color2; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_read_crc. + * + * Description: This function reads the hardware CRC value, which is used for + * automated testing. + * parameters: + * crc: Holds the crc value. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_read_crc(unsigned long *crc) +{ + GAL_READCRC sReadcrc; + + INIT_GAL(&sReadcrc); + sReadcrc.dwSubfunction = GALFN_READCRC; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sReadcrc)) { + return 0; + } else { + *crc = sReadcrc.crc; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_read_window_crc. + * + * Description: This function reads the hardware CRC value for a subsection + * of the display. + * + * parameters: + * source: + * x: + * y: + * width: + * height: + * crc: + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_read_window_crc(int source, unsigned short x, unsigned short y, + unsigned short width, unsigned short height, + int crc32, unsigned long *crc) +{ + GAL_READWINDOWCRC sReadwindowcrc; + + INIT_GAL(&sReadwindowcrc); + sReadwindowcrc.dwSubfunction = GALFN_READWINDOWCRC; + sReadwindowcrc.source = source; + sReadwindowcrc.x = x; + sReadwindowcrc.y = y; + sReadwindowcrc.width = width; + sReadwindowcrc.height = height; + sReadwindowcrc.crc32 = crc32; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sReadwindowcrc)) { + return 0; + } else { + *crc = sReadwindowcrc.crc; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_get_macrovision_enable. + * + * Description: This function gets the enable state of the macrovision. + * + * parameters: + * enable: ptr holds the macrovision enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_get_macrovision_enable(int *enable) +{ + GAL_MACROVISIONENABLE sGetmacrovisionenable; + + INIT_GAL(&sGetmacrovisionenable); + sGetmacrovisionenable.dwSubfunction = GALFN_GETMACROVISIONENABLE; + + if (ioctl(ifbdev_handle, FBIOGAL_API, &sGetmacrovisionenable)) { + return 0; + } else { + *enable = sGetmacrovisionenable.enable; + return 1; + } +} + +/*-------------------------------------------------------------------------- + * Gal_set_macrovision_enable. + * + * Description: This function gets the enable state of the macrovision. + * + * parameters: + * enable: macrovision enable state. + * return: '1' was returned on success otherwise '0' was returned. + *------------------------------------------------------------------------*/ +BOOLEAN +Gal_set_macrovision_enable(int enable) +{ + GAL_MACROVISIONENABLE sSetmacrovisionenable; + + INIT_GAL(&sSetmacrovisionenable); + sSetmacrovisionenable.dwSubfunction = GALFN_SETMACROVISIONENABLE; + + sSetmacrovisionenable.enable = enable; + if (ioctl(ifbdev_handle, FBIOGAL_API, &sSetmacrovisionenable)) { + return 0; + } else { + return 1; + } +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_galstub.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_galstub.c new file mode 100644 index 000000000..6ed534f89 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_galstub.c @@ -0,0 +1,157 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_galstub.c,v 1.2 2003/01/14 09:34:31 alanh Exp $ */ +/* + * $Workfile: nsc_galstub.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file contains the file inclusions of the GAL + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Geode Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Geode Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Geode Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#if defined(STB_X) +/* all driver need this */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +/* pci stuff */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" +#include "asm/page.h" /* #define for PAGE_* */ + +#define makedev(major, minor) ((((unsigned int) (major)) << 8) \ + | ((unsigned int) (minor))) + +#include "nsc_galfns.c" +#endif /* STB_X */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_accel.c new file mode 100644 index 000000000..dccfe395b --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_accel.c @@ -0,0 +1,1788 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_accel.c,v 1.5 2003/02/11 13:36:41 alanh Exp $ */ +/* + * $Workfile: nsc_gx1_accel.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file is consists of main Xfree + * acceleration supported routines like solid fill used + * here. + * Project: Geode Xfree Frame buffer device driver. + * + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* + * Fixes by + * Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +/* Xfree86 header files */ +#include "vgaHW.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xaalocal.h" +#include "xf86fbman.h" +#include "miline.h" +#include "xf86_libc.h" +#include "xaarop.h" +#include "nsc.h" + +#define SCR2SCREXP 0 + +/* STATIC VARIABLES FOR THIS FILE + * Used to maintain state between setup and rendering calls. + */ + +static int GeodeTransparent; +static int GeodeTransColor; +static int Geodedstx; +static int Geodedsty; +static int Geodesrcx; +static int Geodesrcy; +static int Geodewidth; +static int Geodeheight; +static int Geodebpp; +static int GeodeCounter; + +#if !defined(STB_X) +static unsigned int GeodeROP = 0; +static unsigned short Geode_blt_mode = 0; +static unsigned short Geode_vector_mode = 0; +static unsigned short Geode_buffer_width = 0; +#endif +static unsigned int gu1_bpp = 0; +static unsigned int gu1_xshift = 1; +static unsigned int gu1_yshift = 1; +static unsigned short GeodebufferWidthPixels; +static unsigned int ImgBufOffset; +static unsigned short Geodebb0Base; +static unsigned short Geodebb1Base; +static XAAInfoRecPtr localRecPtr; + +#define CALC_FBOFFSET(_SrcX, _SrcY) \ + (((unsigned int) (_SrcY) << gu1_yshift) |\ + (((unsigned int) (_SrcX)) << gu1_xshift)) + +#define GFX_WAIT_BUSY while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { ; } +#define GFX_WAIT_PENDING while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { ; } + +#define BB0_BASE_3K 0x400 +#define BB1_BASE_3K 0x930 + +Bool GX1AccelInit(ScreenPtr pScreen); +void GX1AccelSync(ScrnInfoPtr pScreenInfo); +void GX1SetupForFillRectSolid(ScrnInfoPtr pScreenInfo, int color, int rop, + unsigned int planemask); +void GX1SubsequentFillRectSolid(ScrnInfoPtr pScreenInfo, int x, int y, + int w, int h); +void GX1SetupFor8x8PatternColorExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, + int rop, unsigned int planemask, + int trans_color); +void GX1Subsequent8x8PatternColorExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int x, + int y, int w, int h); +void GX1SetupFor8x8PatternMonoExpand(ScrnInfoPtr pScreenInfo, int patternx, + int patterny, int fg, int bg, int rop, + unsigned int planemask); +void GX1Subsequent8x8PatternMonoExpand(ScrnInfoPtr pScreenInfo, int patternx, + int patterny, int x, int y, int w, + int h); +void GX1SetupForScreenToScreenCopy(ScrnInfoPtr pScreenInfo, int xdir, + int ydir, int rop, unsigned int planemask, + int transparency_color); +void GX1SubsequentScreenToScreenCopy(ScrnInfoPtr pScreenInfo, int x1, int y1, + int x2, int y2, int w, int h); +void GX1SetupForSolidLine(ScrnInfoPtr pScreenInfo, int color, int rop, + unsigned int planemask); +void GX1SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern); +void GX1SubsequentBresenhamLine(ScrnInfoPtr pScreenInfo, int x1, int y1, + int absmaj, int absmin, int err, int len, + int octant); +void GX1SubsequentSolidTwoPointLine(ScrnInfoPtr pScreenInfo, int x0, int y0, + int x1, int y1, int flags); +void GX1SubsequentHorVertLine(ScrnInfoPtr pScreenInfo, int x, int y, int len, + int dir); + +void GX1SetupForScanlineImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, + int depth); + +void GX1SubsequentScanlineImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft); + +void GX1SubsequentImageWriteScanline(ScrnInfoPtr pScreenInfo, int bufno); +void GX1FillCacheBltRects(ScrnInfoPtr pScrn, int rop, unsigned int planemask, + int nBox, BoxPtr pBox, int xorg, int yorg, + XAACacheInfoPtr pCache); +void OPTGX1SetupForFillRectSolid(ScrnInfoPtr pScreenInfo, int color, int rop, + unsigned int planemask); +void OPTGX1SubsequentFillRectSolid(ScrnInfoPtr pScreenInfo, int x, int y, + int w, int h); +void OPTGX1SetupForScreenToScreenCopy(ScrnInfoPtr pScreenInfo, int xdir, + int ydir, int rop, + unsigned int planemask, + int transparency_color); +void OPTGX1SubsequentScreenToScreenCopy(ScrnInfoPtr pScreenInfo, int x1, + int y1, int x2, int y2, int w, int h); +void OPTGX1SetupForSolidLine(ScrnInfoPtr pScreenInfo, int color, int rop, + unsigned int planemask); +void OPTGX1SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern); +void OPTGX1SubsequentBresenhamLine(ScrnInfoPtr pScreenInfo, int x1, int y1, + int absmaj, int absmin, int err, int len, + int octant); +void OPTGX1SubsequentSolidTwoPointLine(ScrnInfoPtr pScreenInfo, + int x0, int y0, int x1, int y1, + int flags); +void OPTGX1SubsequentHorVertLine(ScrnInfoPtr pScreenInfo, int x, int y, + int len, int dir); + +void OPTGX1SetupForScanlineImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, + int depth); + +void OPTGX1SubsequentScanlineImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft); + +void OPTGX1SubsequentImageWriteScanline(ScrnInfoPtr pScreenInfo, int bufno); + +/*---------------------------------------------------------------------------- + * GX1AccelSync. + * + * Description :This function is called to syncronize with the graphics + * engine and it waits the graphic engine is idle.This is + * required before allowing direct access to the + * framebuffer. + * Parameters. + * pScreenInfo:Screeen info pointer structure. + * + * Returns :none + * + * Comments :This function is called on geode_video routines. +*---------------------------------------------------------------------------- +*/ +void +GX1AccelSync(ScrnInfoPtr pScreenInfo) +{ + GFX(wait_until_idle()); +} + +/*---------------------------------------------------------------------------- + * GX1SetupForFillRectSolid. + * + * Description :This routine is called to setup the solid pattern + * color for future rectangular fills or vectors. + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * color :Specifies the color to be filled up in defined area. + * rop :Specifies the raster operation value. + * planemask :Specifies the masking value based rop srcdata. + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX1SetupForFillRectSolid(ScrnInfoPtr pScreenInfo, + int color, int rop, unsigned int planemask) +{ + GFX(set_solid_pattern((unsigned long)color)); + + /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ + if (planemask == 0xFFFFFFFF) { + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAAPatternROP[rop])); + } else { + /* SELECT ROP THAT USES SOURCE DATA FOR PLANEMASK */ + GFX(set_solid_source((unsigned long)planemask)); + GFX(set_raster_operation(XAAPatternROP_PM[rop])); + } +} + + /*---------------------------------------------------------------------------- + * GX1SubsequentFillRectSolid. + * + * Description :This routine is used to fill the rectangle of previously + * specified solid pattern. + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * x and y :Specifies the x and y co-ordinatesarea. + * w and h :Specifies width and height respectively. + * + * Returns :none + * + * Comments :desired pattern can be set before this function by + * gfx_set_solid_pattern. + * Sample application uses: + * - Window backgrounds. + * - x11perf: rectangle tests (-rect500). + * - x11perf: fill trapezoid tests (-trap100). + * - x11perf: horizontal line segments (-hseg500). + *---------------------------------------------------------------------------- +*/ +void +GX1SubsequentFillRectSolid(ScrnInfoPtr pScreenInfo, int x, int y, int w, + int h) +{ + /* SIMPLY PASS THE PARAMETERS TO THE DURANGO ROUTINE */ + GeodePtr pGeode; + + pGeode = GEODEPTR(pScreenInfo); + + if (pGeode->TV_Overscan_On) { + x += pGeode->TVOx; + y += pGeode->TVOy; + } + + GFX(pattern_fill((unsigned short)x, (unsigned short)y, + (unsigned short)w, (unsigned short)h)); +} + +/*---------------------------------------------------------------------------- + * GX1SetupFor8x8PatternColorExpand + * + * Description :This routine is called to fill the color pattern of + * 8x8. + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * patternx :This is set from on rop data. + * patterny :This is set based on rop data. + * planemask :Specifies the value of masking from rop data + * trans_color :to be added. + * Returns :none. + * + * Comments :none. + * +*---------------------------------------------------------------------------- +*/ + +void +GX1SetupFor8x8PatternColorExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, + int rop, unsigned int planemask, + int trans_color) +{ + /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ + if (planemask == 0xFFFFFFFF) { + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAAPatternROP[rop])); + } else { + /* SELECT ROP THAT USES SOURCE DATA FOR PLANEMASK */ + GFX(set_solid_source((unsigned int)planemask)); + GFX(set_raster_operation(XAAPatternROP_PM[rop])); + } +} + +/*---------------------------------------------------------------------------- + * GX1Subsequent8x8PatternColorExpand + * + * Description :This routine is called to fill a rectangle with the + * color pattern of previously loaded pattern. + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * patternx :This is set from on rop data. + * patterny :This is set based on rop data. + * x :x -coordinates of the destination rectangle + * y :y-co-ordinates of the destination rectangle + * w :Specifies width of the rectangle + * h :Height of the window of the rectangle + * + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses: + * - Patterned desktops + * - x11perf: stippled rectangle tests (-srect500). + * - x11perf: opaque stippled rectangle tests (-osrect500). +*---------------------------------------------------------------------------- +*/ +void +GX1Subsequent8x8PatternColorExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int x, int y, + int w, int h) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + DEBUGMSG(1, (0, 0, "8x8color %d %d %dx%d\n", x, y, w, h)); + if (pGeode->TV_Overscan_On) { + x += pGeode->TVOx; + y += pGeode->TVOy; + } + /* SIMPLY PASS THE PARAMETERS TO THE DURANGO ROUTINE */ + /* Ignores specified pattern. */ + GFX(color_pattern_fill((unsigned short)x, (unsigned short)y, + (unsigned short)w, (unsigned short)h, + ((unsigned long *)((pGeode->FBBase + + (patterny << gu1_yshift)) + + patternx)))); +} + +/*---------------------------------------------------------------------------- + * GX1SetupFor8x8PatternMonoExpand + * + * Description :This routine is called to fill the monochrome pattern of + * 8x8. + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * patternx:This is set from on rop data. + * patterny:This is set based on rop data. + * fg :Specifies the foreground color + * bg :Specifies the background color + * planemask :Specifies the value of masking from rop data + + * Returns :none. + * + * Comments :none. + * +*---------------------------------------------------------------------------- +*/ +void +GX1SetupFor8x8PatternMonoExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int fg, + int bg, int rop, unsigned int planemask) +{ + int trans = (bg == -1); + + /* LOAD PATTERN COLORS AND DATA */ + GFX(set_mono_pattern((unsigned int)bg, (unsigned int)fg, + (unsigned int)patternx, (unsigned int)patterny, + trans)); + + GFX(set_mono_source((unsigned int)bg, (unsigned int)fg, trans)); + + /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ + if (planemask == 0xFFFFFFFF) { + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAAPatternROP[rop])); + } else { + /* SELECT ROP THAT USES SOURCE DATA FOR PLANEMASK */ + GFX(set_solid_source((unsigned int)planemask)); + GFX(set_raster_operation(XAAPatternROP_PM[rop])); + } +} + +/*---------------------------------------------------------------------------- + * GX1Subsequent8x8PatternMonoExpand + * + * Description :This routine is called to fill a ractanglethe + * monochrome pattern of previusly loaded pattern. + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * patternx :This is set from on rop data. + * patterny :This is set based on rop data. + * fg :Specifies the foreground color + * bg :Specifies the background color + * planemask :Specifies the value of masking from rop data + + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses: + * - Patterned desktops + * - x11perf: stippled rectangle tests (-srect500). + * - x11perf: opaque stippled rectangle tests (-osrect500). +*---------------------------------------------------------------------------- +*/ +void +GX1Subsequent8x8PatternMonoExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int x, int y, + int w, int h) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + if (pGeode->TV_Overscan_On) { + x += pGeode->TVOx; + y += pGeode->TVOy; + } + + /* SIMPLY PASS THE PARAMETERS TO THE DURANGO ROUTINE */ + /* Ignores specified pattern. */ + GFX(pattern_fill((unsigned short)x, (unsigned short)y, + (unsigned short)w, (unsigned short)h)); +} + +/*---------------------------------------------------------------------------- + * GX1SetupForScreenToScreenCopy + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * xdir :This is set based on rop data. + * ydir :This is set based on rop data. + * rop :sets the raster operation + * transparency:tobeadded + * planemask :Specifies the value of masking from rop data + + * Returns :none + * + * Comments :The patterns specified is ignored inside the function +*---------------------------------------------------------------------------- +*/ +void +GX1SetupForScreenToScreenCopy(ScrnInfoPtr pScreenInfo, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + GFX(set_solid_pattern(planemask)); + /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */ + GFX(set_raster_operation(XAACopyROP[rop])); + /* SAVE TRANSPARENCY FLAG */ + GeodeTransparent = (transparency_color == -1) ? 0 : 1; + GeodeTransColor = transparency_color; + +} + +/*---------------------------------------------------------------------------- + * GX1SubsquentScreenToScreenCopy + * + * Description :This function is called to perform a screen to screen + * BLT using the previously specified planemask,raster + * operation and * transparency flag + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * x1 :x -coordinates of the source window + * y1 :y-co-ordinates of the source window + * x2 :x -coordinates of the destination window + * y2 :y-co-ordinates of the destination window + * w :Specifies width of the window to be copied + * h :Height of the window to be copied. + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses (non-transparent): + * - Moving windows. + * - x11perf: scroll tests (-scroll500). + * - x11perf: copy from window to window (-copywinwin500). + * + * No application found using transparency. +*---------------------------------------------------------------------------- +*/ + +void +GX1SubsequentScreenToScreenCopy(ScrnInfoPtr pScreenInfo, + int x1, int y1, int x2, int y2, int w, int h) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + if (pGeode->TV_Overscan_On) { + if ((x1 < pScreenInfo->virtualX) && (y1 < pScreenInfo->virtualY)) { + x1 += pGeode->TVOx; + y1 += pGeode->TVOy; + } + x2 += pGeode->TVOx; + y2 += pGeode->TVOy; + } + + if (GeodeTransparent) { + /* CALL ROUTINE FOR TRANSPARENT SCREEN TO SCREEN BLT + * * Should only be called for the "copy" raster operation. + */ + GFX(screen_to_screen_xblt((unsigned short)x1, (unsigned short)y1, + (unsigned short)x2, (unsigned short)y2, + (unsigned short)w, (unsigned short)h, + GeodeTransColor)); + } else { + /* CALL ROUTINE FOR NORMAL SCREEN TO SCREEN BLT */ + GFX(screen_to_screen_blt((unsigned short)x1, (unsigned short)y1, + (unsigned short)x2, (unsigned short)y2, + (unsigned short)w, (unsigned short)h)); + } +} + +/*---------------------------------------------------------------------------- + * GX1SetupForScanlineImageWrite + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * rop :sets the raster operation + * transparency_color :transparency color key. + * planemask :Specifies the value of masking from rop data + * bpp :bits per pixel of the source pixmap + * depth :depth of the source pixmap. + * Returns :none + * + * Comments :none + * x11perf -putimage10 + * x11perf -putimage100 + * x11perf -putimage500 +*---------------------------------------------------------------------------- +*/ + +void +GX1SetupForScanlineImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth) +{ + GFX(set_solid_pattern((unsigned int)planemask)); + /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */ + GFX(set_raster_operation(XAACopyROP_PM[rop])); + /* SAVE TRANSPARENCY FLAG */ + GeodeTransparent = (transparency_color == -1) ? 0 : 1; + GeodeTransColor = transparency_color; + Geodebpp = bpp; +} + +/*---------------------------------------------------------------------------- + * GX1SubsequentScanlineImageWriteRect + * + * Description :This function is used to set up the x,y corordinates and width + * &height for future Bliting functionality. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x :destination x + * y :destination y + * w :Specifies the width of the rectangle to be copied + * h :Specifies the height of the rectangle to be copied + * + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +GX1SubsequentScanlineImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, int skipleft) +{ + + Geodedstx = x; + Geodedsty = y; + Geodewidth = w; + Geodeheight = h; + GeodeCounter = 0; +} + +/*---------------------------------------------------------------------------- + * GX1SubsquentImageWriteScanline + * + * Description :This function is called to + * BLT using the previously specified planemask,raster + * operation and transparency flag + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses (non-transparent): + * - Moving windows. + * - x11perf: scroll tests (-scroll500). + * - x11perf: copy from window to window (-copywinwin500). + * + * No application found using transparency. +*---------------------------------------------------------------------------- +*/ + +void +GX1SubsequentImageWriteScanline(ScrnInfoPtr pScreenInfo, int bufno) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + int blt_height = 0; + char blit = FALSE; + + GeodeCounter++; + + if ((Geodeheight <= pGeode->NoOfImgBuffers) && + (GeodeCounter == Geodeheight)) { + blit = TRUE; + blt_height = Geodeheight; + } else if ((Geodeheight > pGeode->NoOfImgBuffers) + && (GeodeCounter == pGeode->NoOfImgBuffers)) { + blit = TRUE; + Geodeheight -= pGeode->NoOfImgBuffers; + blt_height = pGeode->NoOfImgBuffers; + } else + return; + + if (blit) { + blit = FALSE; + + GeodeCounter = 0; + + if (GeodeTransparent) { + /* CALL ROUTINE FOR TRANSPARENT SCREEN TO SCREEN BLT + * * Should only be called for the "copy" raster operation. + */ + GFX(screen_to_screen_xblt((unsigned short)Geodesrcx, + (unsigned short)Geodesrcy, + (unsigned short)Geodedstx, + (unsigned short)Geodedsty, + (unsigned short)Geodewidth, + (unsigned short)blt_height, + GeodeTransColor)); + } else { + /* CALL ROUTINE FOR NORMAL SCREEN TO SCREEN BLT */ + GFX(screen_to_screen_blt((unsigned short)Geodesrcx, + (unsigned short)Geodesrcy, + (unsigned short)Geodedstx, + (unsigned short)Geodedsty, + (unsigned short)Geodewidth, + (unsigned short)blt_height)); + } + Geodedsty += blt_height; + GFX(wait_until_idle()); + } +} + +static unsigned short vector_mode_table[] = { + VM_MAJOR_INC | VM_MINOR_INC | VM_X_MAJOR, + VM_MAJOR_INC | VM_MINOR_INC | VM_Y_MAJOR, + VM_MAJOR_INC | VM_X_MAJOR, + VM_MINOR_INC | VM_Y_MAJOR, + VM_MINOR_INC | VM_X_MAJOR, + VM_MAJOR_INC | VM_Y_MAJOR, + VM_X_MAJOR, + VM_Y_MAJOR, +}; + +/*---------------------------------------------------------------------------- + * GX1SetupForSolidLine + * + * Description :This function is used setup the solid line color for + * future line draws. + * + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * color :Specifies the color value od line + * rop :Specifies rop values. + * Planemask :Specifies planemask value. + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +GX1SetupForSolidLine(ScrnInfoPtr pScreenInfo, + int color, int rop, unsigned int planemask) +{ + /* LOAD THE SOLID PATTERN COLOR */ + GFX(set_solid_pattern((unsigned int)color)); + + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAAPatternROP[rop])); +} + +/*--------------------------------------------------------------------------- + * GX1SubsequentBresenhamLine + * + * Description :This function is used to render a vector using the + * specified bresenham parameters. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x1 :Specifies the starting x position + * y1 :Specifies starting y possition + * absmaj :Specfies the Bresenman absolute major. + * absmin :Specfies the Bresenman absolute minor. + * err :Specifies the bresenham err term. + * len :Specifies the length of the vector interms of pixels. + * octant :not used in this function,may be added for standard + * interface. + * Returns :none + * + * Comments :none + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-line500). + * - x11perf: line segments (-seg500). +*---------------------------------------------------------------------------- +*/ +void +GX1SubsequentBresenhamLine(ScrnInfoPtr pScreenInfo, + int x1, int y1, int absmaj, int absmin, int err, + int len, int octant) +{ + int axial, init, diag; + + DEBUGMSG(0, (0, 0, "BLine %d, %d, %d, %d, %d, %d, %d\n", + x1, y1, absmaj, absmin, err, len, octant)); + + /* DETERMINE BRESENHAM PARAMETERS */ + + axial = ((int)absmin << 1); + init = axial - (int)absmaj; + diag = init - (int)absmaj; + + /* ADJUST INITIAL ERROR + * * Adjust by -1 for certain directions so that the vector + * * hits the same pixels when drawn in either direction. + * * The Gamma value is assumed to account for the initial + * * error adjustment for clipped lines. + */ + + init += err; + + /* CALL ROUTINE TO DRAW VECTOR */ + + GFX(bresenham_line((unsigned short)x1, + (unsigned short)y1, + (unsigned short)len, + (unsigned short)init, + (unsigned short)axial, + (unsigned short)diag, + (unsigned short)vector_mode_table[octant])); + +} + +#define ABS(_val1, _val2) (((_val1) > (_val2)) ? ((_val1)-(_val2)) : ((_val2) - (_val1))) + +void +GX1SubsequentSolidTwoPointLine(ScrnInfoPtr pScreenInfo, + int x0, int y0, int x1, int y1, int flags) +{ + long dx, dy, dmaj, dmin; + long axialerr, diagerr, initerr; + unsigned short vec_flags = 0; + + dx = ABS(x1, x0); + dy = ABS(y1, y0); + if (dx >= dy) { + dmaj = dx; + dmin = dy; + vec_flags = VM_X_MAJOR; + if (x1 > x0) + vec_flags |= VM_MAJOR_INC; + if (y1 > y0) + vec_flags |= VM_MINOR_INC; + } else { + dmaj = dy; + dmin = dx; + vec_flags = VM_Y_MAJOR; + if (x1 > x0) + vec_flags |= VM_MINOR_INC; + if (y1 > y0) + vec_flags |= VM_MAJOR_INC; + } + axialerr = dmin << 1; + diagerr = (dmin - dmaj) << 1; + initerr = (dmin << 1) - dmaj; + if (!(vec_flags & VM_MINOR_INC)) + initerr--; + + GFX(bresenham_line((unsigned short)x0, + (unsigned short)y0, + (unsigned short)dmaj, + (unsigned short)initerr, + (unsigned short)axialerr, + (unsigned short)diagerr, vec_flags)); +} + +/*--------------------------------------------------------------------------- + * GX1SubsequentHorVertLine + * + * This routine is called to render a vector using the specified Bresenham + * parameters. + * + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-hseg500). + * - x11perf: line segments (-vseg500). + *--------------------------------------------------------------------------- + */ +void +GX1SubsequentHorVertLine(ScrnInfoPtr pScreenInfo, + int x, int y, int len, int dir) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + if (pGeode->TV_Overscan_On) { + x += pGeode->TVOx; + y += pGeode->TVOy; + } + GFX(pattern_fill((unsigned short)x, (unsigned short)y, + (unsigned short)((dir == DEGREES_0) ? len : 1), + (unsigned short)((dir == DEGREES_0) ? 1 : len))); +} + +void +GX1SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern) +{ + int trans = (bg == -1); + unsigned long *pat = (unsigned long *)pattern; + + /* LOAD PATTERN COLORS AND DATA */ + + GFX(set_mono_pattern((unsigned long)bg, (unsigned long)fg, + (unsigned long)pat, (unsigned long)pat, + (unsigned char)trans)); + + /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ + + if (planemask == (unsigned int)-1) { + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + + GFX(set_raster_operation(XAAPatternROP[rop])); + } else { + /* SELECT ROP THAT USES SOURCE DATA FOR PLANEMASK */ + + GFX(set_solid_source((unsigned long)planemask)); + GFX(set_raster_operation(XAAPatternROP_PM[rop])); + } +} + +#if SCR2SCREXP +void +GX1SetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask) +{ + GFX(set_solid_pattern(planemask)); + GFX(set_mono_source(bg, fg, (bg == -1))); + + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAACopyROP_PM[rop & 0x0F])); + + DEBUGMSG(0, (0, X_NONE, "%x %x %x %x\n", fg, bg, rop, planemask)); +} + +void +GX1SubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int srcx, int srcy, int offset) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + GFX(mono_bitmap_to_screen_blt(offset, 0, x, y, w, h, + (unsigned char *)(pGeode->FBBase + + CALC_FBOFFSET(srcx, srcy)), + pGeode->Pitch)); +} +#endif + +#if !defined(STB_X) +/*---------------------------------------------------------------------------- + * OPTGX1SetupForFillRectSolid. + * + * Description :This routine is called to setup the solid pattern + * color for future rectangular fills or vectors. + * (non durango version) + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * color :Specifies the color to be filled up in defined area. + * rop :Specifies the raster operation value. + * planemask :Specifies the masking value based rop srcdata. + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +OPTGX1SetupForFillRectSolid(ScrnInfoPtr pScreenInfo, + int color, int rop, unsigned int planemask) +{ + unsigned short rop16; + + if (gu1_bpp == 8) { + color &= 0x00FF; + color |= (color << 8); + } + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + + if (planemask == 0xFFFFFFFF) { + if (gu1_bpp == 8) { + planemask &= 0x00FF; + planemask |= (planemask << 8); + } + + rop16 = XAAPatternROP[rop]; + + /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ + + GFX_WAIT_PENDING; + WRITE_REG32(GP_SRC_COLOR_0, (planemask << 16) | planemask); + } else { + rop16 = XAAPatternROP_PM[rop]; + } + + Geode_blt_mode = 0; + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + /* Only one operation can be pending at a time. */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color); + WRITE_REG16(GP_RASTER_MODE, rop16); +} + + /*---------------------------------------------------------------------------- + * OPTGX1SubsequentFillRectSolid. + * + * Description :This routine is used to fill the rectangle of previously + * specified solid pattern. + * (non durango version) + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * x and y :Specifies the x and y co-ordinatesarea. + * w and h :Specifies width and height respectively. + * + * Returns :none + * + * Comments :desired pattern can be set before this function by + * gfx_set_solid_pattern. + * Sample application uses: + * - Window backgrounds. + * - x11perf: rectangle tests (-rect500). + * - x11perf: fill trapezoid tests (-trap100). + * - x11perf: horizontal line segments (-hseg500). + *---------------------------------------------------------------------------- +*/ +void +OPTGX1SubsequentFillRectSolid(ScrnInfoPtr pScreenInfo, + int x, int y, int width, int height) +{ + unsigned short section; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + if (pGeode->TV_Overscan_On) { + x += pGeode->TVOx; + y += pGeode->TVOy; + } + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Only one operation can be pending at a time. */ + + GFX_WAIT_PENDING; + + /* SET REGISTERS TO DRAW RECTANGLE */ + WRITE_REG32(GP_DST_XCOOR, (y << 16) | x); + + WRITE_REG16(GP_HEIGHT, height); + + /* CHECK WIDTH FOR GX BUG WORKAROUND */ + + if (width <= 16) { + /* OK TO DRAW SMALL RECTANGLE IN ONE PASS */ + + WRITE_REG16(GP_WIDTH, width); + WRITE_REG16(GP_BLIT_MODE, Geode_blt_mode); + } else { + /* DRAW FIRST PART OF RECTANGLE */ + /* Get to a 16 pixel boundary. */ + + section = 0x10 - (x & 0x0F); + WRITE_REG16(GP_WIDTH, section); + WRITE_REG16(GP_BLIT_MODE, Geode_blt_mode); + + /* POLL UNTIL ABLE TO LOAD THE SECOND RECTANGLE */ + + GFX_WAIT_PENDING; + + WRITE_REG32(GP_DST_XCOOR, (y << 16) | (x + section)); + WRITE_REG16(GP_WIDTH, width - section); + WRITE_REG16(GP_BLIT_MODE, Geode_blt_mode); + } +} + +/*---------------------------------------------------------------------------- + * OPTGX1SetupForScreenToScreenCopy + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality. + * (non durango version) + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * xdir :This is set based on rop data. + * ydir :This is set based on rop data. + * rop :sets the raster operation + * transparency:tobeadded + * planemask :Specifies the value of masking from rop data + + * Returns :none + * + * Comments :The patterns specified is ignored inside the function +*---------------------------------------------------------------------------- +*/ +void +OPTGX1SetupForScreenToScreenCopy(ScrnInfoPtr pScreenInfo, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color) +{ + int GFXusesDstData; + unsigned short rop16 = XAACopyROP[rop]; + + /* FORMAT 8 BPP COLOR */ + /* GX requires 8BPP color data be duplicated into bits [15:8]. */ + + if (gu1_bpp == 8) { + planemask &= 0x00FF; + planemask |= (planemask << 8); + } + + /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */ + /* True if even bits (0:2:4:6) do not equal the correspinding */ + /* even bits (1:3:5:7). */ + + GFXusesDstData = ((rop & 0x55) ^ ((rop >> 1) & 0x55)); + + Geode_blt_mode = GFXusesDstData ? BM_READ_DST_FB1 | BM_READ_SRC_FB : + BM_READ_SRC_FB; + + /* CHECK AVAILABLE BLT BUFFER SIZE */ + /* Can use both BLT buffers if no destination data is required. */ + + Geode_buffer_width = GFXusesDstData ? GeodebufferWidthPixels : + GeodebufferWidthPixels << 1; + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + /* Only one operation can be pending at a time. */ + + GFX_WAIT_PENDING; + + WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)planemask); + WRITE_REG16(GP_RASTER_MODE, rop16); + + GeodeTransparent = (transparency_color == -1) ? 0 : 1; + GeodeTransColor = transparency_color; +} + +/*---------------------------------------------------------------------------- + * OPTGX1SubsquentScreenToScreenCopy + * + * Description :This function is called to perform a screen to screen + * BLT using the previously specified planemask,raster + * operation and * transparency flag + * (non durango version) + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * srcx :x -coordinates of the source window + * srcy :y-co-ordinates of the source window + * dstx :x -coordinates of the destination window + * dsty :y-co-ordinates of the destination window + * width :Specifies width of the window to be copied + * height :Height of the window to be copied. + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses (non-transparent): + * - Moving windows. + * - x11perf: scroll tests (-scroll500). + * - x11perf: copy from window to window (-copywinwin500). + * + * No application found using transparency. +*---------------------------------------------------------------------------- +*/ +void +OPTGX1SubsequentScreenToScreenCopy(ScrnInfoPtr pScreenInfo, + int srcx, int srcy, int dstx, int dsty, + int width, int height) +{ + unsigned short section; + unsigned short blit_mode = 0; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + if (pGeode->TV_Overscan_On) { + if ((srcx < pScreenInfo->virtualX) && (srcy < pScreenInfo->virtualY)) { + srcx += pGeode->TVOx; + srcy += pGeode->TVOy; + } + dstx += pGeode->TVOx; + dsty += pGeode->TVOy; + } + if (GeodeTransparent) { + if (gu1_bpp == 8) { + GeodeTransColor &= 0x00FF; + GeodeTransColor |= (GeodeTransColor << 8); + } + GeodeTransColor = + (GeodeTransColor & 0x0000FFFF) | (GeodeTransColor << 16); + + /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */ + /* Need to make sure any previous BLT using BB1 is complete. */ + /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */ + + GFX_WAIT_BUSY; + WRITE_SCRATCH32(Geodebb1Base, GeodeTransColor); + + /* DO BOGUS BLT TO LATCH DATA FROM BB1 */ + /* Already know graphics pipeline is idle. */ + /* Only need to latch data into the holding registers for the current */ + /* data from BB1. A 1 pixel wide BLT will suffice. */ + + WRITE_REG32(GP_DST_XCOOR, 0); + WRITE_REG32(GP_SRC_XCOOR, 0); + WRITE_REG32(GP_WIDTH, 0x00010001); + WRITE_REG16(GP_RASTER_MODE, 0x00CC); + WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1); + + /* WRITE REGISTERS FOR REAL SCREEN TO SCREEN BLT */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, height); + WRITE_REG16(GP_RASTER_MODE, 0x10C6); + WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); + + } + + /* CHECK Y DIRECTION */ + /* Hardware has support for negative Y direction. */ + + if (dsty > srcy) { + blit_mode = BM_REVERSE_Y; + srcy += height - 1; + dsty += height - 1; + } + + /* CHECK X DIRECTION */ + /* Hardware does not support negative X direction since at the time */ + /* of development all supported resolutions could fit a scanline of */ + /* data at once into the BLT buffers (using both BB0 and BB1). This */ + /* code is more generic to allow for any size BLT buffer. */ + + if (dstx > srcx) { + srcx += width; + dstx += width; + } + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Write the registers that do not change for each section. */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_HEIGHT, height); + + /* REPEAT UNTIL FINISHED WITH RECTANGLE */ + /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ + /* Hardware does not split the operations, so software must do it to */ + /* avoid large scanlines that would overflow the BLT buffers. */ + + while (width > 0) { + /* CHECK WIDTH OF CURRENT SECTION */ + + if (width > Geode_buffer_width) + section = Geode_buffer_width; + else + section = width; + + /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ + + GFX_WAIT_PENDING; + WRITE_REG16(GP_SRC_YCOOR, srcy); + WRITE_REG16(GP_DST_YCOOR, dsty); + WRITE_REG16(GP_WIDTH, section); + + /* CHECK X DIRECTION */ + + if (dstx > srcx) { + /* NEGATIVE X DIRECTION */ + /* Still positive X direction within the section. */ + + srcx -= section; + dstx -= section; + WRITE_REG16(GP_SRC_XCOOR, srcx); + WRITE_REG16(GP_DST_XCOOR, dstx); + } else { + /* POSITIVE X DIRECTION */ + + WRITE_REG16(GP_SRC_XCOOR, srcx); + WRITE_REG16(GP_DST_XCOOR, dstx); + dstx += section; + srcx += section; + } + WRITE_REG16(GP_BLIT_MODE, Geode_blt_mode | blit_mode); + width -= section; + } +} + +/*---------------------------------------------------------------------------- + * OPTGX1SetupForScanlineImageWrite + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality.(non durango version) + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * rop :sets the raster operation + * transparency_color :tobeadded + * planemask :Specifies the value of masking from rop data + * bpp :bits per pixel of the source pixmap + * depth :depth of the source pixmap. + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +OPTGX1SetupForScanlineImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth) +{ + Geodebpp = bpp; + OPTGX1SetupForScreenToScreenCopy(pScreenInfo, + 0, 0, rop, planemask, transparency_color); +} + +/*---------------------------------------------------------------------------- + * OPTGX1SubsequentScanlineImageWriteRect + * + * Description :This function is used to set up the x,y corordinates and width + * &height for future Bliting functionality.(non durango version) + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x :destination x + * y :destination y + * w :Specifies the width of the rectangle to be copied + * h :Specifies the height of the rectangle to be copied + * Returns :none + * + * Comments :none + *---------------------------------------------------------------------------- +*/ +void +OPTGX1SubsequentScanlineImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft) +{ + + Geodedstx = x; + Geodedsty = y; + Geodewidth = w; + Geodeheight = h; + GeodeCounter = 0; +} + +/*---------------------------------------------------------------------------- + * OPTGX1SubsquentImageWriteScanline + * + * Description :This function is called to + * BLT using the previously specified planemask,raster + * operation and transparency flag(non durango version) + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses (non-transparent): + * - Moving windows. + * - x11perf: scroll tests (-scroll500). + * - x11perf: copy from window to window (-copywinwin500). + * + * No application found using transparency. +*---------------------------------------------------------------------------- +*/ + +void +OPTGX1SubsequentImageWriteScanline(ScrnInfoPtr pScreenInfo, int bufno) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + int blt_height = 0; + char blit = FALSE; + + GeodeCounter++; + + if ((Geodeheight <= pGeode->NoOfImgBuffers) && + (GeodeCounter == Geodeheight)) { + blit = TRUE; + blt_height = Geodeheight; + } else if ((Geodeheight > pGeode->NoOfImgBuffers) + && (GeodeCounter == pGeode->NoOfImgBuffers)) { + blit = TRUE; + Geodeheight -= pGeode->NoOfImgBuffers; + blt_height = pGeode->NoOfImgBuffers; + } else + return; + + if (blit) { + blit = FALSE; + GeodeCounter = 0; + OPTGX1SubsequentScreenToScreenCopy(pScreenInfo, + Geodesrcx, Geodesrcy, Geodedstx, + Geodedsty, Geodewidth, blt_height); + Geodedsty += blt_height; + GFX_WAIT_BUSY; + } +} + +/*---------------------------------------------------------------------------- + * OPTGX1SetupForSolidLine + * + * Description :This function is used setup the solid line color for + * future line draws. + * + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * color :Specifies the color value od line + * rop :Specifies rop values. + * Planemask :Specifies planemask value. + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +OPTGX1SetupForSolidLine(ScrnInfoPtr pScreenInfo, + int color, int rop, unsigned int planemask) +{ + if (gu1_bpp == 8) { + color &= 0x00FF; + color |= (color << 8); + } + + GeodeROP = XAAPatternROP[rop]; + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + GFX_WAIT_PENDING; + WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color); + WRITE_REG16(GP_RASTER_MODE, GeodeROP); + + if ((GeodeROP & 0x55) ^ ((GeodeROP >> 1) & 0x55)) { + Geode_vector_mode = VM_READ_DST_FB; + Geode_blt_mode = BM_READ_DST_FB1 | BM_READ_SRC_FB; + } else { + Geode_vector_mode = 0; + Geode_blt_mode = BM_READ_SRC_FB; + } +} + +/*--------------------------------------------------------------------------- + * OPTGX1SubsequentBresenhamLine + * + * Description :This function is used to render a vector using the + * specified bresenham parameters. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x1 :Specifies the starting x position + * y1 :Specifies starting y possition + * absmaj :Specfies the Bresenman absolute major. + * absmin :Specfies the Bresenman absolute minor. + * err :Specifies the bresenham err term. + * len :Specifies the length of the vector interms of pixels. + * octant :not used in this function,may be added for standard + * interface. + * Returns :none + * + * Comments :none + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-seg500). +*---------------------------------------------------------------------------- +*/ +void +OPTGX1SubsequentBresenhamLine(ScrnInfoPtr pScreenInfo, + int x1, int y1, int absmaj, int absmin, int err, + int len, int octant) +{ + int axial, init, diag; + + DEBUGMSG(0, (0, 0, "BLine %d, %d, %d, %d, %d, %d, %d\n", + x1, y1, absmaj, absmin, err, len, octant)); + + /* DETERMINE BRESENHAM PARAMETERS */ + + axial = ((int)absmin << 1); + init = axial - (int)absmaj; + diag = init - (int)absmaj; + + /* ADJUST INITIAL ERROR + * * Adjust by -1 for certain directions so that the vector + * * hits the same pixels when drawn in either direction. + * * The Gamma value is assumed to account for the initial + * * error adjustment for clipped lines. + */ + + init += err; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GFX_WAIT_PENDING; + WRITE_REG32(GP_DST_XCOOR, (y1 << 16) | x1); + WRITE_REG32(GP_VECTOR_LENGTH, (((unsigned long)init) << 16) | + ((unsigned short)len)); + WRITE_REG32(GP_AXIAL_ERROR, (((unsigned long)diag) << 16) | + ((unsigned short)axial)); + WRITE_REG16(GP_VECTOR_MODE, + (Geode_vector_mode | vector_mode_table[octant])); +} + +void +OPTGX1SubsequentSolidTwoPointLine(ScrnInfoPtr pScreenInfo, + int x0, int y0, int x1, int y1, int flags) +{ + long dx, dy, dmaj, dmin; + long axialerr, diagerr, initerr; + unsigned short vec_flags = 0; + + dx = ABS(x1, x0); + dy = ABS(y1, y0); + if (dx >= dy) { + dmaj = dx; + dmin = dy; + vec_flags = VM_X_MAJOR; + if (x1 > x0) + vec_flags |= VM_MAJOR_INC; + if (y1 > y0) + vec_flags |= VM_MINOR_INC; + } else { + dmaj = dy; + dmin = dx; + vec_flags = VM_Y_MAJOR; + if (x1 > x0) + vec_flags |= VM_MINOR_INC; + if (y1 > y0) + vec_flags |= VM_MAJOR_INC; + } + + axialerr = dmin << 1; + diagerr = (dmin - dmaj) << 1; + initerr = (axialerr - dmaj); + + if (!(vec_flags & VM_MINOR_INC)) + initerr--; + + GFX_WAIT_PENDING; + WRITE_REG32(GP_DST_XCOOR, (y0 << 16) | x0); + WRITE_REG32(GP_VECTOR_LENGTH, (((unsigned long)initerr) << 16) | + ((unsigned short)dmaj)); + WRITE_REG32(GP_AXIAL_ERROR, (((unsigned long)diagerr) << 16) | + ((unsigned short)axialerr)); + WRITE_REG16(GP_VECTOR_MODE, (Geode_vector_mode | vec_flags)); +} + +/*--------------------------------------------------------------------------- + * OPTGX1SubsequentHorVertLine + * + * This routine is called to render a vector using the specified Bresenham + * parameters. + * + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-hseg500). + * - x11perf: line segments (-vseg500). + *--------------------------------------------------------------------------- + */ +void +OPTGX1SubsequentHorVertLine(ScrnInfoPtr pScreenInfo, + int x, int y, int len, int dir) +{ + + DEBUGMSG(0, (0, 0, "HLine %d, %d, %d, %d\n", x, y, len, dir)); + + OPTGX1SubsequentFillRectSolid(pScreenInfo, + (unsigned short)x, (unsigned short)y, + (unsigned short)((dir == DEGREES_0) ? len : + 1), + (unsigned short)((dir == DEGREES_0) ? 1 : + len)); +} +#endif + +/*---------------------------------------------------------------------------- + * GX1AccelInit. + * + * Description :This function sets up the supported acceleration routines and + * appropriate flags. + * + * Parameters: + * pScreen :Screeen pointer structure. + * + * Returns :TRUE on success and FALSE on Failure + * + * Comments :This function is called in GX1ScreenInit in + geode_driver.c to set * the acceleration. +*---------------------------------------------------------------------------- +*/ +Bool +GX1AccelInit(ScreenPtr pScreen) +{ + GeodePtr pGeode; + ScrnInfoPtr pScreenInfo; + + pScreenInfo = xf86Screens[pScreen->myNum]; + pGeode = GEODEPTR(pScreenInfo); + + switch (pScreenInfo->bitsPerPixel) { + case 8: + gu1_bpp = 8; + break; + case 16: + gu1_bpp = 16; + break; + } + + gu1_xshift = pScreenInfo->bitsPerPixel >> 4; + + switch (pGeode->Pitch) { + case 1024: + gu1_yshift = 10; + break; + case 2048: + gu1_yshift = 11; + break; + case 4096: + gu1_yshift = 12; + break; + } + + Geodebb0Base = BB0_BASE_3K; + Geodebb1Base = BB1_BASE_3K; + GeodebufferWidthPixels = Geodebb1Base - Geodebb0Base - 16; + + if (gu1_bpp > 8) { + /* If 16bpp, divide GFXbufferWidthPixels by 2 */ + GeodebufferWidthPixels >>= 1; + } + /* Getting the pointer for acceleration Inforecord */ + pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec(); + + /* SET ACCELERATION FLAGS */ + localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER; + localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES; + + /* HOOK SYNCRONIZARION ROUTINE */ + localRecPtr->Sync = GX1AccelSync; + + /* HOOK FILLED RECTANGLES */ + localRecPtr->SetupForSolidFill = (GX1SetupForFillRectSolid); + localRecPtr->SubsequentSolidFillRect = (GX1SubsequentFillRectSolid); + localRecPtr->SolidFillFlags = 0; + + /* HOOK 8x8 MonoEXPAND PATTERNS */ + localRecPtr->SetupForMono8x8PatternFill = GX1SetupFor8x8PatternMonoExpand; + localRecPtr->SubsequentMono8x8PatternFillRect = + GX1Subsequent8x8PatternMonoExpand; + localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST | + HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN; + + localRecPtr->SetupForColor8x8PatternFill = + GX1SetupFor8x8PatternColorExpand; + localRecPtr->SubsequentColor8x8PatternFillRect = + GX1Subsequent8x8PatternColorExpand; + /* Color expansion */ + localRecPtr->Color8x8PatternFillFlags = + BIT_ORDER_IN_BYTE_MSBFIRST | + SCANLINE_PAD_DWORD | HARDWARE_PATTERN_SCREEN_ORIGIN; + + /* HOOK SCREEN TO SCREEN COPIES + * * Set flag to only allow copy if transparency is enabled. + */ + localRecPtr->SetupForScreenToScreenCopy = + OPTACCEL(GX1SetupForScreenToScreenCopy); + localRecPtr->SubsequentScreenToScreenCopy = + OPTACCEL(GX1SubsequentScreenToScreenCopy); + localRecPtr->ScreenToScreenCopyFlags = 0; + + /* HOOK BRESENHAM SOLID LINES */ + /* Do not hook unless flag can be set preventing use of planemask. */ + localRecPtr->SolidLineFlags = NO_PLANEMASK; + localRecPtr->SetupForSolidLine = OPTACCEL(GX1SetupForSolidLine); + localRecPtr->SubsequentSolidBresenhamLine = + OPTACCEL(GX1SubsequentBresenhamLine); + localRecPtr->SubsequentSolidHorVertLine = + OPTACCEL(GX1SubsequentHorVertLine); + localRecPtr->SubsequentSolidTwoPointLine = + OPTACCEL(GX1SubsequentSolidTwoPointLine); + localRecPtr->SolidBresenhamLineErrorTermBits = 15; + +#if SCR2SCREXP + /* Color expansion */ + localRecPtr->ScreenToScreenColorExpandFillFlags = + BIT_ORDER_IN_BYTE_MSBFIRST | NO_TRANSPARENCY; + + localRecPtr->SetupForScreenToScreenColorExpandFill = + (GX1SetupForScreenToScreenColorExpandFill); + localRecPtr->SubsequentScreenToScreenColorExpandFill = + (GX1SubsequentScreenToScreenColorExpandFill); +#endif + + /* + * ImageWrite. + * + * SInce this uses off-screen scanline buffers, it is only of use when + * complex ROPs are used. But since the current XAA pixmap cache code + * only works when an ImageWrite is provided, the NO_GXCOPY flag is + * temporarily disabled. + */ + if (pGeode->AccelImageWriteBufferOffsets) { + + localRecPtr->ScanlineImageWriteFlags = + localRecPtr->ScreenToScreenCopyFlags; + localRecPtr->ScanlineImageWriteBuffers = + pGeode->AccelImageWriteBufferOffsets; + localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers; + localRecPtr->ImageWriteRange = pGeode->NoOfImgBuffers << gu1_yshift; + localRecPtr->SetupForScanlineImageWrite = + OPTACCEL(GX1SetupForScanlineImageWrite); + localRecPtr->SubsequentScanlineImageWriteRect = + OPTACCEL(GX1SubsequentScanlineImageWriteRect); + localRecPtr->SubsequentImageWriteScanline = + OPTACCEL(GX1SubsequentImageWriteScanline); + + ImgBufOffset = pGeode->AccelImageWriteBufferOffsets[0] - pGeode->FBBase; + Geodesrcy = ImgBufOffset >> gu1_yshift; + + Geodesrcx = ImgBufOffset & (pGeode->Pitch - 1); + Geodesrcx /= (pScreenInfo->bitsPerPixel >> 3); + } + + return (XAAInit(pScreen, localRecPtr)); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_cursor.c new file mode 100644 index 000000000..9aa1bd047 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_cursor.c @@ -0,0 +1,396 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_cursor.c,v 1.5 2003/02/21 16:51:09 alanh Exp $ */ +/* + * $Workfile: nsc_gx1_cursor.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: Xfree cursor implementation routines + * for geode HWcursor init.setting cursor color,image etc + * are done here. + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "nsc.h" + +/* Forward declarations of the functions */ +Bool GX1HWCursorInit(ScreenPtr pScreen); +static void GX1SetCursorColors(ScrnInfoPtr pScreenInfo, int bg, int fg); +static void GX1SetCursorPosition(ScrnInfoPtr pScreenInfo, int x, int y); +void GX1LoadCursorImage(ScrnInfoPtr pScreenInfo, unsigned char *src); +void GX1HideCursor(ScrnInfoPtr pScreenInfo); +void GX1ShowCursor(ScrnInfoPtr pScreenInfo); +static Bool GX1UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); +extern void GX1SetVideoPosition(int x, int y, int width, int height, + short src_w, short src_h, short drw_w, + short drw_h, int id, int offset, + ScrnInfoPtr pScrn); +/*---------------------------------------------------------------------------- + * GX1HWCursorInit. + * + * Description :This function sets the cursor information by probing the + * hardware. + * + * Parameters. + * pScreen :Screeen pointer structure. + * + * Returns :TRUE on success and FALSE on Failure + * + * Comments :Geode supports the hardware_cursor,no need to enable SW + * cursor. +*---------------------------------------------------------------------------- +*/ +Bool +GX1HWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + xf86CursorInfoPtr infoPtr; + + infoPtr = xf86CreateCursorInfoRec(); + if (!infoPtr) + return FALSE; + /* the geode structure is intiallized with the cursor infoRec */ + pGeode->CursorInfo = infoPtr; + infoPtr->MaxWidth = 32; + infoPtr->MaxHeight = 32; + /* seeting up the cursor flags */ + infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; + /* cursor info ptr is intiallized with the values obtained from + * * durnago calls + */ + infoPtr->SetCursorColors = GX1SetCursorColors; + infoPtr->SetCursorPosition = GX1SetCursorPosition; + infoPtr->LoadCursorImage = GX1LoadCursorImage; + infoPtr->HideCursor = GX1HideCursor; + infoPtr->ShowCursor = GX1ShowCursor; + infoPtr->UseHWCursor = GX1UseHWCursor; + return (xf86InitCursor(pScreen, infoPtr)); +} + +/*---------------------------------------------------------------------------- + * GX1SetCursorColors. + * + * Description :This function sets the cursor foreground and background + * colors + * Parameters: + * pScreen: Screeen pointer structure. + * bg: Specifies the color value of cursor background color. + * fg: Specifies the color value of cursor foreground color. + * Returns: none. + * + * Comments: The integer color value passed by this function is + * converted into * RGB value by the gfx_set_color routines. + *---------------------------------------------------------------------------- + */ +static void +GX1SetCursorColors(ScrnInfoPtr pScreenInfo, int bg, int fg) +{ + GFX(set_cursor_colors(bg, fg)); +} + +/*---------------------------------------------------------------------------- + * GX1SetCursorPosition. + * + * Description :This function sets the cursor co -ordinates and enable the + * cursor. + * + * Parameters: + * pScreen: Screeen pointer structure. + * x: Specifies the x-cordinates of the cursor. + * y: Specifies the y co-ordinate of the cursor. + * Returns: none. + * + *---------------------------------------------------------------------------- + */ +static void +GX1SetCursorPosition(ScrnInfoPtr pScreenInfo, int x, int y) +{ + unsigned long offset; + static int panOffset = 0; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + unsigned short xhot = 0, yhot = 0; + + if (x < 0) { + xhot = (unsigned short)(-x); + x = 0; + } + if (y < 0) { + yhot = (unsigned short)(-y); + y = 0; + } + + if (pGeode->TV_Overscan_On) { + x += pGeode->TVOx; + y += pGeode->TVOy; + } + GFX(set_cursor_position(pGeode->CursorStartOffset, x, y, xhot, yhot)); + GFX(set_cursor_enable(1)); + + if ((pGeode->OverlayON) && (pGeode->Panel)) { +#if defined(STB_X) + Gal_get_display_offset(&offset); +#else + offset = gfx_get_display_offset(); +#endif + if (offset != panOffset) { + GX1SetVideoPosition(pGeode->video_x, pGeode->video_y, + pGeode->video_w, pGeode->video_h, + pGeode->video_srcw, pGeode->video_srch, + pGeode->video_dstw, pGeode->video_dsth, + pGeode->video_id, pGeode->video_offset, + pGeode->video_scrnptr); + panOffset = offset; + } + } +} + +/*---------------------------------------------------------------------------- + * GX1LoadCursorImage + * + * Description :This function loads the 32x32 cursor pattern.The shape + * and color is set by AND and XOR masking of arrays of 32 + * DWORD. + * Parameters: + * pScreen: Screeen pointer structure. + * src : Specifies cursor data. + * Returns : none + * + *---------------------------------------------------------------------------- +*/ +void +GX1LoadCursorImage(ScrnInfoPtr pScreenInfo, unsigned char *src) +{ + int i, j; + unsigned long shape; + unsigned long mask; + unsigned long andMask[32] = { 0, }; + unsigned long xorMask[32] = { 0, }; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + j = 0; + for (i = 0; i < 32; i++) { + if (src) { + shape = ((unsigned long)src[i * 4] << 24) | + ((unsigned long)src[i * 4 + 1] << 16) | + ((unsigned long)src[i * 4 + 2] << 8) | + ((unsigned long)src[i * 4 + 3] << 0); + mask = ((unsigned long)src[i * 4 + 128] << 24) | + ((unsigned long)src[i * 4 + 1 + 128] << 16) | + ((unsigned long)src[i * 4 + 2 + 128] << 8) | + ((unsigned long)src[i * 4 + 3 + 128] << 0); + } else { + mask = 0x0; + shape = 0xFFFFFFFF; + } + + andMask[i] = ~(mask); + xorMask[i] = shape & mask; + } + + GFX(set_cursor_shape32(pGeode->CursorStartOffset, andMask, xorMask)); +} + +/*---------------------------------------------------------------------------- + * GX1HideCursor. + * + * Description :This function will disable the cursor. + * + * Parameters: + * pScreen: Handles to the Screeen pointer structure. + * + * Returns: none. + * + * Comments: gfx_set_cursor enable function is hardcoded to disable + * the cursor. + *---------------------------------------------------------------------------- + */ +void +GX1HideCursor(ScrnInfoPtr pScreenInfo) +{ + GFX(set_cursor_enable(0)); +} + +/*---------------------------------------------------------------------------- + * GX1ShowCursor + * + * Description :This function will enable the cursor. + * + * Parameters: + * pScreen :Handles to the Screeen pointer structure. + * + * Returns :none + * + * Comments :gfx_set_cursor enable function is hardcoded to enable the + * cursor + *---------------------------------------------------------------------------- +*/ +void +GX1ShowCursor(ScrnInfoPtr pScreenInfo) +{ + GFX(set_cursor_enable(1)); +} + +/*---------------------------------------------------------------------------- + * GX1UseHwCursor. + * + * Description :This function will sets the hardware cursor flag in + * pscreen structure. + * + * Parameters. + * pScreen :Handles to the Screeen pointer structure. + * + * Returns :none + * + * Comments :none + * + *---------------------------------------------------------------------------- +*/ +static Bool +GX1UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScreenInfo = XF86SCRNINFO(pScreen); + + if (pScreenInfo->currentMode->Flags & V_DBLSCAN) + return FALSE; + return TRUE; +} + +/* End of File */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c new file mode 100644 index 000000000..af4340963 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c @@ -0,0 +1,506 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c,v 1.2 2003/01/14 09:34:31 alanh Exp $ */ +/* + * $Workfile: nsc_gx1_dga.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File contents: DGA(Direct Acess Graphics mode) is feature of + * XFree86 that allows the program to access directly to video + * memory on the graphics card.DGA supports the double + * flickering.This file has the functions to support the DGA + * modes. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xaa.h" +#include "xaalocal.h" +#include "nsc.h" +#include "dgaproc.h" + +/* forward declarations */ +static Bool GX1_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static void GX1_CloseFramebuffer(ScrnInfoPtr pScrn); +static Bool GX1_SetMode(ScrnInfoPtr, DGAModePtr); +static int GX1_GetViewport(ScrnInfoPtr); +static void GX1_SetViewport(ScrnInfoPtr, int, int, int); +static void GX1_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void GX1_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); + +extern void GX1AdjustFrame(int, int, int, int); +extern Bool GX1SwitchMode(int, DisplayModePtr, int); +extern void GX1AccelSync(ScrnInfoPtr pScreenInfo); + +Bool GX1DGAInit(ScreenPtr pScreen); + +static DGAFunctionRec GeodeDGAFuncs = { + GX1_OpenFramebuffer, + GX1_CloseFramebuffer, + GX1_SetMode, + GX1_SetViewport, + GX1_GetViewport, + GX1AccelSync, + GX1_FillRect, + GX1_BlitRect, + NULL +}; + +/*---------------------------------------------------------------------------- + * GX1DGAInit. + * + * Description :This function is used to intiallize the DGA modes and sets the + viewport based on the screen mode. + * Parameters. + * pScreeen :Pointer to screen info structure. + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :This function prepares the DGA mode settings for + * other func reference. + * +*---------------------------------------------------------------------------- +*/ +Bool +GX1DGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GeodePtr pGeode = GEODEPTR(pScrn); + DGAModePtr modes = NULL, newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int Bpp = pScrn->bitsPerPixel >> 3; + int num = 0; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + DEBUGMSG(0, (0, X_NONE, "GX1DGAInit\n")); + while (pMode) { + + /* redundant but it can be used in future:if(0). */ + if (0) { /*pScrn->displayWidth != pMode->HDisplay */ + /* memory is allocated for dga to + *setup the viewport and mode parameters + */ + newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + /* one record is allocated here */ + newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + if (!newmodes) { + xfree(modes); + return FALSE; + } + modes = newmodes; + + SECOND_PASS: /* DGA mode flgas and viewport parametrs are set here. */ + + currentMode = modes + num; + num++; + currentMode->mode = pMode; + currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if (pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if (pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = pScrn->depth; + currentMode->bitsPerPixel = pScrn->bitsPerPixel; + currentMode->red_mask = pScrn->mask.red; + currentMode->green_mask = pScrn->mask.green; + currentMode->blue_mask = pScrn->mask.blue; + currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 1; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = pGeode->FBBase; + if (oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = + ((pScrn->displayWidth * Bpp) + 3) & ~3L; + currentMode->imageWidth = pScrn->displayWidth; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + } + pMode = pMode->next; + if (pMode == firstMode) + break; + } + pGeode->numDGAModes = num; + pGeode->DGAModes = modes; + return DGAInit(pScreen, &GeodeDGAFuncs, modes, num); +} + +/*---------------------------------------------------------------------------- + * GX1_SetMode. + * + * Description :This function is sets into the DGA mode. + *. + * Parameters. + * pScreeen :Pointer to screen info structure. + * pMode :Points to the DGAmode ptr data + * Returns :TRUE on success and FALSE on failure. + * + * Comments :none. + * + * +*---------------------------------------------------------------------------- +*/ +static Bool +GX1_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) +{ + static int OldDisplayWidth[MAXSCREENS]; + int index = pScrn->pScreen->myNum; + GeodePtr pGeode = GEODEPTR(pScrn); + + DEBUGMSG(0, (0, X_NONE, "GX1_SetMode\n")); + if (!pMode) { + /* restore the original mode + * * put the ScreenParameters back + */ + pScrn->displayWidth = OldDisplayWidth[index]; + GX1SwitchMode(index, pScrn->currentMode, 0); + pGeode->DGAactive = FALSE; + } else { + if (!pGeode->DGAactive) { /* save the old parameters */ + OldDisplayWidth[index] = pScrn->displayWidth; + pGeode->DGAactive = TRUE; + } + pScrn->displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + GX1SwitchMode(index, pMode->mode, 0); + } + /* enable/disable cursor */ + if (pGeode->HWCursor) { +#if defined(STB_X) + Gal_set_compression_enable(((pGeode->DGAactive) ? + GAL_COMPRESSION_DISABLE : + GAL_COMPRESSION_ENABLE)); + Gal_set_cursor_enable(!pGeode->DGAactive); +#else + gfx_set_cursor_enable(!pGeode->DGAactive); + gfx_set_compression_enable(!pGeode->DGAactive); +#endif /* STB_X */ + } + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX1_GetViewPort. + * + * Description :This function is Gets the viewport window memory. + *. + * Parameters. + * pScrn :Pointer to screen info structure. + * + * Returns :returns the viewport status. + * + * Comments :none. + * + * +*---------------------------------------------------------------------------- +*/ +static int +GX1_GetViewport(ScrnInfoPtr pScrn) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + return pGeode->DGAViewportStatus; +} + +/*---------------------------------------------------------------------------- + * GX1_SetViewPort. + * + * Description :This function is Gets the viewport window memory. + * + * Parameters. + * pScrn :Pointer to screen info structure. + x :x-cordinate of viewport window + * y :y-codinate of the viewport window. + * flags :indicates the viewport to be flipped or not. + * Returns :returns the viewport status as zero. + * + * Comments :none. + * +*---------------------------------------------------------------------------- +*/ +static void +GX1_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + GX1AdjustFrame(pScrn->pScreen->myNum, x, y, flags); + pGeode->DGAViewportStatus = 0; /*GX1AdjustFrame loops until finished */ +} + +/*---------------------------------------------------------------------------- + * GX1_FillRect. + * + * Description :This function is Gets the viewport window memory. + *. + * Parameters. + * pScrn :Pointer to screen info structure. + * x :x-cordinate of viewport window + * y :y-codinate of the viewport window. + * w :width of the rectangle + * h :height of the rectangle. + * color :color to be filled in rectangle. + * + * Returns :returns the viewport status as zero. + * + * Comments :This function is implemented by solidfill routines.. + * +*---------------------------------------------------------------------------- +*/ +static void +GX1_FillRect(ScrnInfoPtr pScrn, int x, int y, + int w, int h, unsigned long color) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + if (pGeode->AccelInfoRec) { + (*pGeode->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0); + (*pGeode->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); + SET_SYNC_FLAG(pGeode->AccelInfoRec); + } +} + +/*---------------------------------------------------------------------------- + * GX1_BlitRect. + * + * Description :This function implementing Blit and it moves a + * Rectangular block of data from one location to other + * Location. + * + * Parameters. + * pScrn :Pointer to screen info structure. + * srcx :x-cordinate of the src rectangle + * srcy :y-codinate of src rectangle. + * w :width of the rectangle + * h :height of the rectangle. + * dstx :x-cordinate of the dst rectangle. + * dsty :y -coordinates of the dst rectangle. + * Returns :none. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static void +GX1_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, + int h, int dstx, int dsty) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + if (pGeode->AccelInfoRec) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pGeode->AccelInfoRec->SetupForScreenToScreenCopy) + (pScrn, xdir, ydir, GXcopy, ~0, -1); + (*pGeode->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrn, srcx, + srcy, dstx, dsty, + w, h); + SET_SYNC_FLAG(pGeode->AccelInfoRec); + } +} + +/*---------------------------------------------------------------------------- + * GX1_OpenFramebuffer. + * + * Description :This function open the framebuffer driver for DGA. + * + * Parameters. + * pScrn :Pointer to screen info structure. + * srcx :x-cordinate of the src rectangle + * srcy :y-codinate of src rectangle. + * w :width of the rectangle + * h :height of the rectangle. + * dstx :x-cordinate of the dst rectangle. + * dsty :y -coordinates of the dst rectangle. + * Returns :none. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static Bool +GX1_OpenFramebuffer(ScrnInfoPtr pScrn, + char **name, unsigned char **mem, + int *size, int *offset, int *flags) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char *)pGeode->FBLinearAddr; + *size = pGeode->FBSize; + *offset = 0; + *flags = DGA_NEED_ROOT; + return TRUE; +} + +static void +GX1_CloseFramebuffer(ScrnInfoPtr pScrn) +{ +} + +/* end of file */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_driver.c new file mode 100644 index 000000000..a5d83be28 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_driver.c @@ -0,0 +1,2484 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_driver.c,v 1.7 2003/02/14 13:28:29 alanh Exp $ */ +/* + * $Workfile: nsc_gx1_driver.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This is the main module configures the interfacing + * with the X server. The individual modules will be + * loaded based upon the options selected from the + * XF86Config. This file also has modules for finding + * supported modes, turning on the modes based on options. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* + * Lots of fixes & updates + * Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +#define DEBUG(x) +#define GEODE_TRACE 0 +#define CFB 0 +#define HWVGA 0 + +/* Includes that are used by all drivers */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Resources.h" + +/* We may want inb() and outb() */ +#include "compiler.h" + +/* We may want to access the PCI config space */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +/* Colormap handling stuff */ +#include "xf86cmap.h" + +/* Frame buffer stuff */ +#if CFB +/* + * If using cfb, cfb.h is required. Select the others for the bpp values + * the driver supports. + */ +#define PSZ 8 /* needed for cfb.h */ +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" + +#else +#include "fb.h" + +#endif + +#include "shadowfb.h" + +/* Machine independent stuff */ +#include "mipointer.h" +#include "mibank.h" +#include "micmap.h" +/* All drivers implementing backing store need this */ +#include "mibstore.h" +#include "vgaHW.h" +#include "vbe.h" + +/* Check for some extensions */ +#ifdef XFreeXDGA +#define _XF86_DGA_SERVER_ +#include "extensions/xf86dgastr.h" +#endif /* XFreeXDGA */ + +#ifdef DPMSExtension +#include "globals.h" +#include "opaque.h" +#define DPMS_SERVER +#include "extensions/dpms.h" +#endif /* DPMSExtension */ + +/* Our private include file (this also includes the durango headers) */ +#include "nsc.h" + +#if GEODE_TRACE +/* ANSI C does not allow var arg macros */ +#define GeodeDebug(args) DebugPort(DCount++);ErrorF args +#else +#define GeodeDebug(args) +#endif + +extern SymTabRec GeodeChipsets[]; +extern OptionInfoRec GeodeOptions[]; + +typedef struct _MemOffset +{ + unsigned long xres; + unsigned long yres; + unsigned long bpp; + unsigned long CBOffset; + unsigned short CBPitch; + unsigned short CBSize; + unsigned long CurOffset; + unsigned long OffScreenOffset; +} +MemOffset; + +/* predefined memory address for compression and cursor offsets + * if COMPRESSION enabled. + */ +MemOffset GeodeMemOffset[] = { + {640, 480, 8, 640, 1024, 272, 0x78000, 0x78100}, + {640, 480, 16, 1280, 2048, 272, 0x610, 0xF0000}, + {800, 600, 8, 800, 1024, 208, 0x96000, 0x96100}, + {800, 600, 16, 1600, 2048, 272, 0x12C000, 0x12C100}, + {1024, 768, 8, 0xC0000, 272, 272, 0xF3000, 0xF3100}, + {1024, 768, 16, 0x180000, 272, 272, 0x1B3000, 0x1B3100}, + {1152, 864, 8, 1152, 2048, 272, 0x590, 0x1B0000}, + {1152, 864, 16, 2304, 4096, 272, 0xA10, 0x360000}, + {1280, 1024, 8, 1280, 2048, 272, 0x610, 0x200000}, + {1280, 1024, 16, 2560, 4096, 272, 0xB10, 0x400000}, + + /* PAL TV modes */ + + {704, 576, 16, 1408, 2048, 272, 0x690, 0x120000}, + {720, 576, 16, 1440, 2048, 272, 0x6B0, 0x120000}, + {768, 576, 16, 1536, 2048, 256, 0x700, 0x120000}, + + /* NTSC TV modes */ + + {704, 480, 16, 1408, 2048, 272, 0x690, 0xF0000}, + {720, 480, 16, 1440, 2048, 272, 0x6B0, 0xF0000} + +}; +static int MemIndex = 0; + +static Bool GX1PreInit(ScrnInfoPtr, int); +static Bool GX1ScreenInit(int, ScreenPtr, int, char **); +static Bool GX1EnterVT(int, int); +static void GX1LeaveVT(int, int); +static void GX1FreeScreen(int, int); +void GX1AdjustFrame(int, int, int, int); +Bool GX1SwitchMode(int, DisplayModePtr, int); +static int GX1ValidMode(int, DisplayModePtr, Bool, int); +static void GX1LoadPalette(ScrnInfoPtr pScreenInfo, + int numColors, int *indizes, + LOCO * colors, VisualPtr pVisual); +static Bool GX1MapMem(ScrnInfoPtr); +static Bool GX1UnmapMem(ScrnInfoPtr); + +extern Bool GX1AccelInit(ScreenPtr pScreen); +extern Bool GX1HWCursorInit(ScreenPtr pScreen); +extern void GX1HideCursor(ScrnInfoPtr pScreenInfo); +extern void GX1ShowCursor(ScrnInfoPtr pScreenInfo); +extern void GX1PointerMoved(int index, int x, int y); +extern void GX1RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void GX1RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void GX1RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void GX1InitVideo(ScreenPtr pScreen); +extern Bool GX1DGAInit(ScreenPtr pScreen); +extern void GX1LoadCursorImage(ScrnInfoPtr pScreenInfo, unsigned char *src); +extern unsigned int GetVideoMemSize(void); + +void get_tv_overscan_geom(const char *options, int *X, int *Y, int *W, + int *H); +void GX1SetupChipsetFPtr(ScrnInfoPtr pScrn); +GeodePtr GX1GetRec(ScrnInfoPtr pScreenInfo); +void gx1_clear_screen(int width, int height); + +#if !defined(STB_X) +extern unsigned char *XpressROMPtr; +#endif /* STB_X */ + +/* List of symbols from other modules that this module references.The purpose +* is that to avoid unresolved symbol warnings +*/ +extern const char *nscVgahwSymbols[]; +extern const char *nscVbeSymbols[]; +extern const char *nscInt10Symbols[]; + +#if CFB +extern const char *nscCfbSymbols[]; +#else +extern const char *nscFbSymbols[]; +#endif +extern const char *nscXaaSymbols[]; +extern const char *nscRamdacSymbols[]; +extern const char *nscShadowSymbols[]; + +void +GX1SetupChipsetFPtr(ScrnInfoPtr pScrn) +{ + GeodeDebug(("GX1SetupChipsetFPtr!\n")); + + pScrn->PreInit = GX1PreInit; + pScrn->ScreenInit = GX1ScreenInit; + pScrn->SwitchMode = GX1SwitchMode; + pScrn->AdjustFrame = GX1AdjustFrame; + pScrn->EnterVT = GX1EnterVT; + pScrn->LeaveVT = GX1LeaveVT; + pScrn->FreeScreen = GX1FreeScreen; + pScrn->ValidMode = GX1ValidMode; +} + +/*---------------------------------------------------------------------------- + * GX1GetRec. + * + * Description :This function allocate an GeodeRec and hooked into + * pScreenInfo str driverPrivate member of ScreeenInfo + * structure. + * Parameters. + * pScreenInfo :Pointer handle to the screenonfo structure. + * + * Returns :allocated pScreeninfo structure. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +GeodePtr +GX1GetRec(ScrnInfoPtr pScreenInfo) +{ + if (!pScreenInfo->driverPrivate) + pScreenInfo->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); + return GEODEPTR(pScreenInfo); +} + +/*---------------------------------------------------------------------------- + * GX1FreeRec. + * + * Description :This function deallocate an GeodeRec and freed from + * pScreenInfo str driverPrivate member of ScreeenInfo + * structure. + * Parameters. + * pScreenInfo :Pointer handle to the screenonfo structure. + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static void +GX1FreeRec(ScrnInfoPtr pScreenInfo) +{ + if (pScreenInfo->driverPrivate == NULL) { + return; + } + xfree(pScreenInfo->driverPrivate); + pScreenInfo->driverPrivate = NULL; +} + +/*---------------------------------------------------------------------------- + * GX1SaveScreen. + * + * Description :This is todo the screen blanking + * + * Parameters. + * pScreen :Handle to ScreenPtr structure. + * mode :mode is used by vgaHWSaveScren to check blnak os on. + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +static Bool +GX1SaveScreen(ScreenPtr pScreen, int mode) +{ +#if !defined(STB_X) + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + + GeodeDebug(("GX2SaveScreen!\n")); + + if (!pScreenInfo->vtSema) + return vgaHWSaveScreen(pScreen, mode); + +#endif /* STB_X */ + return TRUE; +} + +/*---------------------------------------------------------------------------- + * get_tv_overscan_geom. + * + * Description :This is todo the screen blanking + * + * Parameters: + * options : Pointer to the display options. + * X: Pointer to the offset of the screen X-co-ordinate. + * Y: Pointer to the offset of the screen Y-co-ordinate. + * W: Pointer to the width of the screen. + * H: Pointer to the height of the screen. + * Returns : none. + * + * Comments :none + *------------------------------------------------------------------------ + */ +void +get_tv_overscan_geom(const char *options, int *X, int *Y, int *W, int *H) +{ + char *tv_opt; + + tv_opt = strtok((char *)options, ":"); + *X = strtoul(tv_opt, NULL, 0); + tv_opt = strtok(NULL, ":"); + *Y = strtoul(tv_opt, NULL, 0); + tv_opt = strtok(NULL, ":"); + *W = strtoul(tv_opt, NULL, 0); + tv_opt = strtok(NULL, ":"); + *H = strtoul(tv_opt, NULL, 0); +} + +static void +GX1ProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} + +/*---------------------------------------------------------------------------- + * GX1PreInit. + * + * Description :This function is called only once ate teh server startup + * + * Parameters. + * pScreenInfo :Handle to ScreenPtr structure. + * flags :flags may be used to check the probeed one with config. + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :none. + *---------------------------------------------------------------------------- + */ +static Bool +GX1PreInit(ScrnInfoPtr pScreenInfo, int flags) +{ + static ClockRange GeodeClockRange = + { NULL, 25175, 135000, 0, FALSE, TRUE, 1, 1, 0 }; + MessageType from; + int i = 0; + GeodePtr pGeode; + char *mod = NULL; + +#if CFB + char *reqSymbol = NULL; +#endif + +#if defined(STB_X) + GAL_ADAPTERINFO sAdapterInfo; +#endif /* STB_X */ + unsigned int PitchInc = 0, minPitch = 0, maxPitch = 0; + unsigned int minHeight = 0, maxHeight = 0; + const char *s; + char **modes; + char **tvmodes_defa; + + GeodeDebug(("GX1PreInit!\n")); + /* Allocate driver private structure */ + if (!(pGeode = GX1GetRec(pScreenInfo))) + return FALSE; + + /* This is the general case */ + for (i = 0; i < pScreenInfo->numEntities; i++) { + pGeode->pEnt = xf86GetEntityInfo(pScreenInfo->entityList[i]); + if (pGeode->pEnt->resources) + return FALSE; + pGeode->Chipset = pGeode->pEnt->chipset; + pScreenInfo->chipset = (char *)xf86TokenToString(GeodeChipsets, + pGeode->pEnt->chipset); + } + + if (flags & PROBE_DETECT) { + GX1ProbeDDC(pScreenInfo, pGeode->pEnt->index); + return TRUE; + } + + pGeode->FBVGAActive = 0; /* KFB will Knock of VGA */ + +#if !defined(STB_X) + /* If the vgahw module would be needed it would be loaded here */ + if (!xf86LoadSubModule(pScreenInfo, "vgahw")) { + return FALSE; + } + + xf86LoaderReqSymLists(nscVgahwSymbols, NULL); +#endif /* STB_X */ + GeodeDebug(("GX1PreInit(1)!\n")); + + /* Do the durango hardware detection */ +#if defined(STB_X) + if (!Gal_initialize_interface()) + return FALSE; + if (Gal_get_adapter_info(&sAdapterInfo)) { + pGeode->cpu_version = sAdapterInfo.dwCPUVersion; + pGeode->vid_version = sAdapterInfo.dwVideoVersion; + pGeode->FBSize = sAdapterInfo.dwFrameBufferSize; + /* update the max clock from the one system suports */ + GeodeClockRange.maxClock = sAdapterInfo.dwMaxSupportedPixelClock; + pGeode->FBLinearAddr = sAdapterInfo.dwFrameBufferBase; + + if (!GX1MapMem(pScreenInfo)) + return FALSE; + + } else { + return FALSE; + } +#else + pGeode->cpu_version = gfx_detect_cpu(); + pGeode->vid_version = gfx_detect_video(); + pGeode->FBLinearAddr = gfx_get_frame_buffer_base(); + /* update the max clock from the one system suports */ + GeodeClockRange.maxClock = gfx_get_max_supported_pixel_clock(); + + if (!GX1MapMem(pScreenInfo)) + return FALSE; + + DEBUGMSG(1, + (0, X_INFO, + "Geode chip info: cpu:%x vid:%x size:%x base:%x, rom:%X\n", + pGeode->cpu_version, pGeode->vid_version, pGeode->FBSize, + pGeode->FBBase, XpressROMPtr)); +#endif /* STB_X */ + + /* Fill in the monitor field */ + pScreenInfo->monitor = pScreenInfo->confScreen->monitor; + GeodeDebug(("GX1PreInit(2)!\n")); + /* Determine depth, bpp, etc. */ + if (!xf86SetDepthBpp(pScreenInfo, 8, 8, 8, 0)) { + return FALSE; + + } else { + + switch (pScreenInfo->depth) { + case 8: + case 16: + break; + default: + /* Depth not supported */ + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "Given depth (%d bpp) is not supported by this driver\n", + pScreenInfo->depth)); + return FALSE; + } + } + + /*This must happen after pScreenInfo->display has been set + * * because xf86SetWeight references it. + */ + if (pScreenInfo->depth > 8) { + /* The defaults are OK for us */ + rgb zeros = { 0, 0, 0 }; + + if (!xf86SetWeight(pScreenInfo, zeros, zeros)) { + return FALSE; + } else { + /* XXX Check if the returned weight is supported */ + } + } + xf86PrintDepthBpp(pScreenInfo); + GeodeDebug(("GX1PreInit(3)!\n")); + if (!xf86SetDefaultVisual(pScreenInfo, -1)) + return FALSE; + GeodeDebug(("GX1PreInit(4)!\n")); + + /* The new cmap layer needs this to be initialized */ + if (pScreenInfo->depth > 1) { + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScreenInfo, zeros)) { + return FALSE; + } + } + GeodeDebug(("GX1PreInit(5)!\n")); + /* We use a programmable clock */ + pScreenInfo->progClock = TRUE; + + /*Collect all of the relevant option flags + * *(fill in pScreenInfo->options) + */ + xf86CollectOptions(pScreenInfo, NULL); + + /*Process the options */ + xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options, + GeodeOptions); + + /*Set the bits per RGB for 8bpp mode */ + if (pScreenInfo->depth == 8) { + /* Default to 8 */ + pScreenInfo->rgbBits = 8; + } + from = X_DEFAULT; + pGeode->HWCursor = TRUE; + /* + * *The preferred method is to use the "hw cursor" option as a tri-state + * *option, with the default set above. + */ + if (xf86GetOptValBool(GeodeOptions, OPTION_HW_CURSOR, &pGeode->HWCursor)) { + from = X_CONFIG; + } + /* For compatibility, accept this too (as an override) */ + if (xf86ReturnOptValBool(GeodeOptions, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pGeode->HWCursor = FALSE; + } + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, "Using %s cursor\n", + pGeode->HWCursor ? "HW" : "SW")); + + pGeode->Compression = TRUE; + if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOCOMPRESSION, FALSE)) { + pGeode->Compression = FALSE; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "NoCompression\n")); + } + + pGeode->NoAccel = FALSE; + if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOACCEL, FALSE)) { + pGeode->NoAccel = TRUE; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "Acceleration \ + disabled\n")); + } + + if (!xf86GetOptValInteger(GeodeOptions, OPTION_OSM_IMG_BUFS, + &(pGeode->NoOfImgBuffers))) + pGeode->NoOfImgBuffers = DEFAULT_NUM_OF_BUF; /* default # of buffers */ + if (pGeode->NoOfImgBuffers <= 0) + pGeode->NoOfImgBuffers = 0; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "No of Buffers %d\n", + pGeode->NoOfImgBuffers)); + + pGeode->TVSupport = FALSE; + + pGeode->FBTVActive = 0; + GFX(get_tv_enable(&(pGeode->FBTVActive))); + DEBUGMSG(1, (1, X_PROBED, "FB TV %d \n", pGeode->FBTVActive)); + + if ((s = xf86GetOptValString(GeodeOptions, OPTION_TV_SUPPORT))) { + + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "TV = %s\n", s)); + if (!xf86NameCmp(s, "PAL-768x576")) { + pGeode->TvParam.wStandard = TV_STANDARD_PAL; + pGeode->TvParam.wType = GFX_ON_TV_SQUARE_PIXELS; + pGeode->TvParam.wWidth = 768; + pGeode->TvParam.wHeight = 576; + pGeode->TVSupport = TRUE; + } else if (!xf86NameCmp(s, "PAL-720x576")) { + pGeode->TvParam.wStandard = TV_STANDARD_PAL; + pGeode->TvParam.wType = GFX_ON_TV_NO_SCALING; + pGeode->TvParam.wWidth = 720; + pGeode->TvParam.wHeight = 576; + pGeode->TVSupport = TRUE; + } else if (!xf86NameCmp(s, "NTSC-640x480")) { + pGeode->TvParam.wStandard = TV_STANDARD_NTSC; + pGeode->TvParam.wType = GFX_ON_TV_SQUARE_PIXELS; + pGeode->TvParam.wWidth = 640; + pGeode->TvParam.wHeight = 480; + pGeode->TVSupport = TRUE; + } else if (!xf86NameCmp(s, "NTSC-720x480")) { + pGeode->TvParam.wStandard = TV_STANDARD_NTSC; + pGeode->TvParam.wType = GFX_ON_TV_NO_SCALING; + pGeode->TvParam.wWidth = 720; + pGeode->TvParam.wHeight = 480; + pGeode->TVSupport = TRUE; + } + + if (pGeode->TVSupport == TRUE) { + pGeode->TvParam.wOutput = TV_OUTPUT_S_VIDEO; /* default */ + + /* Now find the output */ + if (pGeode->TVSupport) { + if ((s = xf86GetOptValString(GeodeOptions, OPTION_TV_OUTPUT))) { + if (!xf86NameCmp(s, "COMPOSITE")) { + pGeode->TvParam.wOutput = TV_OUTPUT_COMPOSITE; + } else if (!xf86NameCmp(s, "SVIDEO")) { + pGeode->TvParam.wOutput = TV_OUTPUT_S_VIDEO; + } else if (!xf86NameCmp(s, "YUV")) { + pGeode->TvParam.wOutput = TV_OUTPUT_YUV; + } else if (!xf86NameCmp(s, "SCART")) { + pGeode->TvParam.wOutput = TV_OUTPUT_SCART; + } + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "TVOutput = %s %d\n", s, + pGeode->TvParam.wOutput)); + } + } + } +/* Only SC1200 can support TV modes */ + if ((pGeode->vid_version != GFX_VID_SC1200) + && (pGeode->TVSupport == TRUE)) { + pGeode->TVSupport = FALSE; + } + + /*TV can be turned on only in 16BPP mode */ + if ((pScreenInfo->depth == 8) && (pGeode->TVSupport == TRUE)) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Warning TV Disabled, TV Can't be supported in 8Bpp !!!\n")); + pGeode->TVSupport = FALSE; + } + } + + /* If TV Supported then check for TVO support */ + if (pGeode->TVSupport == TRUE) { + pGeode->TVOx = 0; + pGeode->TVOy = 0; + pGeode->TVOw = 0; + pGeode->TVOh = 0; + pGeode->TV_Overscan_On = FALSE; + if ((s = xf86GetOptValString(GeodeOptions, OPTION_TV_OVERSCAN))) { + get_tv_overscan_geom(s, &(pGeode->TVOx), + &(pGeode->TVOy), &(pGeode->TVOw), + &(pGeode->TVOh)); + + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "TVO %d %d %d %d\n", pGeode->TVOx, pGeode->TVOy, + pGeode->TVOw, pGeode->TVOh)); + + if ((pGeode->TVOx >= 0 && pGeode->TVOy >= 0) && + (pGeode->TVOh > 0 && pGeode->TVOw > 0)) { + if (((pGeode->TVOx + pGeode->TVOw) <= pGeode->TvParam.wWidth) && + ((pGeode->TVOy + pGeode->TVOh) <= pGeode->TvParam.wHeight)) { + pGeode->TV_Overscan_On = TRUE; + } + } + } + } + + /* If TV is not selected and currently TV is enabled, disable the TV out */ + if (pGeode->TVSupport == FALSE) { + unsigned int status = 0; + + GFX(get_tv_enable(&status)); + if (status) + GFX(set_tv_enable(0)); + } + + pGeode->Panel = FALSE; + if (xf86ReturnOptValBool(GeodeOptions, OPTION_FLATPANEL, FALSE)) { + DEBUGMSG(0, (pScreenInfo->scrnIndex, X_CONFIG, "FlatPanel Selected\n")); + pGeode->Panel = TRUE; + } + + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Quering FP Bios %d\n", pGeode->Panel)); + + /* if FP not supported in BIOS, then turn off user option */ + if (pGeode->Panel) { + int ret; + + /* check if bios supports FP */ +#if defined(STB_X) + Gal_get_softvga_state(&ret); + if (!ret) { + /* its time to wakeup softvga */ + Gal_set_softvga_state(TRUE); + Gal_vga_mode_switch(0); + } + Gal_pnl_enabled_in_bios(&pGeode->Panel); + + if (pGeode->Panel) { + Gal_pnl_info_from_bios(&pGeode->FPBX, &pGeode->FPBY, + &pGeode->FPBB, &pGeode->FPBF); + } + if (!ret) { + /* its time to put softvga back to sleep */ + Gal_set_softvga_state(FALSE); + Gal_vga_mode_switch(1); + } +#else + ret = gfx_get_softvga_active(); + if (!ret) { + /* its time to wakeup softvga */ + gfx_enable_softvga(); + gfx_vga_mode_switch(0); + } + pGeode->Panel = Pnl_IsPanelEnabledInBIOS(); + if (pGeode->Panel) { + Pnl_GetPanelInfoFromBIOS(&pGeode->FPBX, &pGeode->FPBY, + &pGeode->FPBB, &pGeode->FPBF); + } + if (!ret) { + /* its time to put softvga back to sleep */ + gfx_disable_softvga(); + gfx_vga_mode_switch(1); + } +#endif + } + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Quering FP Bios %d %d %d %d\n", + pGeode->FPBX, pGeode->FPBY, pGeode->FPBB, pGeode->FPBF)); + + /* if panel not selected and Panel can be supported. + * Power down the panel. + */ + if (!pGeode->Panel) { +#if defined(STB_X) + Gal_pnl_powerdown(); +#else + Pnl_PowerDown(); +#endif /* STB_X */ + } else { +#if defined(STB_X) + Gal_pnl_powerup(); +#else + Pnl_PowerUp(); +#endif /* STB_X */ + } + + pGeode->ShadowFB = FALSE; + if (xf86ReturnOptValBool(GeodeOptions, OPTION_SHADOW_FB, FALSE)) { + pGeode->ShadowFB = TRUE; + pGeode->NoAccel = TRUE; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Using \"Shadow Framebuffer\" - acceleration disabled\n")); + } + + pGeode->Rotate = 0; + if ((s = xf86GetOptValString(GeodeOptions, OPTION_ROTATE))) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "Rotating - %s\n", s)); + if (!xf86NameCmp(s, "CW")) { + pGeode->ShadowFB = TRUE; + pGeode->NoAccel = TRUE; + pGeode->HWCursor = FALSE; + pGeode->Rotate = 1; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n")); + } else { + if (!xf86NameCmp(s, "CCW")) { + pGeode->ShadowFB = TRUE; + pGeode->NoAccel = TRUE; + pGeode->HWCursor = FALSE; + pGeode->Rotate = -1; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Rotating screen counter clockwise - acceleration \ + disabled\n")); + } else { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "\"%s\" is not a valid value for Option \"Rotate\"\n", + s)); + DEBUGMSG(1, + (pScreenInfo->scrnIndex, X_INFO, + "Valid options are \"CW\" or \"CCW\"\n")); + } + } + } + + /* Disable Rotation when TV Over Scan is enabled */ + if (pGeode->TV_Overscan_On) + pGeode->Rotate = 0; + + /* XXX Init further private data here */ + + /* + * * This shouldn't happen because such problems should be caught in + * * GeodeProbe(), but check it just in case. + */ + if (pScreenInfo->chipset == NULL) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "ChipID 0x%04X is not recognised\n", pGeode->Chipset)); + return FALSE; + } + if (pGeode->Chipset < 0) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognised\n", + pScreenInfo->chipset)); + return FALSE; + } + GeodeDebug(("GX1PreInit(6)!\n")); + + /* + * * Init the screen with some values + */ +#if !defined(STB_X) + + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, + "Video I/O registers at 0x%08lX\n", + (unsigned long)VGAHW_GET_IOBASE())); +#endif /* STB_X */ + + if (pScreenInfo->memPhysBase == 0) { + from = X_PROBED; +#if defined(STB_X) + pScreenInfo->memPhysBase = sAdapterInfo.dwFrameBufferBase; +#else /* STB_X */ + pScreenInfo->memPhysBase = gfx_get_frame_buffer_base(); +#endif /* STB_X */ + } + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, + "Linear framebuffer at 0x%08lX\n", + (unsigned long)pScreenInfo->memPhysBase)); + + if (pGeode->pEnt->device->videoRam == 0) { + from = X_PROBED; + pScreenInfo->videoRam = pGeode->FBSize / 1024; + } else { + pScreenInfo->videoRam = pGeode->pEnt->device->videoRam; + from = X_CONFIG; + } + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, + "VideoRam: %d kByte\n", + (unsigned long)pScreenInfo->videoRam)); + + GeodeDebug(("GX1PreInit(7)!\n")); + + /* + * * xf86ValidateModes will check that the mode HTotal and VTotal values + * * don't exceed the chipset's limit if pScreenInfo->maxHValue adn + * * pScreenInfo->maxVValue are set. Since our GX1ValidMode() + * * already takes care of this, we don't worry about setting them here. + */ + /* Select valid modes from those available */ + /* + * * min pitch 1024, max 2048 (Pixel count) + * * min height 480, max 1024 (Pixel count) + */ + minPitch = 1024; + maxPitch = 2048; + minHeight = 480; + maxHeight = 1024; /* Can support upto 1280x1024 16Bpp */ + if (pScreenInfo->depth == 16) { + PitchInc = 2048; + } else { + PitchInc = 1024; + } + PitchInc <<= 3; /* in bits */ + + /* by default use what user sets in the XF86Config file */ + modes = pScreenInfo->display->modes; + if (pGeode->TVSupport == TRUE) { + char str[20]; + + sprintf(str, "%dx%d-%d", + pGeode->TvParam.wWidth, + pGeode->TvParam.wHeight, + ((pGeode->TvParam.wStandard == TV_STANDARD_PAL) ? 50 : 60)); + + tvmodes_defa = (char **)malloc(sizeof(char *) * 2); + tvmodes_defa[0] = (char *)malloc(strlen(str)); + tvmodes_defa[1] = NULL; + strcpy(str, tvmodes_defa[0]); + + modes = tvmodes_defa; + } + + i = xf86ValidateModes(pScreenInfo, + pScreenInfo->monitor->Modes, + modes, + &GeodeClockRange, + NULL, minPitch, maxPitch, + PitchInc, minHeight, maxHeight, + pScreenInfo->display->virtualX, + pScreenInfo->display->virtualY, +#if defined(STB_X) + sAdapterInfo.dwFrameBufferSize, +#else + pGeode->FBSize, +#endif /* STB_X */ + LOOKUP_BEST_REFRESH); + + DEBUGMSG(0, (pScreenInfo->scrnIndex, from, + "xf86ValidateModes: %d %d %d\n", + pScreenInfo->virtualX, + pScreenInfo->virtualY, pScreenInfo->displayWidth)); + if (i == -1) { + GX1FreeRec(pScreenInfo); + return FALSE; + } + GeodeDebug(("GX1PreInit(8)!\n")); + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScreenInfo); + GeodeDebug(("GX1PreInit(9)!\n")); + if (i == 0 || pScreenInfo->modes == NULL) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "No valid modes found\n")); + GX1FreeRec(pScreenInfo); + return FALSE; + } + GeodeDebug(("GX1PreInit(10)!\n")); + xf86SetCrtcForModes(pScreenInfo, 0); + GeodeDebug(("GX1PreInit(11)!\n")); + /* Set the current mode to the first in the list */ + pScreenInfo->currentMode = pScreenInfo->modes; + GeodeDebug(("GX1PreInit(12)!\n")); + /* Print the list of modes being used */ + xf86PrintModes(pScreenInfo); + GeodeDebug(("GX1PreInit(13)!\n")); + /* Set the display resolution */ + xf86SetDpi(pScreenInfo, 0, 0); + GeodeDebug(("GX1PreInit(14)!\n")); + /* Load bpp-specific modules */ + mod = NULL; + +#if CFB + /* Load bpp-specific modules */ + switch (pScreenInfo->bitsPerPixel) { + case 8: + mod = "cfb"; + reqSymbol = "cfbScreenInit"; + break; + case 16: + mod = "cfb16"; + reqSymbol = "cfb16ScreenInit"; + break; + default: + return FALSE; + } + if (mod && xf86LoadSubModule(pScreenInfo, mod) == NULL) { + GX1FreeRec(pScreenInfo); + return FALSE; + } + + xf86LoaderReqSymbols(reqSymbol, NULL); +#else + if (xf86LoadSubModule(pScreenInfo, "fb") == NULL) { + GX1FreeRec(pScreenInfo); + return FALSE; + } + + xf86LoaderReqSymLists(nscFbSymbols, NULL); +#endif + GeodeDebug(("GX1PreInit(15)!\n")); + if (pGeode->NoAccel == FALSE) { + if (!xf86LoadSubModule(pScreenInfo, "xaa")) { + GX1FreeRec(pScreenInfo); + return FALSE; + } + xf86LoaderReqSymLists(nscXaaSymbols, NULL); + } + GeodeDebug(("GX1PreInit(16)!\n")); + if (pGeode->HWCursor == TRUE) { + if (!xf86LoadSubModule(pScreenInfo, "ramdac")) { + GX1FreeRec(pScreenInfo); + return FALSE; + } + xf86LoaderReqSymLists(nscRamdacSymbols, NULL); + } + GeodeDebug(("GX1PreInit(17)!\n")); + /* Load shadowfb if needed */ + if (pGeode->ShadowFB) { + if (!xf86LoadSubModule(pScreenInfo, "shadowfb")) { + GX1FreeRec(pScreenInfo); + return FALSE; + } + xf86LoaderReqSymLists(nscShadowSymbols, NULL); + } + GeodeDebug(("GX2PreInit(18)!\n")); + if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "xf86RegisterResources() found resource conflicts\n")); + GX1FreeRec(pScreenInfo); + return FALSE; + } + GX1UnmapMem(pScreenInfo); + GeodeDebug(("GX1PreInit(19)!\n")); + GeodeDebug(("GX1PreInit(20)!\n")); + GeodeDebug(("GX1PreInit ... done successfully!\n")); + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX1RestoreEx. + * + * Description :This function restores the mode that was saved on server + entry + * Parameters. + * pScreenInfo :Handle to ScreenPtr structure. + * Pmode :poits to screen mode + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static void +GX1RestoreEx(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode) +{ + GeodePtr pGeode; + + GeodeDebug(("GX1RestoreEx!\n")); + /* Get driver private structure */ + if (!(pGeode = GX1GetRec(pScreenInfo))) + return; + /* Restore the extended registers */ +#if defined(STB_X) + pGeode->FBgfxVgaRegs.dwFlags = GFX_VGA_FLAG_MISC_OUTPUT | + GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC; + Gal_vga_restore(&(pGeode->FBgfxVgaRegs)); +#else + gfx_vga_restore(&(pGeode->FBgfxVgaRegs), + GFX_VGA_FLAG_MISC_OUTPUT | + GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC); +#endif /* STB_X */ +} + +/*---------------------------------------------------------------------------- + * GX1CalculatePitchBytes. + * + * Description :This function restores the mode that was saved on server + * + * Parameters. + * pScreenInfo :Handle to ScreenPtr structure. + * Pmode :Points to screenmode + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static int +GX1CalculatePitchBytes(unsigned int width, unsigned int bpp) +{ + int lineDelta = width * (bpp >> 3); + + if (width < 640) { + /* low resolutions have both pixel and line doubling */ + DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n", + width, lineDelta)); + lineDelta <<= 1; + } + /* needed in Rotate mode when in accel is turned off */ + if (1) { /*!pGeode->NoAccel */ + if (lineDelta > 2048) + lineDelta = 4096; + else if (lineDelta > 1024) + lineDelta = 2048; + else + lineDelta = 1024; + } + + DEBUGMSG(1, (0, X_PROBED, "pitch %d %d\n", width, lineDelta)); + + return lineDelta; +} + +/*---------------------------------------------------------------------------- + * GX1GetRefreshRate. + * + * Description :This function restores the mode that saved on server + * + * Parameters. + * Pmode :Pointer to the screen modes + * + * Returns :It returns the selected refresh rate. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static int +GX1GetRefreshRate(DisplayModePtr pMode) +{ +#define THRESHOLD 2 + unsigned int i; + static int validRates[] = { 50, 56, 60, 70, 72, 75, 85 }; /* Hz */ + unsigned long dotClock; + int refreshRate; + int selectedRate; + + dotClock = pMode->SynthClock * 1000; + refreshRate = dotClock / pMode->CrtcHTotal / pMode->CrtcVTotal; + + if ((pMode->CrtcHTotal < 640) && (pMode->CrtcVTotal < 480)) + refreshRate >>= 2; /* double pixel and double scan */ + + DEBUGMSG(1, (0, X_PROBED, "dotclock %d %d\n", dotClock, refreshRate)); + + selectedRate = validRates[0]; + for (i = 0; i < (sizeof(validRates) / sizeof(validRates[0])); i++) { + if (validRates[i] < (refreshRate + THRESHOLD)) { + selectedRate = validRates[i]; + } + } + return selectedRate; +} + +void +gx1_clear_screen(int width, int height) +{ + /* clean up the frame buffer memory */ + GFX(set_solid_pattern(0)); + GFX(set_raster_operation(0xF0)); + GFX(pattern_fill(0, 0, width, height)); +} + +/*---------------------------------------------------------------------------- + * GX1SetMode. + * + * Description :This function sets parametrs for screen mode + * + * Parameters. + * pScreenInfo :Pointer to the screenInfo structure. + * Pmode :Pointer to the screen modes + * + * Returns :TRUE on success and FALSE on Failure. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ + +static Bool +GX1SetMode(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode) +{ + GeodePtr pGeode; + + /* unsigned int compOffset, compPitch, compSize; */ + GeodeDebug(("GX1SetMode!\n")); + pGeode = GEODEPTR(pScreenInfo); + /* Set the VT semaphore */ + pScreenInfo->vtSema = TRUE; + DEBUGMSG(1, (0, X_NONE, "Set mode")); + /* The timing will be adjusted later */ + GeodeDebug(("Set display mode: %dx%d-%d (%dHz)\n", + pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, GX1GetRefreshRate(pMode))); + GeodeDebug(("Before setting the mode\n")); + if ((pMode->CrtcHDisplay >= 640) && (pMode->CrtcVDisplay >= 480)) + + GFX(set_display_bpp(pScreenInfo->bitsPerPixel)); + + if (pGeode->TVSupport == TRUE) { + pGeode->TvParam.bState = 1; /* enable */ + /* wWidth and wHeight already set in init. */ +#if defined(STB_X) + Gal_tv_set_params(GAL_TVSTATE | GAL_TVOUTPUT | + GAL_TVFORMAT | GAL_TVRESOLUTION, &(pGeode->TvParam)); +#else + /* sequence might be important */ + gfx_set_tv_display(pGeode->TvParam.wWidth, pGeode->TvParam.wHeight); + gfx_set_tv_format(pGeode->TvParam.wStandard, pGeode->TvParam.wType); + gfx_set_tv_output(pGeode->TvParam.wOutput); + gfx_set_tv_enable(pGeode->TvParam.bState); + +#endif /* STB_X */ + } else { /* TV not selected */ + + DEBUGMSG(0, (0, X_PROBED, "Setting Display for CRT or TFT\n")); + + if (pGeode->Panel) { + DEBUGMSG(0, (0, X_PROBED, "Setting Display for TFT\n")); + DEBUGMSG(1, (0, X_PROBED, "Restore Panel %d %d %d %d %d\n", + pGeode->FPBX, pGeode->FPBY, + pMode->CrtcHDisplay, + pMode->CrtcVDisplay, pScreenInfo->bitsPerPixel)); + + GFX(set_fixed_timings(pGeode->FPBX, pGeode->FPBY, + pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel)); + } else { + /* display is crt */ + DEBUGMSG(0, (0, X_PROBED, "Setting Display for CRT\n")); + GFX(set_display_mode(pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, + GX1GetRefreshRate(pMode))); + + /* adjust the pitch */ + GFX(set_display_pitch(pGeode->Pitch)); + + } + /* enable crt */ + GFX(set_crt_enable(CRT_ENABLE)); + } + + GFX(set_display_offset(0L)); + GFX(wait_vertical_blank()); + + /* enable compression if option selected */ + if (pGeode->Compression) { + /* set the compression parameters,and it will be turned on later. */ +#if defined(STB_X) + Gal_set_compression_parameters(GAL_COMPRESSION_ALL, + pGeode->CBOffset, + pGeode->CBPitch, pGeode->CBSize); + + /* set the compression buffer, all parameters already set */ + Gal_set_compression_enable(GAL_COMPRESSION_ENABLE); +#else + gfx_set_compression_offset(pGeode->CBOffset); + gfx_set_compression_pitch(pGeode->CBPitch); + gfx_set_compression_size(pGeode->CBSize); + + /* set the compression buffer, all parameters already set */ + gfx_set_compression_enable(1); +#endif /* STB_X */ + + } + if (pGeode->HWCursor) { + /* Load blank cursor */ + GX1LoadCursorImage(pScreenInfo, NULL); + GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); + GFX(set_cursor_enable(1)); + } else { + GeodeDebug(("GX1RestoreEx ... ")); + GX1RestoreEx(pScreenInfo, pMode); + GeodeDebug(("done.\n")); + } + + GeodeDebug(("done.\n")); + /* Reenable the hardware cursor after the mode switch */ + if (pGeode->HWCursor == TRUE) { + GeodeDebug(("GX1ShowCursor ... ")); + GX1ShowCursor(pScreenInfo); + GeodeDebug(("done.\n")); + } + /* Restore the contents in the screen info */ + GeodeDebug(("After setting the mode\n")); + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX1EnterGraphics. + * + * Description :This function will intiallize the displaytiming + structure for nextmode and switch to VGA mode. + * + * Parameters. + * pScreen :Screen information will be stored in this structure. + * pScreenInfo :Pointer to the screenInfo structure. + * + * Returns :TRUE on success and FALSE on Failure. + * + * Comments :gfx_vga_mode_switch() will start and end the + * switching based on the arguments 0 or 1.soft_vga + * is disabled in this function. +*---------------------------------------------------------------------------- +*/ +static Bool +GX1EnterGraphics(ScreenPtr pScreen, ScrnInfoPtr pScreenInfo) +{ + GeodePtr pGeode; + +#if !defined(STB_X) + + vgaHWPtr hwp = VGAHWPTR(pScreenInfo); + + vgaHWUnlock(hwp); +#endif + + GeodeDebug(("GX1EnterGraphics!\n")); + + DEBUGMSG(1, (0, X_NONE, "EnterGraphics\n")); + /* Should we re-save the text mode on each VT enter? */ + pGeode = GX1GetRec(pScreenInfo); +#if 0 + print_gxm_gfx_reg(pGeode, 0x4C); + print_gxm_vga_reg(); +#endif + /* This routine saves the current VGA state in Durango VGA structure */ +#if defined(STB_X) + Gal_get_softvga_state(&pGeode->FBVGAActive); + pGeode->FBgfxVgaRegs.dwFlags = GFX_VGA_FLAG_MISC_OUTPUT | + GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC; + Gal_vga_save(&(pGeode->FBgfxVgaRegs)); +#else + pGeode->FBVGAActive = gfx_get_softvga_active(); + gfx_vga_save(&(pGeode->FBgfxVgaRegs), + GFX_VGA_FLAG_MISC_OUTPUT | + GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC); +#endif /* STB_X */ + DEBUGMSG(1, (0, X_PROBED, "VSA = %d\n", pGeode->FBVGAActive)); + +#if !defined(STB_X) + + vgaHWSave(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL); +#endif + +#if defined(STB_X) + Gal_get_display_timing(&pGeode->FBgfxdisplaytiming); + Gal_tv_get_timings(0, &pGeode->FBgfxtvtiming); + + /* Save Display offset */ + Gal_get_display_offset(&(pGeode->FBDisplayOffset)); + + /* Save the current Compression state */ + Gal_get_compression_enable(&(pGeode->FBCompressionEnable)); + Gal_get_compression_parameters(GAL_COMPRESSION_ALL, + &(pGeode->FBCompressionOffset), + &(pGeode->FBCompressionPitch), + &(pGeode->FBCompressionSize)); + + /* Save Cursor offset */ + { + unsigned short x, y, xhot, yhot; + + Gal_get_cursor_position(&(pGeode->FBCursorOffset), + &x, &y, &xhot, &yhot); + } + /* Save the Panel state */ + Gal_pnl_save(); + + /* its time to put softvga to sleep */ + Gal_set_softvga_state(FALSE); + Gal_vga_mode_switch(1); + +#else + /* Save TV State */ + gfx_get_tv_enable(&(pGeode->FBTVEnabled)); + if (pGeode->FBTVEnabled) { + /* TV Format */ + pGeode->FBtvtiming.HorzTim = READ_VID32(SC1200_TVOUT_HORZ_TIM); + pGeode->FBtvtiming.HorzSync = READ_VID32(SC1200_TVOUT_HORZ_SYNC); + pGeode->FBtvtiming.VertSync = READ_VID32(SC1200_TVOUT_VERT_SYNC); + pGeode->FBtvtiming.LineEnd = READ_VID32(SC1200_TVOUT_LINE_END); + pGeode->FBtvtiming.VertDownscale = + READ_VID32(SC1200_TVOUT_VERT_DOWNSCALE); + pGeode->FBtvtiming.HorzScaling = READ_VID32(SC1200_TVOUT_HORZ_SCALING); + pGeode->FBtvtiming.TimCtrl1 = READ_VID32(SC1200_TVENC_TIM_CTRL_1); + pGeode->FBtvtiming.TimCtrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2); + pGeode->FBtvtiming.Subfreq = READ_VID32(SC1200_TVENC_SUB_FREQ); + pGeode->FBtvtiming.DispPos = READ_VID32(SC1200_TVENC_DISP_POS); + pGeode->FBtvtiming.DispSize = READ_VID32(SC1200_TVENC_DISP_SIZE); + /* TV Output */ + pGeode->FBtvtiming.TimCtrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2); + pGeode->FBtvtiming.Debug = READ_VID32(SC1200_TVOUT_DEBUG); + /* TV Enable */ + pGeode->FBtvtiming.DacCtrl = READ_VID32(SC1200_TVENC_DAC_CONTROL); + } + + /* Save CRT State */ + pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); + pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); + pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); + pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); + pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); + pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); + pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); + pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); + pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); + pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); + pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); + pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); + pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); + pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); + pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); + pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); + + /* Save Display offset */ + pGeode->FBDisplayOffset = gfx_get_display_offset(); + + /* Save the current Compression state */ + pGeode->FBCompressionEnable = gfx_get_compression_enable(); + pGeode->FBCompressionOffset = gfx_get_compression_offset(); + pGeode->FBCompressionPitch = gfx_get_compression_pitch(); + pGeode->FBCompressionSize = gfx_get_compression_size(); + + /* Save Cursor offset */ + pGeode->FBCursorOffset = gfx_get_cursor_offset(); + + /* Save the Panel state */ + Pnl_SavePanelState(); + + /* its time to put softvga to sleep */ + gfx_disable_softvga(); + gfx_vga_mode_switch(1); + +#endif /* STB_X */ + + if (!GX1SetMode(pScreenInfo, pScreenInfo->currentMode)) { + return FALSE; + } +#if 1 + /* clear the frame buffer, for annoying noise during mode switch */ + gx1_clear_screen(pScreenInfo->currentMode->CrtcHDisplay, + pScreenInfo->currentMode->CrtcVDisplay); +#endif + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX1LeaveGraphics: + * + * Description :This function will restore the displaymode parameters + * and switches the VGA mode + * + * Parameters. + * pScreen :Screen information will be stored in this structure. + * pScreenInfo :Pointer to the screenInfo structure. + * + * + * Returns :none. + * + * Comments : gfx_vga_mode_switch() will start and end the switching + * based on the arguments 0 or 1.soft_vga is disabled in + * this function. +*---------------------------------------------------------------------------- +*/ +static void +GX1LeaveGraphics(ScrnInfoPtr pScreenInfo) +{ + GeodePtr pGeode; + + GeodeDebug(("GX1LeaveGraphics!\n")); + pGeode = GEODEPTR(pScreenInfo); + + if (!pGeode->FBTVActive) { + GFX(set_tv_enable(0)); + } + /* clear the frame buffer, when leaving X */ + gx1_clear_screen(pScreenInfo->virtualX, pScreenInfo->virtualY); + +#if defined(STB_X) + Gal_set_display_timing(&pGeode->FBgfxdisplaytiming); + Gal_tv_set_timings(0, &pGeode->FBgfxtvtiming); + Gal_set_display_offset(pGeode->FBDisplayOffset); + + /* Restore Cursor */ + Gal_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); + + /* Restore the previous Compression state */ + if (pGeode->FBCompressionEnable) { + Gal_set_compression_parameters(GAL_COMPRESSION_ALL, + pGeode->FBCompressionOffset, + pGeode->FBCompressionPitch, + pGeode->FBCompressionSize); + + Gal_set_compression_enable(GAL_COMPRESSION_ENABLE); + } +#else + /* Restore TV */ + if (pGeode->FBTVEnabled) { + /* TV Format */ + WRITE_VID32(SC1200_TVOUT_HORZ_TIM, pGeode->FBtvtiming.HorzTim); + WRITE_VID32(SC1200_TVOUT_HORZ_SYNC, pGeode->FBtvtiming.HorzSync); + WRITE_VID32(SC1200_TVOUT_VERT_SYNC, pGeode->FBtvtiming.VertSync); + WRITE_VID32(SC1200_TVOUT_LINE_END, pGeode->FBtvtiming.LineEnd); + WRITE_VID32(SC1200_TVOUT_VERT_DOWNSCALE, + pGeode->FBtvtiming.VertDownscale); + WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, pGeode->FBtvtiming.HorzScaling); + WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, pGeode->FBtvtiming.TimCtrl1); + WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, pGeode->FBtvtiming.TimCtrl2); + WRITE_VID32(SC1200_TVENC_SUB_FREQ, pGeode->FBtvtiming.Subfreq); + WRITE_VID32(SC1200_TVENC_DISP_POS, pGeode->FBtvtiming.DispPos); + WRITE_VID32(SC1200_TVENC_DISP_SIZE, pGeode->FBtvtiming.DispSize); + /* TV Output */ + WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, pGeode->FBtvtiming.TimCtrl2); + /* WRITE_VID32(SC1200_TVENC_DAC_CONTROL, tmp); */ + WRITE_VID32(SC1200_TVOUT_DEBUG, pGeode->FBtvtiming.Debug); + /* TV Enable */ + WRITE_VID32(SC1200_TVENC_DAC_CONTROL, pGeode->FBtvtiming.DacCtrl); + } + + /* Restore CRT */ + gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, + pGeode->FBgfxdisplaytiming.wPolarity, + pGeode->FBgfxdisplaytiming.wHActive, + pGeode->FBgfxdisplaytiming.wHBlankStart, + pGeode->FBgfxdisplaytiming.wHSyncStart, + pGeode->FBgfxdisplaytiming.wHSyncEnd, + pGeode->FBgfxdisplaytiming.wHBlankEnd, + pGeode->FBgfxdisplaytiming.wHTotal, + pGeode->FBgfxdisplaytiming.wVActive, + pGeode->FBgfxdisplaytiming.wVBlankStart, + pGeode->FBgfxdisplaytiming.wVSyncStart, + pGeode->FBgfxdisplaytiming.wVSyncEnd, + pGeode->FBgfxdisplaytiming.wVBlankEnd, + pGeode->FBgfxdisplaytiming.wVTotal, + pGeode->FBgfxdisplaytiming.dwDotClock); + + gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); + + gfx_set_display_offset(pGeode->FBDisplayOffset); + + /* Restore Cursor */ + gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); + + /* Restore the previous Compression state */ + if (pGeode->FBCompressionEnable) { + gfx_set_compression_offset(pGeode->FBCompressionOffset); + gfx_set_compression_pitch(pGeode->FBCompressionPitch); + gfx_set_compression_size(pGeode->FBCompressionSize); + gfx_set_compression_enable(1); + } +#endif /* STB_X */ + + /* We need this to get back to vga mode when soft-vga + * * kicks in. + * * We actually need to examine the attribute Ctlr to find out + * * what kinda crap (grafix or text) we need to enter in + * * For now just lookout for 720x400 + */ +#if 0 + if ((pGeode->FBgfxdisplaytiming.wHActive == 720) && + (pGeode->FBgfxdisplaytiming.wVActive == 400)) +#else + if (pGeode->FBVGAActive) +#endif + { + /* VSA was active before we started. Since we disabled it + * we got to enable it */ +#if defined(STB_X) + Gal_set_softvga_state(TRUE); + Gal_vga_mode_switch(1); + Gal_vga_clear_extended(); +#else + gfx_enable_softvga(); + gfx_vga_mode_switch(1); + gfx_vga_clear_extended(); +#endif /* STB_X */ + +#if !defined(STB_X) + + vgaHWRestore(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL); +#endif + +#if defined(STB_X) + pGeode->FBgfxVgaRegs.dwFlags = GFX_VGA_FLAG_MISC_OUTPUT | + GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC; + Gal_vga_restore(&(pGeode->FBgfxVgaRegs)); + Gal_vga_mode_switch(0); +#else + gfx_vga_restore(&(pGeode->FBgfxVgaRegs), + GFX_VGA_FLAG_MISC_OUTPUT | + GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC); + gfx_vga_mode_switch(0); +#endif /* STB_X */ + } +#if 0 + print_gxm_gfx_reg(pGeode, 0x4C); + print_gxm_vga_reg(); +#endif +} + +/*---------------------------------------------------------------------------- + * GX1CloseScreen. + * + * Description :This function will restore the original mode + * and also it unmap video memory + * + * Parameters. + * ScrnIndex :Screen index value of the screen will be closed. + * pScreen :Pointer to the screen structure. + * + * + * Returns :TRUE on success and FALSE on Failure. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static Bool +GX1CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + DEBUGMSG(1, (scrnIndex, X_PROBED, "GX1CloseScreen\n")); + GeodeDebug(("GX1CloseScreen!\n")); + GX1LeaveGraphics(pScreenInfo); + if (pGeode->AccelInfoRec) + XAADestroyInfoRec(pGeode->AccelInfoRec); + pScreenInfo->vtSema = FALSE; + if (pGeode->DGAModes) + xfree(pGeode->DGAModes); + pGeode->DGAModes = 0; + if (pGeode->ShadowPtr) + xfree(pGeode->ShadowPtr); + + if (pGeode->AccelImageWriteBufferOffsets) { + xfree(pGeode->AccelImageWriteBufferOffsets); + pGeode->AccelImageWriteBufferOffsets = 0x0; + } + /* free the allocated off screen area */ + xf86FreeOffscreenArea(pGeode->AccelImgArea); + xf86FreeOffscreenArea(pGeode->CompressionArea); + + GX1UnmapMem(pScreenInfo); + + pScreen->CloseScreen = pGeode->CloseScreen; + return (*pScreen->CloseScreen) (scrnIndex, pScreen); + +} + +#ifdef DPMSExtension +/*---------------------------------------------------------------------------- + * GX1DPMSet. + * + * Description :This function sets geode into Power Management + * Signalling mode. + * + * Parameters. + * pScreenInfo :Pointer to screen info strucrure. + * mode :Specifies the power management mode. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static void +GX1DPMSSet(ScrnInfoPtr pScreenInfo, int mode, int flags) +{ + GeodePtr pGeode; + + pGeode = GEODEPTR(pScreenInfo); + + GeodeDebug(("GX1DPMSSet!\n")); + + /* Check if we are actively controlling the display */ + if (!pScreenInfo->vtSema) { + ErrorF("GX1DPMSSet called when we not controlling the VT!\n"); + return; + } + switch (mode) { + case DPMSModeOn: + /* Screen: On; HSync: On; VSync: On */ + GFX(set_crt_enable(CRT_ENABLE)); +#if defined(STB_X) + if (pGeode->Panel) + Gal_pnl_powerup(); +#else + if (pGeode->Panel) + Pnl_PowerUp(); +#endif /* STB_X */ + if (pGeode->TVSupport) + GFX(set_tv_enable(1)); + break; + + case DPMSModeStandby: + /* Screen: Off; HSync: Off; VSync: On */ + GFX(set_crt_enable(CRT_STANDBY)); +#if defined(STB_X) + if (pGeode->Panel) + Gal_pnl_powerdown(); +#else + if (pGeode->Panel) + Pnl_PowerDown(); +#endif /* STB_X */ + if (pGeode->TVSupport) + GFX(set_tv_enable(0)); + break; + + case DPMSModeSuspend: + /* Screen: Off; HSync: On; VSync: Off */ + GFX(set_crt_enable(CRT_SUSPEND)); +#if defined(STB_X) + if (pGeode->Panel) + Gal_pnl_powerdown(); +#else + if (pGeode->Panel) + Pnl_PowerDown(); +#endif /* STB_X */ + if (pGeode->TVSupport) + GFX(set_tv_enable(0)); + break; + case DPMSModeOff: + /* Screen: Off; HSync: Off; VSync: Off */ + GFX(set_crt_enable(CRT_DISABLE)); +#if defined(STB_X) + if (pGeode->Panel) + Gal_pnl_powerdown(); +#else + if (pGeode->Panel) + Pnl_PowerDown(); +#endif /* STB_X */ + if (pGeode->TVSupport) + GFX(set_tv_enable(0)); + break; + } +} +#endif + +/*---------------------------------------------------------------------------- + * GX1ScreenInit. + * + * Description :This function will be called at the each ofserver + * generation. + * + * Parameters. + * scrnIndex :Specfies the screenindex value during generation. + * pScreen :Pointer to screen info strucrure. + * argc :parameters for command line arguments count + * argv :command line arguments if any it is not used. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static Bool +GX1ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + GeodePtr pGeode; + int i; + Bool Inited = FALSE; + unsigned char *FBStart; + unsigned int req_offscreenmem; + int width, height, displayWidth; + VisualPtr visual; + BoxRec AvailBox; + RegionRec OffscreenRegion; + + DCount = 30; + + GeodeDebug(("GX1ScreenInit!\n")); + /* Get driver private */ + pGeode = GX1GetRec(pScreenInfo); + GeodeDebug(("GX1ScreenInit(0)!\n")); + +#if !defined(STB_X) + /* + * * Allocate a vgaHWRec + */ + if (!vgaHWGetHWRec(pScreenInfo)) + return FALSE; + VGAHWPTR(pScreenInfo)->MapSize = 0x10000; /* Standard 64k VGA window */ + if (!vgaHWMapMem(pScreenInfo)) + return FALSE; +#endif + + if (!GX1MapMem(pScreenInfo)) + return FALSE; + +#if !defined(STB_X) + vgaHWGetIOBase(VGAHWPTR(pScreenInfo)); +#endif + + pGeode->Pitch = GX1CalculatePitchBytes(pScreenInfo->virtualX, + pScreenInfo->bitsPerPixel); + + /* find the index to our operating mode the offsets are located */ + for (i = 0; i < (int)((sizeof(GeodeMemOffset) / sizeof(MemOffset))); i++) { + if ((pScreenInfo->virtualX == (int)GeodeMemOffset[i].xres) && + (pScreenInfo->virtualY == (int)GeodeMemOffset[i].yres) && + (pScreenInfo->bitsPerPixel == (int)GeodeMemOffset[i].bpp)) { + MemIndex = i; + break; + } + } + if (MemIndex == -1) /* no match */ + return FALSE; + + /* SET UP GRAPHICS MEMORY AVAILABLE FOR PIXMAP CACHE */ + AvailBox.x1 = 0; + AvailBox.y1 = pScreenInfo->virtualY; + AvailBox.x2 = pScreenInfo->displayWidth; + AvailBox.y2 = (pGeode->FBSize / pGeode->Pitch); + + pGeode->CursorSize = 8 * 32; /* 32 DWORDS */ + + if (pGeode->HWCursor) { + /* Compute cursor buffer */ + /* Default cursor offset, end of the frame buffer */ + pGeode->CursorStartOffset = pGeode->FBSize - pGeode->CursorSize; + AvailBox.y2 -= 1; + } + + DEBUGMSG(1, (scrnIndex, X_PROBED, + "Memory manager initialized to (%d,%d) (%d,%d) %d %d\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2, + pGeode->Pitch, pScreenInfo->displayWidth)); + /* set the offscreen offset accordingly */ + if (pGeode->Compression) { + + pGeode->CBOffset = GeodeMemOffset[MemIndex].CBOffset; + pGeode->CBSize = GeodeMemOffset[MemIndex].CBSize - 16; + pGeode->CBPitch = GeodeMemOffset[MemIndex].CBPitch; + + if ((pScreenInfo->virtualX == 1024) && (pScreenInfo->virtualY == 768)) { + req_offscreenmem = pScreenInfo->virtualY * pGeode->CBPitch; + req_offscreenmem += pGeode->Pitch - 1; + req_offscreenmem /= pGeode->Pitch; + pGeode->CBOffset = AvailBox.y1 * pGeode->Pitch; + AvailBox.y1 += req_offscreenmem; + } + } + DEBUGMSG(1, (scrnIndex, X_PROBED, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2)); + + if (!pGeode->NoAccel) { + if (pGeode->NoOfImgBuffers > 0) { + if (pGeode->NoOfImgBuffers <= (AvailBox.y2 - AvailBox.y1)) { + pGeode->AccelImageWriteBufferOffsets = + xalloc(sizeof(unsigned long) * pGeode->NoOfImgBuffers); + + pGeode->AccelImageWriteBufferOffsets[0] = + ((unsigned char *)pGeode->FBBase) + + (AvailBox.y1 * pGeode->Pitch); + + for (i = 1; i < pGeode->NoOfImgBuffers; i++) { + pGeode->AccelImageWriteBufferOffsets[i] = + pGeode->AccelImageWriteBufferOffsets[i - 1] + + pGeode->Pitch; + } + + for (i = 0; i < pGeode->NoOfImgBuffers; i++) { + DEBUGMSG(1, (scrnIndex, X_PROBED, + "memory %d %x\n", i, + pGeode->AccelImageWriteBufferOffsets[i])); + } + AvailBox.y1 += pGeode->NoOfImgBuffers; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Unable to reserve scanline area\n"); + } + } + DEBUGMSG(1, (scrnIndex, X_PROBED, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2)); + + REGION_INIT(pScreen, &OffscreenRegion, &AvailBox, 2); + + if (!xf86InitFBManagerRegion(pScreen, &OffscreenRegion)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); + } else { + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); + } + REGION_UNINIT(pScreen, &OffscreenRegion); + } + + /* Initialise graphics mode */ + if (!GX1EnterGraphics(pScreen, pScreenInfo)) + return FALSE; + + GX1AdjustFrame(scrnIndex, pScreenInfo->frameX0, pScreenInfo->frameY0, 0); + GeodeDebug(("GX1ScreenInit(1)!\n")); + + /* Reset visual list */ + miClearVisualTypes(); + GeodeDebug(("GX1ScreenInit(2)!\n")); + + /* Setup the visual we support */ + if (pScreenInfo->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScreenInfo->depth, + TrueColorMask, + pScreenInfo->rgbBits, + pScreenInfo->defaultVisual)) { + return FALSE; + } + } else { + if (!miSetVisualTypes(pScreenInfo->depth, + miGetDefaultVisualMask(pScreenInfo->depth), + pScreenInfo->rgbBits, + pScreenInfo->defaultVisual)) { + return FALSE; + } + } + GeodeDebug(("GX1ScreenInit(3)!\n")); + /* Set this for RENDER extension */ + miSetPixmapDepths(); + /* Call the framebuffer layer's ScreenInit function, and fill in other + * * pScreen fields. + */ + + if (pGeode->TV_Overscan_On) { + width = pGeode->TVOw; + height = pGeode->TVOh; + GeodeDebug(("width : %d , height : %d", width, height)); + } else { + width = pScreenInfo->virtualX; + height = pScreenInfo->virtualY; + } + + displayWidth = pScreenInfo->displayWidth; + if (pGeode->Rotate) { + if (pGeode->TV_Overscan_On) { + width = pGeode->TVOh; + height = pGeode->TVOw; + } else { + width = pScreenInfo->virtualY; + height = pScreenInfo->virtualX; + } + } + if (pGeode->ShadowFB) { + pGeode->ShadowPitch = BitmapBytePad(pScreenInfo->bitsPerPixel * width); + pGeode->ShadowPtr = xalloc(pGeode->ShadowPitch * height); + displayWidth = pGeode->ShadowPitch / (pScreenInfo->bitsPerPixel >> 3); + FBStart = pGeode->ShadowPtr; + } else { + pGeode->ShadowPtr = NULL; + + if (pGeode->TV_Overscan_On) { + GeodeDebug(("pGeode->Pitch (%d)!\n", pGeode->Pitch)); + FBStart = pGeode->FBBase + (pGeode->Pitch * pGeode->TVOy) + + (pGeode->TVOx << ((pScreenInfo->depth >> 3) - 1)); + } else { + FBStart = pGeode->FBBase; + } + DEBUGMSG(1, (0, X_PROBED, "FBStart %X \n", FBStart)); + } + + /* Initialise the framebuffer */ + switch (pScreenInfo->bitsPerPixel) { +#if CFB + case 8: + Inited = cfbScreenInit(pScreen, FBStart, width, height, + pScreenInfo->xDpi, pScreenInfo->yDpi, + displayWidth); + break; + case 16: + Inited = cfb16ScreenInit(pScreen, FBStart, width, height, + pScreenInfo->xDpi, pScreenInfo->yDpi, + displayWidth); + break; + +#else + case 8: + case 16: + Inited = fbScreenInit(pScreen, FBStart, width, height, + pScreenInfo->xDpi, pScreenInfo->yDpi, + displayWidth, pScreenInfo->bitsPerPixel); + break; +#endif + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in ScreenInit\n", + pScreenInfo->bitsPerPixel); + Inited = FALSE; + break; + } + if (!Inited) + return FALSE; + + GeodeDebug(("GX1ScreenInit(4)!\n")); + + xf86SetBlackWhitePixels(pScreen); + + if (!pGeode->ShadowFB && (!pGeode->TV_Overscan_On)) { + GX1DGAInit(pScreen); + } + GeodeDebug(("GX1ScreenInit(5)!\n")); + if (pScreenInfo->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScreenInfo->offset.red; + visual->offsetGreen = pScreenInfo->offset.green; + visual->offsetBlue = pScreenInfo->offset.blue; + visual->redMask = pScreenInfo->mask.red; + visual->greenMask = pScreenInfo->mask.green; + visual->blueMask = pScreenInfo->mask.blue; + } + } + } +#if CFB +#else + /* must be after RGB ordering fixed */ + fbPictureInit(pScreen, 0, 0); +#endif + + GeodeDebug(("GX1ScreenInit(6)!\n")); + if (!pGeode->NoAccel) { + GX1AccelInit(pScreen); + } + GeodeDebug(("GX1ScreenInit(7)!\n")); + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + GeodeDebug(("GX1ScreenInit(8)!\n")); + /* Initialise software cursor */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + /* Initialize HW cursor layer. + * * Must follow software cursor initialization + */ + if (pGeode->HWCursor) { + if (!GX1HWCursorInit(pScreen)) + xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + } + GeodeDebug(("GX1ScreenInit(9)!\n")); + + /* Setup default colourmap */ + if (!miCreateDefColormap(pScreen)) { + return FALSE; + } + + GeodeDebug(("GX1ScreenInit(10)!\n")); + /* Initialize colormap layer. + * * Must follow initialization of the default colormap + */ + if (!xf86HandleColormaps(pScreen, 256, 8, + GX1LoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | + CMAP_RELOAD_ON_MODE_SWITCH)) { + return FALSE; + } + GeodeDebug(("GX1ScreenInit(11)!\n")); + + if (pGeode->ShadowFB) { + RefreshAreaFuncPtr refreshArea = GX1RefreshArea; + + if (pGeode->Rotate) { + if (!pGeode->PointerMoved) { + pGeode->PointerMoved = pScreenInfo->PointerMoved; + pScreenInfo->PointerMoved = GX1PointerMoved; + } + switch (pScreenInfo->bitsPerPixel) { + case 8: + refreshArea = GX1RefreshArea8; + break; + case 16: + refreshArea = GX1RefreshArea16; + break; + } + } + ShadowFBInit(pScreen, refreshArea); + } +#ifdef DPMSExtension + xf86DPMSInit(pScreen, GX1DPMSSet, 0); +#endif + GeodeDebug(("GX1ScreenInit(12)!\n")); + + if (pGeode->TV_Overscan_On) { + GeodeDebug(("pGeode->Pitch (%d)!\n", pGeode->Pitch)); + + pScreenInfo->memPhysBase = (unsigned long)(pGeode->FBBase + + (pGeode->Pitch * + pGeode->TVOy) + + (pGeode-> + TVOx << + ((pScreenInfo->depth >> 3) - + 1))); + GeodeDebug(("->memPhysBase (%X)!\n", pScreenInfo->memPhysBase)); + } else { + pScreenInfo->memPhysBase = (unsigned long)pGeode->FBBase; + } + pScreenInfo->fbOffset = 0; + + GeodeDebug(("GX1ScreenInit(13)!\n")); + GX1InitVideo(pScreen); /* needed for video */ + /* Wrap the screen's CloseScreen vector and set its + * SaveScreen vector + */ + pGeode->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = GX1CloseScreen; + + pScreen->SaveScreen = GX1SaveScreen; + GeodeDebug(("GX1ScreenInit(14)!\n")); + /* Report any unused options */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options); + } + GeodeDebug(("GX2ScreenInit(15)!\n")); + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX1SwitchMode. + * + * Description :This function will switches the screen mode + * + * Parameters: + * scrnIndex :Specfies the screen index value. + * pMode :pointer to the mode structure. + * flags :may be used for status check?. + * + * Returns :Returns TRUE on success and FALSE on failure. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +Bool +GX1SwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) +{ + GeodeDebug(("GX1SwitchMode!\n")); + return GX1SetMode(xf86Screens[scrnIndex], pMode); +} + +/*---------------------------------------------------------------------------- + * GX1AdjustFrame. + * + * Description :This function is used to intiallize the start + * address of the memory. + * Parameters. + * scrnIndex :Specfies the screen index value. + * x :x co-ordinate value interms of pixels. + * y :y co-ordinate value interms of pixels. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +void +GX1AdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + GeodePtr pGeode; + unsigned long offset; + + pGeode = GX1GetRec(pScreenInfo); + offset = (unsigned long)y *(unsigned long)pGeode->Pitch; + + offset += x; + if (pScreenInfo->bitsPerPixel > 8) { + offset += x; + } + GFX(set_display_offset(offset)); +} + +/*---------------------------------------------------------------------------- + * GX1EnterVT. + * + * Description :This is called when VT switching back to the X server + * + * Parameters. + * scrnIndex :Specfies the screen index value. + * flags :Not used inside the function. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static Bool +GX1EnterVT(int scrnIndex, int flags) +{ + GeodeDebug(("GX1EnterVT!\n")); + return GX1EnterGraphics(NULL, xf86Screens[scrnIndex]); +} + +/*---------------------------------------------------------------------------- + * GX1LeaveVT. + * + * Description :This is called when VT switching X server text mode. + * + * Parameters. + * scrnIndex :Specfies the screen index value. + * flags :Not used inside the function. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static void +GX1LeaveVT(int scrnIndex, int flags) +{ + GeodeDebug(("GX1LeaveVT!\n")); + GX1LeaveGraphics(xf86Screens[scrnIndex]); +} + +/*---------------------------------------------------------------------------- + * GX1FreeScreen. + * + * Description :This is called to free any persistent data structures. + * + * Parameters. + * scrnIndex :Specfies the screen index value. + * flags :Not used inside the function. + * + * Returns :none. + * + * Comments :This will be called only when screen being deleted.. +*---------------------------------------------------------------------------- +*/ +static void +GX1FreeScreen(int scrnIndex, int flags) +{ + GeodeDebug(("GX1FreeScreen!\n")); +#if !defined(STB_X) + + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); +#endif + GX1FreeRec(xf86Screens[scrnIndex]); +} + +/*---------------------------------------------------------------------------- + * GX1ValidMode. + * + * Description :This function checks if a mode is suitable for selected + * chipset. + * Parameters. + * scrnIndex :Specfies the screen index value. + * pMode :Pointer to the screen mode structure.. + * verbose :not used for implementation. + * flags :not used for implementation + * + * Returns :MODE_OK if the specified mode is supported or + * MODE_NO_INTERLACE. + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static int +GX1ValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + unsigned int total_memory_required; + int ret = -1; + GeodePtr pGeode = GX1GetRec(pScreenInfo); + + DEBUGMSG(1, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n", + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, GX1GetRefreshRate(pMode))); + + if (pGeode->TVSupport == TRUE) { + if ((pGeode->TvParam.wWidth == pMode->CrtcHDisplay) && + (pGeode->TvParam.wHeight == pMode->CrtcVDisplay)) { + DEBUGMSG(1, (0, X_NONE, "TV mode\n")); + +#if defined(STB_X) + Gal_is_tv_mode_supported(0, &(pGeode->TvParam), &ret); +#else + ret = gfx_is_tv_display_mode_supported(pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pGeode->TvParam.wStandard); +#endif + } + } else { + DEBUGMSG(1, (0, X_NONE, "CRT mode\n")); + + if (pMode->Flags & V_INTERLACE) + return MODE_NO_INTERLACE; + +#if defined(STB_X) + Gal_is_display_mode_supported(pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, + GX1GetRefreshRate(pMode), &ret); +#else + ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, + GX1GetRefreshRate(pMode)); +#endif /* STB_X */ + } + + if (ret < 0) + return MODE_NOMODE; + + total_memory_required = GX1CalculatePitchBytes(pMode->CrtcHDisplay, + pScreenInfo->bitsPerPixel) * + pMode->CrtcVDisplay; + + DEBUGMSG(0, (0, X_NONE, "Total Mem %X %X", + total_memory_required, pGeode->FBSize)); + + if (total_memory_required > pGeode->FBSize) + return MODE_MEM; + + return MODE_OK; +} + +/*---------------------------------------------------------------------------- + * GX1LoadPalette. + * + * Description :This function sets the palette entry used for graphics data + * + * Parameters. + * pScreenInfo:Points the screeninfo structure. + * numColors:Specifies the no of colors it supported. + * indizes :This is used get index value . + * LOCO :to be added. + * pVisual :to be added. + * + * Returns :MODE_OK if the specified mode is supported or + * MODE_NO_INTERLACE. + * Comments :none. +*---------------------------------------------------------------------------- +*/ + +static void +GX1LoadPalette(ScrnInfoPtr pScreenInfo, + int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) +{ + int i, index, color; + + for (i = 0; i < numColors; i++) { + index = indizes[i] & 0xFF; + color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | + (((unsigned long)(colors[index].green & 0xFF)) << 8) | + ((unsigned long)(colors[index].blue & 0xFF)); + DEBUGMSG(0, (0, X_NONE, "GX1LoadPalette: %d %d %X\n", + numColors, index, color)); + + GFX(set_display_palette_entry(index, color)); + } +} + +static Bool +GX1MapMem(ScrnInfoPtr pScreenInfo) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + +#if defined(STB_X) + pGeode->FBBase = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_FRAMEBUFFER, + pGeode->FBLinearAddr, + pGeode->FBSize); + +#else + /* SET DURANGO REGISTER POINTERS + * * The method of mapping from a physical address to a linear address + * * is operating system independent. Set variables to linear address. + */ + gfx_virt_regptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_MMIO, + (unsigned int) + gfx_get_cpu_register_base + (), 0x9000); + gfx_virt_spptr = gfx_virt_regptr; + gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_MMIO, + (unsigned int) + gfx_get_vid_register_base + (), 0x1000); + pGeode->FBSize = GetVideoMemSize(); + gfx_virt_fbptr = + (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_FRAMEBUFFER, + pGeode->FBLinearAddr, pGeode->FBSize); + + /* CHECK IF REGISTERS WERE MAPPED SUCCESSFULLY */ + if ((!gfx_virt_regptr) || + (!gfx_virt_spptr) || (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) { + DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n")); + return (FALSE); + } + + /* Map the XpressROM ptr to read what platform are we on */ + XpressROMPtr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_FRAMEBUFFER, 0xF0000, + 0x10000); + + if (!XpressROMPtr) + return FALSE; + + pGeode->FBBase = gfx_virt_fbptr; +#endif + + return TRUE; +} + +/* + * Unmap the framebuffer and MMIO memory. + */ + +static Bool +GX1UnmapMem(ScrnInfoPtr pScreenInfo) +{ +#if !defined(STB_X) + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + /* unmap all the memory map's */ + xf86UnMapVidMem(pScreenInfo->scrnIndex, gfx_virt_regptr, 0x9000); + xf86UnMapVidMem(pScreenInfo->scrnIndex, gfx_virt_vidptr, 0x1000); + xf86UnMapVidMem(pScreenInfo->scrnIndex, gfx_virt_fbptr, pGeode->FBSize); + xf86UnMapVidMem(pScreenInfo->scrnIndex, XpressROMPtr, 0x10000); +#endif /* STB_X */ + + return TRUE; +} + +/* End of file */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_shadow.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_shadow.c new file mode 100644 index 000000000..a1ba41a0d --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_shadow.c @@ -0,0 +1,468 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_shadow.c,v 1.2 2003/01/14 09:34:32 alanh Exp $ */ +/* + * $Workfile: nsc_gx1_shadow.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: Direct graphics display routines are implemented and + * graphics rendering are all done in memory. + * + * Project: Geode Xfree Frame buffer device driver. + * + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "nsc.h" +#include "shadowfb.h" +#include "servermd.h" + +void GX1RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void GX1PointerMoved(int index, int x, int y); +void GX1RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void GX1RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void GX1RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void GX1RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + +/*---------------------------------------------------------------------------- + * GX1RefreshArea. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer. + * Parameters. + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns :none + * + * Comments : none + * +*---------------------------------------------------------------------------- +*/ +void +GX1RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + while (num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pGeode->ShadowPtr + (pbox->y1 * pGeode->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pGeode->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + while (height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pGeode->ShadowPitch; + } + + pbox++; + } +} + +/*---------------------------------------------------------------------------- + * GX1PointerMoved. + * + * Description :This function moves one screen memory from one area to other. + * + * Parameters. + * index :Pointer to screen index. + * x :Specifies the new x co-ordinates of new area. + * y :Specifies the new y co-ordinates of new area. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX1PointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + GeodePtr pGeode = GEODEPTR(pScrn); + int newX, newY; + + if (pGeode->Rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + } + (*pGeode->PointerMoved) (index, newX, newY); +} + +/*---------------------------------------------------------------------------- + * GX1RefreshArea8. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 8bpp. + * Parameters. + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX1RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2, + srcPitch3, srcPitch4; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pGeode->Rotate * pGeode->ShadowPitch; + srcPitch2 = srcPitch * 2; + srcPitch3 = srcPitch * 3; + srcPitch4 = srcPitch * 4; + while (num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if (pGeode->Rotate == 1) { + dstPtr = pGeode->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = pGeode->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = pGeode->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pGeode->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + while (width--) { + src = srcPtr; + dst = (CARD32 *) dstPtr; + count = height; + while (count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch2] << 16) | (src[srcPitch3] << 24); + src += srcPitch4; + } + srcPtr += pGeode->Rotate; + dstPtr += dstPitch; + } + pbox++; + } +} + +/*---------------------------------------------------------------------------- + * GX1RefreshArea16. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 16bpp. + * Parameters: + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX1RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pGeode->Rotate * pGeode->ShadowPitch >> 1; + srcPitch2 = srcPitch * 2; + while (num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + if (pGeode->Rotate == 1) { + dstPtr = (CARD16 *) pGeode->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16 *) pGeode->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD16 *) pGeode->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16 *) pGeode->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while (width--) { + src = srcPtr; + dst = (CARD32 *) dstPtr; + count = height; + while (count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch2; + } + srcPtr += pGeode->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + +/*---------------------------------------------------------------------------- + * GX1RefreshArea24. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 24bpp. + * Parameters. + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX1RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2, srcPitch3; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = BitmapBytePad(pScrn->displayWidth * 24); + srcPitch = -pGeode->Rotate * pGeode->ShadowPitch; + srcPitch2 = srcPitch * 2; + srcPitch3 = srcPitch * 3; + while (num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* blocks of 3 dwords */ + if (pGeode->Rotate == 1) { + dstPtr = pGeode->FBBase + + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); + srcPtr = pGeode->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); + } else { + dstPtr = pGeode->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); + srcPtr = pGeode->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; + } + while (width--) { + src = srcPtr; + dst = (CARD32 *) dstPtr; + count = height; + while (count--) { + dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | + (src[srcPitch] << 24); + dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | + (src[srcPitch2] << 16) | (src[srcPitch2 + 1] << 24); + dst[2] = src[srcPitch2 + 2] | (src[srcPitch3] << 8) | + (src[srcPitch3 + 1] << 16) | (src[srcPitch3 + 2] << 24); + dst += 3; + src += srcPitch << 2; + } + srcPtr += pGeode->Rotate * 3; + dstPtr += dstPitch; + } + pbox++; + } +} + +/*---------------------------------------------------------------------------- + * GX1RefreshArea32. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 32bpp. + * Parameters: + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns : none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX1RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int count, width, height, dstPitch, srcPitch; + CARD32 *dstPtr, *srcPtr, *src, *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pGeode->Rotate * pGeode->ShadowPitch >> 2; + while (num--) { + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + if (pGeode->Rotate == 1) { + dstPtr = (CARD32 *) pGeode->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; + srcPtr = (CARD32 *) pGeode->ShadowPtr + + ((1 - pbox->y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD32 *) pGeode->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; + srcPtr = (CARD32 *) pGeode->ShadowPtr + + (pbox->y1 * srcPitch) + pbox->x2 - 1; + } + while (width--) { + src = srcPtr; + dst = dstPtr; + count = height; + while (count--) { + *(dst++) = *src; + src += srcPitch; + } + srcPtr += pGeode->Rotate; + dstPtr += dstPitch; + } + pbox++; + } +} + +/* End of file */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_video.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_video.c new file mode 100644 index 000000000..e410d2f7f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_video.c @@ -0,0 +1,1629 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_video.c,v 1.6 2003/02/21 16:51:09 alanh Exp $ */ +/* + * $Workfile: nsc_gx1_video.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file consists of main Xfree video supported routines. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* + * Fixes & Extensions to support Y800 greyscale modes + * Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "nsc.h" +#include "Xv.h" +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" +#include "nsc_fourcc.h" + +#define OFF_DELAY 200 /* milliseconds */ +#define FREE_DELAY 60000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) +#define XV_PROFILE 0 +#define REINIT 1 + +void GX1InitVideo(ScreenPtr pScreen); +void GX1ResetVideo(ScrnInfoPtr pScrn); + +#ifndef XvExtension +void +GX1InitVideo(ScreenPtr pScreen) +{ +} + +void +GX1ResetVideo(ScrnInfoPtr pScrn) +{ +} +#else + +#define DBUF 0 + +static XF86VideoAdaptorPtr GX1SetupImageVideo(ScreenPtr); +static void GX1InitOffscreenImages(ScreenPtr); +static void GX1StopVideo(ScrnInfoPtr, pointer, Bool); +static int GX1SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int GX1GetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); +static void GX1QueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, + unsigned int *, pointer); +static int GX1PutImage(ScrnInfoPtr, + short, short, short, short, short, short, + short, short, int, unsigned char *, short, short, + Bool, RegionPtr, pointer); +static int GX1QueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, + int *, int *); + +static void GX1BlockHandler(int, pointer, pointer, pointer); + +void GX1SetVideoPosition(int, int, int, int, + short, short, short, short, int, int, ScrnInfoPtr); + +extern void GX1AccelSync(ScrnInfoPtr pScreenInfo); + +#if !defined(STB_X) +extern int DeltaX, DeltaY; +#else +int DeltaX, DeltaY; +#endif + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static Atom xvColorKey, xvColorKeyMode, xvFilter +#if DBUF + , xvDoubleBuffer +#endif + ; + +/*---------------------------------------------------------------------------- + * GX1InitVideo + * + * Description :This is the initialization routine.It creates a new video adapter + * and calls GX1SetupImageVideo to initialize the adaptor by filling + * XF86VideoAdaptorREc.Then it lists the existing adaptors and adds the + * new one to it. Finally the list of XF86VideoAdaptorPtr pointers are + * passed to the xf86XVScreenInit(). + * + * Parameters. + * ScreenPtr + * pScreen :Screen handler pointer having screen information. + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX1InitVideo(ScreenPtr pScreen) +{ + GeodePtr pGeode; + + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + + pGeode = GEODEPTR(pScreenInfo); + + if (!pGeode->NoAccel) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + + int num_adaptors; + + DEBUGMSG(0, (0, X_NONE, "InitVideo\n")); + newAdaptor = GX1SetupImageVideo(pScreen); + GX1InitOffscreenImages(pScreen); + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if (newAdaptor) { + if (!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); + if (newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if (num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if (newAdaptors) + xfree(newAdaptors); + } +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = { + { + 0, + "XV_IMAGE", + 1024, 1024, + {1, 1} + } +}; + +#define NUM_FORMATS 4 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = { + {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#if DBUF +#define NUM_ATTRIBUTES 4 +#else +#define NUM_ATTRIBUTES 3 +#endif + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { +#if DBUF + {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, +#endif + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, + {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} +}; + +#define NUM_IMAGES 7 + +static XF86ImageRec Images[NUM_IMAGES] = { + XVIMAGE_UYVY, + XVIMAGE_YUY2, + XVIMAGE_Y2YU, + XVIMAGE_YVYU, + XVIMAGE_Y800, + XVIMAGE_I420, + XVIMAGE_YV12 +}; + +typedef struct +{ + FBAreaPtr area; + FBLinearPtr linear; + RegionRec clip; + CARD32 colorKey; + CARD32 colorKeyMode; + CARD32 filter; + CARD32 videoStatus; + Time offTime; + Time freeTime; +#if DBUF + Bool doubleBuffer; + int currentBuffer; +#endif +} +GeodePortPrivRec, *GeodePortPrivPtr; + +#define GET_PORT_PRIVATE(pScrn) \ + (GeodePortPrivPtr)((GEODEPTR(pScrn))->adaptor->pPortPrivates[0].ptr) + +/*---------------------------------------------------------------------------- + * GX1SetColorKey + * + * Description :This function reads the color key for the pallete and + * sets the video color key register. + * + * Parameters. + * ScreenInfoPtr + * pScrn :Screen pointer having screen information. + * pPriv :Video port private data + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static INT32 +GX1SetColorkey(ScrnInfoPtr pScrn, GeodePortPrivPtr pPriv) +{ + int red, green, blue; + unsigned long key; + + DEBUGMSG(0, (0, X_NONE, "ColorKey\n")); + switch (pScrn->depth) { + case 8: + GFX(get_display_palette_entry(pPriv->colorKey & 0xFF, &key)); + red = ((key >> 16) & 0xFF); + green = ((key >> 8) & 0xFF); + blue = (key & 0xFF); + break; + default: + red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red << (8 - + pScrn-> + weight. + red); + green = + (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset. + green << (8 - pScrn->weight.green); + blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset. + blue << (8 - pScrn->weight.blue); + break; + } + GFX(set_video_color_key((blue | (green << 8) | (red << 16)), 0xFCFCFC, + (pPriv->colorKeyMode == 0))); + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + return 0; +} + +/*---------------------------------------------------------------------------- + * GX1ResetVideo + * + * Description : This function resets the video + * + * Parameters. + * ScreenInfoPtr + * pScrn :Screen pointer having screen information. + * + * Returns :None + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ + +void +GX1ResetVideo(ScrnInfoPtr pScrn) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + if (!pGeode->NoAccel) { + GeodePortPrivPtr pPriv = pGeode->adaptor->pPortPrivates[0].ptr; + + DEBUGMSG(0, (0, X_NONE, "ResetVideo\n")); + GX1AccelSync(pScrn); + GFX(set_video_palette(NULL)); + GX1SetColorkey(pScrn, pPriv); + GFX(set_video_filter(pPriv->filter, pPriv->filter)); + } +} + +/*---------------------------------------------------------------------------- + * GX1SetupImageVideo + * + * Description : This function allocates space for a Videoadaptor and initializes + * the XF86VideoAdaptorPtr record. + * + * Parameters. + * ScreenPtr + * pScreen :Screen handler pointer having screen information. + * + * Returns :XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ + +static XF86VideoAdaptorPtr +GX1SetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GeodePtr pGeode = GEODEPTR(pScrn); + XF86VideoAdaptorPtr adapt; + GeodePortPrivPtr pPriv; + + DEBUGMSG(0, (0, X_NONE, "SetupImageVideo\n")); + if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "National Semiconductor Corporation"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion *) (&adapt[1]); + pPriv = (GeodePortPrivPtr) (&adapt->pPortPrivates[1]); + adapt->pPortPrivates[0].ptr = (pointer) (pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = GX1StopVideo; + adapt->SetPortAttribute = GX1SetPortAttribute; + adapt->GetPortAttribute = GX1GetPortAttribute; + adapt->QueryBestSize = GX1QueryBestSize; + adapt->PutImage = GX1PutImage; + adapt->QueryImageAttributes = GX1QueryImageAttributes; + + pPriv->colorKey = pGeode->videoKey; + pPriv->colorKeyMode = 0; + pPriv->filter = 0; + pPriv->videoStatus = 0; +#if DBUF + pPriv->doubleBuffer = TRUE; + pPriv->currentBuffer = 0; /* init to first buffer */ +#endif + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + pGeode->adaptor = adapt; + + pGeode->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = GX1BlockHandler; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); + xvFilter = MAKE_ATOM("XV_FILTER"); +#if DBUF + xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); +#endif + + GX1ResetVideo(pScrn); + + return adapt; +} + +#if REINIT +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if (num != REGION_NUM_RECTS(B)) + return FALSE; + + if ((A->extents.x1 != B->extents.x1) || + (A->extents.x2 != B->extents.x2) || + (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) + return FALSE; + + dataA = (int *)REGION_RECTS(A); + dataB = (int *)REGION_RECTS(B); + + while (num--) { + if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; +} +#endif + +/*---------------------------------------------------------------------------- + * GX1StopVideo + * + * Description :This function is used to stop input and output video + * + * Parameters. + * pScreenInfo + * pScrn :Screen handler pointer having screen information. + * data :Pointer to the video port's private data + * exit :Flag indicating whether the offscreen areas used for video + * to be deallocated or not. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static void +GX1StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) +{ + GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; + GeodePtr pGeode = GEODEPTR(pScrn); + + DEBUGMSG(0, (0, X_NONE, "StopVideo\n")); + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + GX1AccelSync(pScrn); + if (exit) { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + GFX(set_video_enable(0)); + } + if (pPriv->area) { + xf86FreeOffscreenArea(pPriv->area); + pPriv->area = NULL; + } + pPriv->videoStatus = 0; + pGeode->OverlayON = FALSE; + } else { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + } + } +} + +/*---------------------------------------------------------------------------- + * GX1SetPortAttribute + * + * Description :This function is used to set the attributes of a port like colorkeymode, + * double buffer support and filter. + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * data :Pointer to the video port's private data + * attribute :The port attribute to be set + * value :Value of the attribute to be set. + * + * Returns :Sucess if the attribute is supported, else BadMatch + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static int +GX1SetPortAttribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 value, pointer data) +{ + GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; + + GX1AccelSync(pScrn); + if (attribute == xvColorKey) { + pPriv->colorKey = value; + GX1SetColorkey(pScrn, pPriv); + } +#if DBUF + else if (attribute == xvDoubleBuffer) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->doubleBuffer = value; + } +#endif + else if (attribute == xvColorKeyMode) { + pPriv->colorKeyMode = value; + GX1SetColorkey(pScrn, pPriv); + } else if (attribute == xvFilter) { + pPriv->filter = value; + GFX(set_video_filter(pPriv->filter, pPriv->filter)); + } else + return BadMatch; + + return Success; +} + +/*---------------------------------------------------------------------------- + * GX1GetPortAttribute + * + * Description :This function is used to get the attributes of a port like hue, + * saturation,brightness or contrast. + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * data :Pointer to the video port's private data + * attribute :The port attribute to be read + * value :Pointer to the value of the attribute to be read. + * + * Returns :Sucess if the attribute is supported, else BadMatch + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static int +GX1GetPortAttribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 * value, pointer data) +{ + GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; + + if (attribute == xvColorKey) { + *value = pPriv->colorKey; + } +#if DBUF + else if (attribute == xvDoubleBuffer) { + *value = (pPriv->doubleBuffer) ? 1 : 0; + } +#endif + else if (attribute == xvColorKeyMode) { + *value = pPriv->colorKeyMode; + } else if (attribute == xvFilter) { + *value = pPriv->filter; + } else + return BadMatch; + + return Success; +} + +/*---------------------------------------------------------------------------- + * GX1QueryBestSize + * + * Description :This function provides a way to query what the destination dimensions + * would end up being if they were to request that an area vid_w by vid_h + * from the video stream be scaled to rectangle of drw_w by drw_h on + * the screen. + * + * Parameters. + * ScreenInfoPtr + * pScrn :Screen handler pointer having screen information. + * data :Pointer to the video port's private data + * vid_w,vid_h :Width and height of the video data. + * drw_w,drw_h :Width and height of the scaled rectangle. + * p_w,p_h :Width and height of the destination rectangle. + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ +static void +GX1QueryBestSize(ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, pointer data) +{ + DEBUGMSG(0, (0, X_NONE, "QueryBestSize\n")); + *p_w = drw_w; + *p_h = drw_h; + + if (*p_w > 16384) + *p_w = 16384; +} +static void +GX1CopyGreyscale(unsigned char *src, + unsigned char *dst, int srcPitch, int dstPitch, int h, int w) +{ + int i; + unsigned char *src2 = src; + unsigned char *dst2 = dst; + unsigned char *dst3; + unsigned char *src3; + + dstPitch <<= 1; + + while (h--) { + dst3 = dst2; + src3 = src2; + for (i = 0; i < w; i++) { + *dst3++ = *src3++; /* Copy Y data */ + *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ + } + src3 = src2; + for (i = 0; i < w; i++) { + *dst3++ = *src3++; /* Copy Y data */ + *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ + } + dst2 += dstPitch; + src2 += srcPitch; + } +} + +/*---------------------------------------------------------------------------- + * GX1CopyData + * + * Description : Copies data from src to destination + * + * Parameters. + * src : pointer to the source data + * dst : pointer to destination data + * srcPitch : pitch of the srcdata + * dstPitch : pitch of the destination data + * h & w : height and width of source data + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static void +GX1CopyData(unsigned char *src, unsigned char *dst, + int srcPitch, int dstPitch, int h, int w) +{ + w <<= 1; + while (h--) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } +} + +static void +GX1CopyMungedData(unsigned char *src1, + unsigned char *src2, + unsigned char *src3, + unsigned char *dst1, + int srcPitch, int srcPitch2, int dstPitch, int h, int w) +{ + CARD32 *dstCur = (CARD32 *) dst1; + CARD32 *dstNext = (CARD32 *) dst1; + int i, j, k, m, n; + CARD32 crcb; + +#if XV_PROFILE + long oldtime, newtime; +#endif + + DEBUGMSG(0, (0, X_NONE, "CopyMungedData\n")); + /* dstPitch is in byte count, but we write longs. + * so divide dstpitch by 4 + */ + dstPitch >>= 2; + /* Width is in byte but video data is 16bit + */ + w >>= 1; + /* We render 2 scanlines at one shot, handle the odd count */ + m = h & 1; + /* decrement the height since we write 2 scans */ + h -= 1; + /* we traverse by 2 bytes in src Y */ + srcPitch <<= 1; +#if XV_PROFILE + UpdateCurrentTime(); + oldtime = currentTime.milliseconds; +#endif + + for (j = 0; j < h; j += 2) { + /* calc the next dest scan start */ + dstNext = dstCur + dstPitch; + for (i = 0; i < w; i++) { + /* crcb is same for the x pixel for 2 scans */ + crcb = (src3[i] << 8) | (src2[i] << 24); + + n = i << 1; + + /* write the first scan pixel DWORD */ + dstCur[i] = src1[n] | (src1[n + 1] << 16) | crcb; + + /* calc the offset of next pixel */ + k = n + srcPitch; + + /* write the 2nd scan pixel DWORD */ + dstNext[i] = src1[k] | (src1[k + 1] << 16) | crcb; + } + /* increment the offsets */ + + /* Y */ + src1 += srcPitch; + /* crcb */ + src2 += srcPitch2; + src3 += srcPitch2; + /* processed dest */ + dstCur += (dstPitch << 1); + } + + /* if any scans remaining */ + if (m) { + for (i = 0, k = 0; i < w; i++, k += 2) { + dstCur[i] = src1[k] | (src1[k + 1] << 16) | + (src3[i] << 8) | (src2[i] << 24); + } + } +#if XV_PROFILE + UpdateCurrentTime(); + newtime = currentTime.milliseconds; + DEBUGMSG(1, (0, X_NONE, "CMD %d\n", newtime - oldtime)); +#endif +} + +static FBAreaPtr +GX1AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int numlines) +{ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + FBAreaPtr new_area; + + if (area) { + if ((area->box.y2 - area->box.y1) >= numlines) + return area; + + if (xf86ResizeOffscreenArea(area, pScrn->displayWidth, numlines)) + return area; + + xf86FreeOffscreenArea(area); + } + + new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + numlines, 0, NULL, NULL, NULL); + + if (!new_area) { + int max_w, max_h; + + xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0, + FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); + + if ((max_w < pScrn->displayWidth) || (max_h < numlines)) + return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + numlines, 0, NULL, NULL, NULL); + } + return new_area; +} + +static BoxRec dstBox; +static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0; +static INT32 Bx1, Bx2, By1, By2; +static int top, left, npixels, nlines; +static int offset, s1offset = 0, s2offset = 0, s3offset = 0; +static unsigned char *dst_start; +static int TVOverScanX; + +static Bool +RegionsIntersect(BoxPtr pRcl1, BoxPtr pRcl2, BoxPtr pRclResult) +{ + pRclResult->x1 = max(pRcl1->x1, pRcl2->x1); + pRclResult->x2 = min(pRcl1->x2, pRcl2->x2); + + if (pRclResult->x1 <= pRclResult->x2) { + pRclResult->y1 = max(pRcl1->y1, pRcl2->y1); + pRclResult->y2 = min(pRcl1->y2, pRcl2->y2); + + if (pRclResult->y1 <= pRclResult->y2) { + return (TRUE); + } + } + + return (FALSE); +} + +void +GX1SetVideoPosition(int x, int y, int width, int height, + short src_w, short src_h, short drw_w, short drw_h, + int id, int offset, ScrnInfoPtr pScrn) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + long xstart, ystart, xend, yend; + unsigned long lines = 0; + unsigned long y_extra = 0; + unsigned short crop = 0; + BoxRec ovly, display, result; + +#if defined(STB_X) + unsigned long startAddress = 0; +#endif + xend = x + drw_w; + yend = y + drw_h; + + /* Take care of panning when panel is present */ + +#if defined(STB_X) + Gal_get_display_offset(&startAddress); + DeltaY = startAddress / pGeode->Pitch; + DeltaX = startAddress & (pGeode->Pitch - 1); + DeltaX /= (pScrn->bitsPerPixel >> 3); +#endif + + if (pGeode->Panel) { + ovly.x1 = x; + ovly.x2 = x + pGeode->video_dstw; + ovly.y1 = y; + ovly.y2 = y + pGeode->video_dsth; + + display.x1 = DeltaX; + display.x2 = DeltaX + pGeode->FPBX; + display.y1 = DeltaY; + display.y2 = DeltaY + pGeode->FPBY; + + x = xend = 0; + + if (RegionsIntersect(&display, &ovly, &result)) { + x = ovly.x1 - DeltaX; + xend = ovly.x2 - DeltaX; + y = ovly.y1 - DeltaY; + yend = ovly.y2 - DeltaY; + } + } + + /* LEFT CLIPPING */ + + if (x < 0) { + if (TVOverScanX) + xstart = TVOverScanX; + else + xstart = 0; + } else { + if (TVOverScanX) + xstart = TVOverScanX; + else + xstart = (unsigned long)x; + } + drw_w -= (xstart - x); + + /* TOP CLIPPING */ + + if (y < 0) { + lines = (-y) * src_h / drw_h; + ystart = 0; + drw_h += y; + y_extra = lines * dstPitch; + } else { + ystart = y; + lines = 0; + y_extra = 0; + } + + /* CLIP RIGHT AND BOTTOM FOR TV OVER SCAN */ + if (pGeode->TV_Overscan_On) { + crop = (pGeode->TVOw + pGeode->TVOx); + if ((xstart + drw_w) > crop) + xend = crop; + crop = (pGeode->TVOh + pGeode->TVOy); + if ((ystart + drw_h) > crop) + yend = crop; + } + GFX(set_video_window(xstart, ystart, xend - xstart, yend - ystart)); + GFX(set_video_offset(offset + y_extra)); + GFX(set_video_left_crop(xstart - x)); + +} + +/*---------------------------------------------------------------------------- + * GX1DisplayVideo + * + * Description : This function sets up the video registers for playing video + * It sets up the video format,width, height & position of the + * video window ,video offsets( y,u,v) and video pitches(y,u,v) + * Parameters. + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static void +GX1DisplayVideo(ScrnInfoPtr pScrn, + int id, + int offset, + short width, short height, + int pitch, + int x1, int y1, int x2, int y2, + BoxPtr dstBox, + short src_w, short src_h, short drw_w, short drw_h) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + /* DisplayModePtr mode = pScrn->currentMode; */ + GX1AccelSync(pScrn); + + GFX(set_video_enable(1)); + + switch (id) { + case FOURCC_UYVY: /* UYVY */ + GFX(set_video_format(VIDEO_FORMAT_UYVY)); + break; + case FOURCC_Y800: /* Y800 - greyscale - we munge it! */ + case FOURCC_YV12: + case FOURCC_I420: + case FOURCC_YUY2: /* YUY2 */ + GFX(set_video_format(VIDEO_FORMAT_YUYV)); + break; + case FOURCC_Y2YU: /* Y2YU */ + GFX(set_video_format(VIDEO_FORMAT_Y2YU)); + break; + case FOURCC_YVYU: /* YVYU */ + GFX(set_video_format(VIDEO_FORMAT_YVYU)); + break; + } + + if (pGeode->TV_Overscan_On) { + if (dstBox->x1 < 0) + TVOverScanX = pGeode->TVOx; + else + TVOverScanX = 0; + dstBox->x1 += pGeode->TVOx; + dstBox->y1 += pGeode->TVOy; + } + if (pGeode->Panel) { + pGeode->video_x = dstBox->x1; + pGeode->video_y = dstBox->y1; + pGeode->video_w = width; + pGeode->video_h = height; + pGeode->video_srcw = src_w; + pGeode->video_srch = src_h; + pGeode->video_dstw = drw_w; + pGeode->video_dsth = drw_h; + pGeode->video_offset = offset; + pGeode->video_id = id; + pGeode->video_scrnptr = pScrn; + } + + GFX(set_video_size(width, height)); + GFX(set_video_scale(width, height, drw_w, drw_h)); + GX1SetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, src_h, + drw_w, drw_h, id, offset, pScrn); + GFX(set_color_space_YUV(0)); +} + +/*---------------------------------------------------------------------------- + * GX1PutImage : This function writes a single frame of video into a drawable. + * The position and size of the source rectangle is specified by src_x,src_y, + * src_w and src_h. This data is stored in a system memory buffer at buf. + * The position and size of the destination rectangle is specified by drw_x, + * drw_y,drw_w,drw_h.The data is in the format indicated by the image descriptor + * and represents a source of size width by height. If sync is TRUE the driver + * should not return from this function until it is through reading the data from + * buf. Returning when sync is TRUE indicates that it is safe for the data at buf + * to be replaced,freed, or modified. + * + * + * Description : + * Parameters. + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static int +GX1PutImage(ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char *buf, + short width, short height, + Bool sync, RegionPtr clipBoxes, pointer data) +{ + GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; + GeodePtr pGeode = GEODEPTR(pScrn); + int pitch, new_h; + +#if REINIT + BOOL ReInitVideo = FALSE; +#endif + +#if XV_PROFILE + long oldtime, newtime; + + UpdateCurrentTime(); + oldtime = currentTime.milliseconds; +#endif + +#if REINIT +/* update cliplist */ + if (!RegionsEqual(&pPriv->clip, clipBoxes)) { + ReInitVideo = TRUE; + } + if (ReInitVideo) { + DEBUGMSG(1, (0, X_NONE, "Regional Not Equal - Init\n")); +#endif + + if (drw_w > 16384) + drw_w = 16384; + + /* Clip */ + Bx1 = src_x; + Bx2 = src_x + src_w; + By1 = src_y; + By2 = src_y + src_h; + + if ((Bx1 >= Bx2) || (By1 >= By2)) + return Success; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; + + pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; + + dstPitch = ((width << 1) + 3) & ~3; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + srcPitch = (width + 3) & ~3; /* of luma */ + s2offset = srcPitch * height; + srcPitch2 = ((width >> 1) + 3) & ~3; + s3offset = (srcPitch2 * (height >> 1)) + s2offset; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + default: + srcPitch = (width << 1); + break; + } + + /* Find how many pitch scanlines required to store the data */ + new_h = ((dstPitch * height) + pitch - 1) / pitch; + +#if DBUF + if (pPriv->doubleBuffer) + new_h <<= 1; +#endif + + if (!(pPriv->area = GX1AllocateMemory(pScrn, pPriv->area, new_h))) + return BadAlloc; + + /* copy data */ + top = By1; + left = Bx1 & ~1; + npixels = ((Bx2 + 1) & ~1) - left; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + { + int tmp; + + top &= ~1; + offset = (pPriv->area->box.y1 * pitch) + (top * dstPitch); + +#if DBUF + if (pPriv->doubleBuffer && pPriv->currentBuffer) + offset += (new_h >> 1) * pitch; +#endif + + dst_start = pGeode->FBBase + offset + left; + tmp = ((top >> 1) * srcPitch2) + (left >> 1); + s2offset += tmp; + s3offset += tmp; + if (id == FOURCC_I420) { + tmp = s2offset; + s2offset = s3offset; + s3offset = tmp; + } + nlines = ((By2 + 1) & ~1) - top; + } + break; + + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + default: + left <<= 1; + buf += (top * srcPitch) + left; + nlines = By2 - top; + offset = (pPriv->area->box.y1 * pitch) + (top * dstPitch); + +#if DBUF + if (pPriv->doubleBuffer && pPriv->currentBuffer) + offset += (new_h >> 1) * pitch; +#endif + + dst_start = pGeode->FBBase + offset + left; + break; + } + s1offset = (top * srcPitch) + left; + +#if REINIT + /* update cliplist */ + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + if (pPriv->colorKeyMode == 0) { + /* draw these */ + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); + } + GX1DisplayVideo(pScrn, id, offset, width, height, dstPitch, + Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, + drw_h); + } +#endif + + switch (id) { + + case FOURCC_Y800: + GX1CopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); + break; + case FOURCC_YV12: + case FOURCC_I420: + GX1CopyMungedData(buf + s1offset, buf + s2offset, + buf + s3offset, dst_start, srcPitch, srcPitch2, + dstPitch, nlines, npixels); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + GX1CopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels); + break; + } +#if !REINIT + /* update cliplist */ + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + if (pPriv->colorKeyMode == 0) { + /* draw these */ + xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } + GX1DisplayVideo(pScrn, id, offset, width, height, dstPitch, + Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); +#endif + +#if XV_PROFILE + UpdateCurrentTime(); + newtime = currentTime.milliseconds; + DEBUGMSG(1, (0, X_NONE, "PI %d\n", newtime - oldtime)); +#endif + +#if DBUF + pPriv->currentBuffer ^= 1; +#endif + + pPriv->videoStatus = CLIENT_VIDEO_ON; + pGeode->OverlayON = TRUE; + return Success; +} + +/*---------------------------------------------------------------------------- + * GX1QueryImageAttributes + * + * Description :This function is called to let the driver specify how data + * for a particular image of size width by height should be + * stored. + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * id :Id for the video format + * width :width of the image (can be modified by the driver) + * height :height of the image (can be modified by the driver) + * Returns : Size of the memory required for storing this image + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ +static int +GX1QueryImageAttributes(ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets) +{ + int size; + int tmp; + + DEBUGMSG(0, (0, X_NONE, "QueryImageAttributes %X\n", id)); + + if (*w > 1024) + *w = 1024; + if (*h > 1024) + *h = 1024; + + *w = (*w + 1) & ~1; + if (offsets) + offsets[0] = 0; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if (pitches) + pitches[0] = size; + size *= *h; + if (offsets) + offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if (pitches) + pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if (offsets) + offsets[2] = size; + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + default: + size = *w << 1; + if (pitches) + pitches[0] = size; + size *= *h; + break; + } + return size; +} + +static void +GX1BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[i]; + ScrnInfoPtr pScrn = xf86Screens[i]; + GeodePtr pGeode = GEODEPTR(pScrn); + GeodePortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + + DEBUGMSG(0, (0, X_NONE, "BlockHandler\n")); + pScreen->BlockHandler = pGeode->BlockHandler; + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScreen->BlockHandler = GX1BlockHandler; + + GX1AccelSync(pScrn); + if (pPriv->videoStatus & TIMER_MASK) { + UpdateCurrentTime(); + if (pPriv->videoStatus & OFF_TIMER) { + if (pPriv->offTime < currentTime.milliseconds) { + GFX(set_video_enable(0)); + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } + } else { /* FREE_TIMER */ + if (pPriv->freeTime < currentTime.milliseconds) { + if (pPriv->area) { + xf86FreeOffscreenArea(pPriv->area); + pPriv->area = NULL; + } + pPriv->videoStatus = 0; + } + } + } +} + +/****************** Offscreen stuff ***************/ + +typedef struct +{ + FBAreaPtr area; + FBLinearPtr linear; + Bool isOn; +} +OffscreenPrivRec, *OffscreenPrivPtr; + +/*---------------------------------------------------------------------------- + * GX1AllocateSurface + * + * Description :This function allocates an area of w by h in the offscreen + * Parameters. + * ScreenPtr + * pScreen :Screen handler pointer having screen information. + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static int +GX1AllocateSurface(ScrnInfoPtr pScrn, + int id, + unsigned short w, unsigned short h, XF86SurfacePtr surface) +{ + FBAreaPtr area; + int pitch, fbpitch, numlines; + OffscreenPrivPtr pPriv; + + DEBUGMSG(0, (0, X_NONE, "AllocateSurface %x\n", id)); + if ((w > 1024) || (h > 1024)) + return BadAlloc; + + w = (w + 1) & ~1; + pitch = ((w << 1) + 15) & ~15; + fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; + numlines = ((pitch * h) + fbpitch - 1) / fbpitch; + + if (!(area = GX1AllocateMemory(pScrn, NULL, numlines))) + return BadAlloc; + + surface->width = w; + surface->height = h; + + if (!(surface->pitches = xalloc(sizeof(int)))) + return BadAlloc; + if (!(surface->offsets = xalloc(sizeof(int)))) { + xfree(surface->pitches); + return BadAlloc; + } + if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { + xfree(surface->pitches); + xfree(surface->offsets); + return BadAlloc; + } + + pPriv->area = area; + pPriv->isOn = FALSE; + + surface->pScrn = pScrn; + surface->id = id; + surface->pitches[0] = pitch; + surface->offsets[0] = area->box.y1 * fbpitch; + surface->devPrivate.ptr = (pointer) pPriv; + + return Success; +} + +static int +GX1StopSurface(XF86SurfacePtr surface) +{ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; + + if (pPriv->isOn) { + pPriv->isOn = FALSE; + } + + return Success; +} + +static int +GX1FreeSurface(XF86SurfacePtr surface) +{ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; + + DEBUGMSG(0, (0, X_NONE, "FreeSurface\n")); + + if (pPriv->isOn) + GX1StopSurface(surface); + xf86FreeOffscreenArea(pPriv->area); + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); + + return Success; +} + +static int +GX1GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 * value) +{ + return GX1GetPortAttribute(pScrn, attribute, value, + (pointer) (GET_PORT_PRIVATE(pScrn))); +} + +static int +GX1SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value) +{ + return GX1SetPortAttribute(pScrn, attribute, value, + (pointer) (GET_PORT_PRIVATE(pScrn))); +} + +static int +GX1DisplaySurface(XF86SurfacePtr surface, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, RegionPtr clipBoxes) +{ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; + ScrnInfoPtr pScrn = surface->pScrn; + GeodePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn); + INT32 x1, y1, x2, y2; + BoxRec dstBox; + + DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + if ((x1 >= x2) || (y1 >= y2)) + return Success; + + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; + + xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); + + GX1DisplayVideo(pScrn, surface->id, surface->offsets[0], + surface->width, surface->height, surface->pitches[0], + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + pPriv->isOn = TRUE; + if (portPriv->videoStatus & CLIENT_VIDEO_ON) { + REGION_EMPTY(pScrn->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } + + return Success; +} + +/*---------------------------------------------------------------------------- + * GX1InitOffscreenImages + * + * Description :This function sets up the offscreen memory management.It fills + * in the XF86OffscreenImagePtr structure with functions to handle + * offscreen memory operations. + * + * Parameters. + * ScreenPtr + * pScreen :Screen handler pointer having screen information. + * + * Returns : None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ +static void +GX1InitOffscreenImages(ScreenPtr pScreen) +{ + XF86OffscreenImagePtr offscreenImages; + + DEBUGMSG(0, (0, X_NONE, "InitOffscreenImages\n")); + /* need to free this someplace */ + if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) + return; + + offscreenImages[0].image = &Images[0]; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].alloc_surface = GX1AllocateSurface; + offscreenImages[0].free_surface = GX1FreeSurface; + offscreenImages[0].display = GX1DisplaySurface; + offscreenImages[0].stop = GX1StopSurface; + offscreenImages[0].setAttribute = GX1SetSurfaceAttribute; + offscreenImages[0].getAttribute = GX1GetSurfaceAttribute; + offscreenImages[0].max_width = 1024; + offscreenImages[0].max_height = 1024; + offscreenImages[0].num_attributes = NUM_ATTRIBUTES; + offscreenImages[0].attributes = Attributes; + + xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); +} + +#endif /* !XvExtension */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_accel.c new file mode 100644 index 000000000..88c49eed9 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_accel.c @@ -0,0 +1,2302 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_accel.c,v 1.4 2003/02/21 16:51:09 alanh Exp $ */ +/* + * $Workfile: nsc_gx2_accel.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file is consists of main Xfree + * acceleration supported routines like solid fill used + * here. + * Project: Geode Xfree Frame buffer device driver. + * + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* Xfree86 header files */ +#include "vgaHW.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xaalocal.h" +#include "xf86fbman.h" +#include "miline.h" +#include "xf86_libc.h" +#include "xaarop.h" +#include "nsc.h" + +#define DASHED_SUPPORT 0 +#define IMGWRITE_SUPPORT 0 +#define SCR2SCREXP 0 + +/* STATIC VARIABLES FOR THIS FILE + * Used to maintain state between setup and rendering calls. + */ + +static int GeodeTransparent; +static int GeodeTransColor; +static int Geodedstx; +static int Geodedsty; +static int Geodesrcx; +static int Geodesrcy; +static int Geodewidth; +static int Geodeheight; +static int Geodebpp; +static int GeodeCounter; + +#if !defined(STB_X) +static unsigned int GeodeROP = 0; +static unsigned short Geode_blt_mode = 0; +static unsigned short Geode_vector_mode = 0; +#endif +static unsigned int gu2_xshift = 1; +static unsigned int gu2_yshift = 1; +static unsigned int gu2_bpp = 1; +static unsigned int SetCPUToScreen = 0; +static unsigned int SetImageWriteRect = 0; +static unsigned int ImgBufOffset; + +#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING) +#define GU2_WAIT_BUSY while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY) + +#define CALC_FBOFFSET(_SrcX, _SrcY) \ + (((unsigned int) (_SrcY) << gu2_yshift) |\ + (((unsigned int) (_SrcX)) << gu2_xshift)) + +#define GFX_PATTERN_FILL(_SrcX, _SrcY, _Width, _Height) \ +{ \ + GU2_WAIT_PENDING;\ + WRITE_GP32(MGP_DST_OFFSET, CALC_FBOFFSET((_SrcX), (_SrcY)));\ + WRITE_GP32(MGP_WID_HEIGHT, \ + (((unsigned int) (_Width)) << 16) | (_Height));\ + WRITE_GP32(MGP_BLT_MODE, Geode_blt_mode);\ +} + +static XAAInfoRecPtr localRecPtr; + +Bool GX2AccelInit(ScreenPtr pScreen); +void GX2AccelSync(ScrnInfoPtr pScreenInfo); +void GX2SetupForFillRectSolid(ScrnInfoPtr pScreenInfo, int color, int rop, + unsigned int planemask); +void GX2SubsequentFillRectSolid(ScrnInfoPtr pScreenInfo, int x, int y, + int w, int h); +void GX2SetupFor8x8PatternColorExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, + int rop, unsigned int planemask, + int trans_color); +void GX2Subsequent8x8PatternColorExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int x, + int y, int w, int h); +void GX2SetupFor8x8PatternMonoExpand(ScrnInfoPtr pScreenInfo, int patternx, + int patterny, int fg, int bg, int rop, + unsigned int planemask); +void GX2Subsequent8x8PatternMonoExpand(ScrnInfoPtr pScreenInfo, int patternx, + int patterny, int x, int y, int w, + int h); +void GX2SetupForScreenToScreenCopy(ScrnInfoPtr pScreenInfo, int xdir, + int ydir, int rop, unsigned int planemask, + int transparency_color); +void GX2SubsequentScreenToScreenCopy(ScrnInfoPtr pScreenInfo, int x1, int y1, + int x2, int y2, int w, int h); +void GX2SetupForSolidLine(ScrnInfoPtr pScreenInfo, int color, int rop, + unsigned int planemask); +void GX2SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern); +void GX2SubsequentBresenhamLine(ScrnInfoPtr pScreenInfo, int x1, int y1, + int absmaj, int absmin, int err, int len, + int octant); +void GX2SubsequentSolidTwoPointLine(ScrnInfoPtr pScreenInfo, int x0, int y0, + int x1, int y1, int flags); +void GX2SubsequentHorVertLine(ScrnInfoPtr pScreenInfo, int x, int y, int len, + int dir); + +void GX2SetupForScanlineImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, + int depth); + +void GX2SubsequentScanlineImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft); + +void GX2SubsequentImageWriteScanline(ScrnInfoPtr pScreenInfo, int bufno); +void GX2FillCacheBltRects(ScrnInfoPtr pScrn, int rop, unsigned int planemask, + int nBox, BoxPtr pBox, int xorg, int yorg, + XAACacheInfoPtr pCache); +void GX2SetupForImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth); +void GX2SubsequentImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, int skipleft); +void GX2SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScreenInfo, + int fg, int bg, int rop, + unsigned int planemask); +void GX2SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft); +void OPTGX2SetupForFillRectSolid(ScrnInfoPtr pScreenInfo, int color, int rop, + unsigned int planemask); +void OPTGX2SubsequentFillRectSolid(ScrnInfoPtr pScreenInfo, int x, int y, + int w, int h); +void OPTGX2SetupForScreenToScreenCopy(ScrnInfoPtr pScreenInfo, int xdir, + int ydir, int rop, + unsigned int planemask, + int transparency_color); +void OPTGX2SubsequentScreenToScreenCopy(ScrnInfoPtr pScreenInfo, int x1, + int y1, int x2, int y2, int w, int h); +void OPTGX2SetupForSolidLine(ScrnInfoPtr pScreenInfo, int color, int rop, + unsigned int planemask); +void OPTGX2SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern); +void OPTGX2SubsequentBresenhamLine(ScrnInfoPtr pScreenInfo, int x1, int y1, + int absmaj, int absmin, int err, int len, + int octant); +void OPTGX2SubsequentSolidTwoPointLine(ScrnInfoPtr pScreenInfo, + int x0, int y0, int x1, int y1, + int flags); +void OPTGX2SubsequentHorVertLine(ScrnInfoPtr pScreenInfo, int x, int y, + int len, int dir); + +void OPTGX2SetupForScanlineImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, + int depth); + +void OPTGX2SubsequentScanlineImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft); + +void OPTGX2SubsequentImageWriteScanline(ScrnInfoPtr pScreenInfo, int bufno); +void OPTGX2SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScreenInfo, + int fg, int bg, int rop, + unsigned int planemask); +void OPTGX2SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft); +void OPTGX2SetupForImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth); +void OPTGX2SubsequentImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, int skipleft); + +/*---------------------------------------------------------------------------- + * GX2AccelSync. + * + * Description :This function is called to syncronize with the graphics + * engine and it waits the graphic engine is idle.This is + * required before allowing direct access to the + * framebuffer. + * Parameters. + * pScreenInfo:Screeen info pointer structure. + * + * Returns :none + * + * Comments :This function is called on geode_video routines. +*---------------------------------------------------------------------------- +*/ +void +GX2AccelSync(ScrnInfoPtr pScreenInfo) +{ + if (SetCPUToScreen) { +#if defined(OPT_ACCEL) + WRITE_GP32(MGP_BLT_MODE, Geode_blt_mode | + MGP_BM_SRC_FB | MGP_BM_SRC_MONO); +#else + GFX(mono_bitmap_to_screen_blt(0, 0, Geodedstx, Geodedsty, + Geodewidth, Geodeheight, + localRecPtr->ColorExpandBase, + ((Geodewidth + 31) >> 5) << 2)); +#endif + + SetCPUToScreen = 0; + } +#if IMGWRITE_SUPPORT + if (SetImageWriteRect) { + unsigned long srcpitch; + +#if defined(OPT_ACCEL) + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + srcpitch = ((Geodewidth << gu2_xshift) + 3) & 0xFFFFFFFC; + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_STRIDE, (srcpitch << 16) | pGeode->Pitch); + WRITE_GP32(MGP_SRC_OFFSET, ImgBufOffset); + WRITE_GP32(MGP_DST_OFFSET, + (CALC_FBOFFSET(Geodedstx, Geodedsty)) & 0x00FFFFFF); + WRITE_GP32(MGP_WID_HEIGHT, + ((unsigned long)Geodewidth << 16) | (unsigned long) + Geodeheight); +/* + ErrorF("%d %d, %d\n", Geodewidth, Geodeheight, gu2_xshift); + ErrorF("%X , %X %X %X %X\n", srcpitch, ((srcpitch << 16) | + pGeode->Pitch), ImgBufOffset, + (CALC_FBOFFSET(Geodedstx, Geodedsty)) & 0x00FFFFFF, + ((unsigned long)Geodewidth << 16) | + (unsigned long)Geodeheight); +*/ + WRITE_GP32(MGP_BLT_MODE, Geode_blt_mode); +#else + srcpitch = ((Geodewidth << gu2_xshift) + 3) & 0xFFFFFFFC; + GFX2(set_source_stride(srcpitch)); + GFX2(screen_to_screen_blt(ImgBufOffset, + CALC_FBOFFSET(Geodedstx, Geodedsty), + Geodewidth, Geodeheight, 0)); +#endif + SetImageWriteRect = 0; + } +#endif /* IMGWRITE_SUPPORT */ + + GFX(wait_until_idle()); +} + +/*---------------------------------------------------------------------------- + * GX2SetupForFillRectSolid. + * + * Description :This routine is called to setup the solid pattern + * color for future rectangular fills or vectors. + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * color :Specifies the color to be filled up in defined area. + * rop :Specifies the raster operation value. + * planemask :Specifies the masking value based rop srcdata. + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX2SetupForFillRectSolid(ScrnInfoPtr pScreenInfo, + int color, int rop, unsigned int planemask) +{ + GFX(set_solid_pattern((unsigned int)color)); + + /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ + if (planemask == 0xFFFFFFFF) { + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAAPatternROP[rop])); + } else { + /* SELECT ROP THAT USES SOURCE DATA FOR PLANEMASK */ + GFX(set_solid_source((unsigned int)planemask)); + GFX(set_raster_operation(XAAPatternROP_PM[rop])); + } +} + + /*---------------------------------------------------------------------------- + * GX2SubsequentFillRectSolid. + * + * Description :This routine is used to fill the rectangle of previously + * specified solid pattern. + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * x and y :Specifies the x and y co-ordinatesarea. + * w and h :Specifies width and height respectively. + * + * Returns :none + * + * Comments :desired pattern can be set before this function by + * gfx_set_solid_pattern. + * Sample application uses: + * - Window backgrounds. + * - x11perf: rectangle tests (-rect500). + * - x11perf: fill trapezoid tests (-trap100). + * - x11perf: horizontal line segments (-hseg500). + *---------------------------------------------------------------------------- +*/ +void +GX2SubsequentFillRectSolid(ScrnInfoPtr pScreenInfo, int x, int y, int w, + int h) +{ + DEBUGMSG(0, (0, 0, "FillRect %d %d %dx%d\n", x, y, w, h)); + + /* SIMPLY PASS THE PARAMETERS TO THE DURANGO ROUTINE */ + + GFX(pattern_fill((unsigned short)x, (unsigned short)y, + (unsigned short)w, (unsigned short)h)); +} + +/*---------------------------------------------------------------------------- + * GX2SetupFor8x8PatternColorExpand + * + * Description :This routine is called to fill the color pattern of + * 8x8. + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * patternx :This is set from on rop data. + * patterny :This is set based on rop data. + * planemask :Specifies the value of masking from rop data + * trans_color :to be added. + * Returns :none. + * + * Comments :none. + * +*---------------------------------------------------------------------------- +*/ + +void +GX2SetupFor8x8PatternColorExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int rop, + unsigned int planemask, int trans_color) +{ + /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ + if (planemask == 0xFFFFFFFF) { + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAAPatternROP[rop])); + } else { + /* SELECT ROP THAT USES SOURCE DATA FOR PLANEMASK */ + GFX(set_solid_source((unsigned int)planemask)); + GFX(set_raster_operation(XAAPatternROP_PM[rop])); + } +} + +/*---------------------------------------------------------------------------- + * GX2Subsequent8x8PatternColorExpand + * + * Description :This routine is called to fill a rectangle with the + * color pattern of previously loaded pattern. + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * patternx :This is set from on rop data. + * patterny :This is set based on rop data. + * x :x -coordinates of the destination rectangle + * y :y-co-ordinates of the destination rectangle + * w :Specifies width of the rectangle + * h :Height of the window of the rectangle + * + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses: + * - Patterned desktops + * - x11perf: stippled rectangle tests (-srect500). + * - x11perf: opaque stippled rectangle tests (-osrect500). +*---------------------------------------------------------------------------- +*/ +void +GX2Subsequent8x8PatternColorExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int x, int y, + int w, int h) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + DEBUGMSG(1, (0, 0, "8x8color %d %d %dx%d\n", x, y, w, h)); + + /* SIMPLY PASS THE PARAMETERS TO THE DURANGO ROUTINE */ + /* Ignores specified pattern. */ + GFX(color_pattern_fill((unsigned short)x, (unsigned short)y, + (unsigned short)w, (unsigned short)h, + ((unsigned long *)((pGeode->FBBase + + (patterny << gu2_yshift)) + + patternx)))); +} + +/*---------------------------------------------------------------------------- + * GX2SetupFor8x8PatternMonoExpand + * + * Description :This routine is called to fill the monochrome pattern of + * 8x8. + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * patternx :This is set from on rop data. + * patterny :This is set based on rop data. + * fg :Specifies the foreground color + * bg :Specifies the background color + * planemask :Specifies the value of masking from rop data + + * Returns :none. + * + * Comments :none. + * +*---------------------------------------------------------------------------- +*/ +void +GX2SetupFor8x8PatternMonoExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int fg, + int bg, int rop, unsigned int planemask) +{ + int trans = (bg == -1); + + /* LOAD PATTERN COLORS AND DATA */ + GFX(set_mono_pattern((unsigned int)bg, (unsigned int)fg, + (unsigned int)patternx, (unsigned int)patterny, + trans)); + + /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ + if (planemask == 0xFFFFFFFF) { + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAAPatternROP[rop])); + } else { + /* SELECT ROP THAT USES SOURCE DATA FOR PLANEMASK */ + GFX(set_solid_source((unsigned int)planemask)); + GFX(set_raster_operation(XAAPatternROP_PM[rop])); + } +} + +/*---------------------------------------------------------------------------- + * GX2Subsequent8x8PatternMonoExpand + * + * Description :This routine is called to fill a ractanglethe + * monochrome pattern of previusly loaded pattern. + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * patternx :This is set from on rop data. + * patterny :This is set based on rop data. + * fg :Specifies the foreground color + * bg :Specifies the background color + * planemask :Specifies the value of masking from rop data + + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses: + * - Patterned desktops + * - x11perf: stippled rectangle tests (-srect500). + * - x11perf: opaque stippled rectangle tests (-osrect500). +*---------------------------------------------------------------------------- +*/ +void +GX2Subsequent8x8PatternMonoExpand(ScrnInfoPtr pScreenInfo, + int patternx, int patterny, int x, int y, + int w, int h) +{ + DEBUGMSG(0, (0, 0, "8x8mono %d %d %dx%d\n", x, y, w, h)); + + /* SIMPLY PASS THE PARAMETERS TO THE DURANGO ROUTINE */ + /* Ignores specified pattern. */ + GFX(pattern_fill((unsigned short)x, (unsigned short)y, + (unsigned short)w, (unsigned short)h)); +} + +/*---------------------------------------------------------------------------- + * GX2SetupForScreenToScreenCopy + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * xdir :This is set based on rop data. + * ydir :This is set based on rop data. + * rop :sets the raster operation + * transparency:tobeadded + * planemask :Specifies the value of masking from rop data + + * Returns :none + * + * Comments :The patterns specified is ignored inside the function +*---------------------------------------------------------------------------- +*/ +void +GX2SetupForScreenToScreenCopy(ScrnInfoPtr pScreenInfo, + int xdir, int ydir, int rop, + unsigned int planemask, int transparency_color) +{ + GFX(set_solid_pattern(planemask)); + /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */ + GFX(set_raster_operation(XAACopyROP[rop])); + /* SAVE TRANSPARENCY FLAG */ + GeodeTransparent = (transparency_color == -1) ? 0 : 1; + GeodeTransColor = transparency_color; + +} + +/*---------------------------------------------------------------------------- + * GX2SubsquentScreenToScreenCopy + * + * Description :This function is called to perform a screen to screen + * BLT using the previously specified planemask,raster + * operation and * transparency flag + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * x1 :x -coordinates of the source window + * y1 :y-co-ordinates of the source window + * x2 :x -coordinates of the destination window + * y2 :y-co-ordinates of the destination window + * w :Specifies width of the window to be copied + * h :Height of the window to be copied. + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses (non-transparent): + * - Moving windows. + * - x11perf: scroll tests (-scroll500). + * - x11perf: copy from window to window (-copywinwin500). + * + * No application found using transparency. +*---------------------------------------------------------------------------- +*/ +void +GX2SubsequentScreenToScreenCopy(ScrnInfoPtr pScreenInfo, + int x1, int y1, int x2, int y2, int w, int h) +{ + if (GeodeTransparent) { + /* CALL ROUTINE FOR TRANSPARENT SCREEN TO SCREEN BLT + * * Should only be called for the "copy" raster operation. + */ + GFX(screen_to_screen_xblt((unsigned short)x1, (unsigned short)y1, + (unsigned short)x2, (unsigned short)y2, + (unsigned short)w, (unsigned short)h, + GeodeTransColor)); + } else { + /* CALL ROUTINE FOR NORMAL SCREEN TO SCREEN BLT */ + GFX(screen_to_screen_blt((unsigned short)x1, (unsigned short)y1, + (unsigned short)x2, (unsigned short)y2, + (unsigned short)w, (unsigned short)h)); + } +} + +void +GX2SetupForImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth) +{ + GFX(set_solid_pattern((unsigned int)planemask)); + /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */ + GFX(set_raster_operation(XAACopyROP[rop])); + /* SAVE TRANSPARENCY FLAG */ + GeodeTransparent = (transparency_color == -1) ? 0 : 1; + GeodeTransColor = transparency_color; + Geodebpp = bpp; +} + +void +GX2SubsequentImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, int skipleft) +{ + Geodedstx = x; + Geodedsty = y; + Geodewidth = w; + Geodeheight = h; + SetImageWriteRect = 1; + +} + +/*---------------------------------------------------------------------------- + * GX2SetupForScanlineImageWrite + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * rop :sets the raster operation + * transparency_color :transparency color key. + * planemask :Specifies the value of masking from rop data + * bpp :bits per pixel of the source pixmap + * depth :depth of the source pixmap. + * Returns :none + * + * Comments :none + * x11perf -putimage10 + * x11perf -putimage100 + * x11perf -putimage500 +*---------------------------------------------------------------------------- +*/ +void +GX2SetupForScanlineImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth) +{ + GFX(set_solid_pattern((unsigned int)planemask)); + /* SET RASTER OPERATION FOR USING PATTERN AS PLANE MASK */ + GFX(set_raster_operation(XAACopyROP[rop & 0x0F])); + /* SAVE TRANSPARENCY FLAG */ + GeodeTransparent = (transparency_color == -1) ? 0 : 1; + GeodeTransColor = transparency_color; + Geodebpp = bpp; +} + +/*---------------------------------------------------------------------------- + * GX2SubsequentScanlineImageWriteRect + * + * Description :This function is used to set up the x,y corordinates and width + * &height for future Bliting functionality. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x :destination x + * y :destination y + * w :Specifies the width of the rectangle to be copied + * h :Specifies the height of the rectangle to be copied + * + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +GX2SubsequentScanlineImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, int skipleft) +{ + Geodedstx = x; + Geodedsty = y; + Geodewidth = w; + Geodeheight = h; + GeodeCounter = 0; +} + +/*---------------------------------------------------------------------------- + * GX2SubsquentImageWriteScanline + * + * Description :This function is called to + * BLT using the previously specified planemask,raster + * operation and transparency flag + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses (non-transparent): + * - Moving windows. + * - x11perf: scroll tests (-scroll500). + * - x11perf: copy from window to window (-copywinwin500). + * + * No application found using transparency. +*---------------------------------------------------------------------------- +*/ +void +GX2SubsequentImageWriteScanline(ScrnInfoPtr pScreenInfo, int bufno) +{ + GeodePtr pGeode; + int blt_height = 0; + char blit = FALSE; + + pGeode = GEODEPTR(pScreenInfo); + + GeodeCounter++; + + if ((Geodeheight <= pGeode->NoOfImgBuffers) && + (GeodeCounter == Geodeheight)) { + blit = TRUE; + blt_height = Geodeheight; + } else if ((Geodeheight > pGeode->NoOfImgBuffers) + && (GeodeCounter == pGeode->NoOfImgBuffers)) { + blit = TRUE; + Geodeheight -= pGeode->NoOfImgBuffers; + blt_height = pGeode->NoOfImgBuffers; + } else + return; + + if (blit) { + blit = FALSE; + + GeodeCounter = 0; + + if (GeodeTransparent) { + /* CALL ROUTINE FOR TRANSPARENT SCREEN TO SCREEN BLT + * * Should only be called for the "copy" raster operation. + */ + GFX(screen_to_screen_xblt((unsigned short)Geodesrcx, + (unsigned short)Geodesrcy, + (unsigned short)Geodedstx, + (unsigned short)Geodedsty, + (unsigned short)Geodewidth, + (unsigned short)blt_height, + GeodeTransColor)); + } else { + /* CALL ROUTINE FOR NORMAL SCREEN TO SCREEN BLT */ + GFX(screen_to_screen_blt((unsigned short)Geodesrcx, + (unsigned short)Geodesrcy, + (unsigned short)Geodedstx, + (unsigned short)Geodedsty, + (unsigned short)Geodewidth, + (unsigned short)blt_height)); + } + Geodedsty += blt_height; + GFX(wait_until_idle()); + } +} + +/*---------------------------------------------------------------------------- + * GX2SetupForCPUToScreenColorExpandFill + * + * Description :This routine is called to setup the background and + * foreground colors,rop and plane mask for future + * color expansion blits from source patterns stored + * in system memory + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * fg :Specifies the foreground color + * bg :Specifies the background color + * rop :Specifies rop values. + * planemask :Specifies the value of masking from rop data + * + * Returns :none. + * + * Comments : + * All the text gets rendered through this i/f. We have given + * the offscreen memory loaction to temporarily put the text + * bitmap. Generaly all the text comes as bitmap and then gets + * rendered via the HOST_SRC(similar to scratchpad in GX1). Now + * since we already have the bitmap in offscreen we can do a + * src_FB_EXPAND. This is the best possible you can do with GX2 + * CPU-to-screen color expansion + *---------------------------------------------------------------------------- +*/ +void +GX2SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScreenInfo, + int fg, int bg, int rop, + unsigned int planemask) +{ + GFX(set_solid_pattern(planemask)); + GFX(set_mono_source(bg, fg, (bg == -1))); + + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAACopyROP_PM[rop & 0x0F])); + + DEBUGMSG(0, (0, X_NONE, "%x %x %x %x\n", fg, bg, rop, planemask)); +} + +/*------------------------------------------------------------------------------- + * GX2SubsequentCPUToScreenColorExpandFill + * + * Description :This routine is used to perform color expansion blits from + * source patterns stored in system memory using the + * previously set rop and plane mask. + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * x and y :Specifies the x and y co-ordinatesarea. + * w and h :Specifies width and height respectively. + * + * Returns :none + * + * Comments :none + *-------------------------------------------------------------------------------- + */ +void +GX2SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft) +{ + Geodedstx = x; + Geodedsty = y; + Geodewidth = w; + Geodeheight = h; + SetCPUToScreen = 1; +} + +#if SCR2SCREXP +void +GX2SetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask) +{ + GFX(set_solid_pattern(planemask)); + GFX(set_mono_source(bg, fg, (bg == -1))); + + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAACopyROP_PM[rop & 0x0F])); + + DEBUGMSG(0, (0, X_NONE, "%x %x %x %x\n", fg, bg, rop, planemask)); +} + +void +GX2SubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int srcx, int srcy, int offset) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + GFX(mono_bitmap_to_screen_blt(offset, 0, x, y, w, h, + (unsigned char *)(pGeode->FBBase + + CALC_FBOFFSET(srcx, srcy)), + pGeode->Pitch)); +} +#endif + +static unsigned short vector_mode_table[] = { + VM_MAJOR_INC | VM_MINOR_INC | VM_X_MAJOR, + VM_MAJOR_INC | VM_MINOR_INC | VM_Y_MAJOR, + VM_MAJOR_INC | VM_X_MAJOR, + VM_MINOR_INC | VM_Y_MAJOR, + VM_MINOR_INC | VM_X_MAJOR, + VM_MAJOR_INC | VM_Y_MAJOR, + VM_X_MAJOR, + VM_Y_MAJOR, +}; + +/*---------------------------------------------------------------------------- + * GX2SetupForSolidLine + * + * Description :This function is used setup the solid line color for + * future line draws. + * + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * color :Specifies the color value od line + * rop :Specifies rop values. + * Planemask :Specifies planemask value. + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +GX2SetupForSolidLine(ScrnInfoPtr pScreenInfo, + int color, int rop, unsigned int planemask) +{ + /* LOAD THE SOLID PATTERN COLOR */ + GFX(set_solid_pattern((unsigned int)color)); + + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(XAAPatternROP[rop & 0x0F])); +} + +/*--------------------------------------------------------------------------- + * GX2SubsequentBresenhamLine + * + * Description :This function is used to render a vector using the + * specified bresenham parameters. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x1 :Specifies the starting x position + * y1 :Specifies starting y possition + * absmaj :Specfies the Bresenman absolute major. + * absmin :Specfies the Bresenman absolute minor. + * err :Specifies the bresenham err term. + * len :Specifies the length of the vector interms of pixels. + * octant :not used in this function,may be added for standard + * interface. + * Returns :none + * + * Comments :none + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-line500). + * - x11perf: line segments (-seg500). +*---------------------------------------------------------------------------- +*/ +void +GX2SubsequentBresenhamLine(ScrnInfoPtr pScreenInfo, + int x1, int y1, int absmaj, int absmin, int err, + int len, int octant) +{ + int axial, init, diag; + + DEBUGMSG(0, (0, 0, "BLine %d, %d, %d, %d, %d, %d, %d\n", + x1, y1, absmaj, absmin, err, len, octant)); + + /* DETERMINE BRESENHAM PARAMETERS */ + + axial = ((int)absmin << 1); + init = axial - (int)absmaj; + diag = init - (int)absmaj; + + /* ADJUST INITIAL ERROR + * * Adjust by -1 for certain directions so that the vector + * * hits the same pixels when drawn in either direction. + * * The Gamma value is assumed to account for the initial + * * error adjustment for clipped lines. + */ + + init += err; + + /* CALL ROUTINE TO DRAW VECTOR */ + + GFX(bresenham_line((unsigned short)x1, + (unsigned short)y1, + (unsigned short)len, + (unsigned short)init, + (unsigned short)axial, + (unsigned short)diag, + (unsigned short)vector_mode_table[octant])); + +} + +#define ABS(_val1, _val2) (((_val1) > (_val2)) ? ((_val1)-(_val2)) : ((_val2) - (_val1))) + +void +GX2SubsequentSolidTwoPointLine(ScrnInfoPtr pScreenInfo, + int x0, int y0, int x1, int y1, int flags) +{ + long dx, dy, dmaj, dmin; + long axialerr, diagerr, initerr; + unsigned short vec_flags = 0; + + dx = ABS(x1, x0); + dy = ABS(y1, y0); + if (dx >= dy) { + dmaj = dx; + dmin = dy; + vec_flags = VM_X_MAJOR; + if (x1 > x0) + vec_flags |= VM_MAJOR_INC; + if (y1 > y0) + vec_flags |= VM_MINOR_INC; + } else { + dmaj = dy; + dmin = dx; + vec_flags = VM_Y_MAJOR; + if (x1 > x0) + vec_flags |= VM_MINOR_INC; + if (y1 > y0) + vec_flags |= VM_MAJOR_INC; + } + axialerr = dmin << 1; + diagerr = (dmin - dmaj) << 1; + initerr = (dmin << 1) - dmaj; + if (!(vec_flags & VM_MINOR_INC)) + initerr--; + + GFX(bresenham_line((unsigned short)x0, + (unsigned short)y0, + (unsigned short)dmaj, + (unsigned short)initerr, + (unsigned short)axialerr, + (unsigned short)diagerr, vec_flags)); +} + +/*--------------------------------------------------------------------------- + * GX2SubsequentHorVertLine + * + * This routine is called to render a vector using the specified Bresenham + * parameters. + * + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-hseg500). + * - x11perf: line segments (-vseg500). + *--------------------------------------------------------------------------- + */ +void +GX2SubsequentHorVertLine(ScrnInfoPtr pScreenInfo, + int x, int y, int len, int dir) +{ + DEBUGMSG(0, (0, 0, "HLine %d, %d, %d, %d\n", x, y, len, dir)); + GFX(pattern_fill((unsigned short)x, (unsigned short)y, + (unsigned short)((dir == DEGREES_0) ? len : 1), + (unsigned short)((dir == DEGREES_0) ? 1 : len))); +} + +#if DASHED_SUPPORT +void +BuildPattern(CARD32 pat, int len, CARD32 * pat8x8) +{ + unsigned long i, count; + + /* find homany can fit comfortably */ + count = 32 / len; + /* add 1 for the residue */ + count++; + /* construct the mask and knock off the unwanted data */ + i = ((CARD32) 0xFFFFFFFF) << (31 - len); + pat &= i; + /* init before the show */ + pat8x8[0] = 0; + /* loop and build the pattern aray data */ + for (i = 0; i < count; i++) { + pat8x8[0] |= (pat >> (len * i)); + } + + /* equate both the array's and then adjust */ + pat8x8[1] = pat8x8[0]; + + /* how many carried from last operation */ + i = (len * count) - 32; + pat8x8[1] >>= i; + pat8x8[1] |= (pat << (len - i)); +} + +#define PAT_SHIFT(pat,n) pat >> n + +/*---------------------------------------------------------------------------- + * GX2SetupForDashedLine + * + * Description :This function is used to setup for + * future line draws. + * + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * Returns :none + * + * Comments :none + * x11perf -dseg100 + * x11perf -dline100 + * x11perf -ddline100 +*---------------------------------------------------------------------------- +*/ +void +GX2SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern) +{ + int trans = (bg == -1); + CARD32 *pat = (CARD32 *) pattern; + CARD32 pat8x8[2]; + + pat8x8[0] = pat[0]; + switch (length) { + case 2: + pat8x8[0] |= PAT_SHIFT(pat8x8[0], 2); /* fall through */ + case 4: + pat8x8[0] |= PAT_SHIFT(pat8x8[0], 4); /* fall through */ + case 8: + pat8x8[0] |= PAT_SHIFT(pat8x8[0], 8); /* fall through */ + case 16: + pat8x8[0] |= PAT_SHIFT(pat8x8[0], 16); + case 32: + pat8x8[1] = pat8x8[0]; + break; + case 64: + pat8x8[1] = pat[1]; + break; + default: + BuildPattern(pat[0], length, pat8x8); + } +/* + ErrorF("%X %d, %X %X\n", pat[0], length, pat8x8[0], pat8x8[1]); +*/ + /* LOAD PATTERN COLORS AND DATA */ + + GFX(set_mono_pattern((unsigned int)bg, (unsigned int)fg, + pat8x8[0], pat8x8[1], (unsigned char)trans)); + + /* CHECK IF PLANEMASK IS NOT USED (ALL PLANES ENABLED) */ + + if (planemask == 0xFFFFFFFF) { + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + + GFX(set_raster_operation(windowsROPpat[rop & 0x0F])); + } else { + /* SELECT ROP THAT USES SOURCE DATA FOR PLANEMASK */ + + GFX(set_raster_operation(windowsROPsrcMask[rop & 0x0F])); + } +} + +/*--------------------------------------------------------------------------- + * GX2SubsequentDashedBresenhamLine + * + * Description :This function is used to render a vector using the + * specified bresenham parameters. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x1 :Specifies the starting x position + * y1 :Specifies starting y possition + * absmaj :Specfies the Bresenman absolute major. + * absmin :Specfies the Bresenman absolute minor. + * err :Specifies the bresenham err term. + * len :Specifies the length of the vector interms of pixels. + * octant :not used in this function,may be added for standard + * interface. + * Returns :none + * + * Comments :none + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-line500). + * - x11perf: line segments (-seg500). +*---------------------------------------------------------------------------- +*/ +void +GX2SubsequentDashedBresenhamLine(ScrnInfoPtr pScreenInfo, + int x1, int y1, int absmaj, int absmin, + int err, int len, int octant) +{ + int axial, init, diag; + + DEBUGMSG(0, (0, 0, "BLine %d, %d, %d, %d, %d, %d, %d\n", + x1, y1, absmaj, absmin, err, len, octant)); + + /* DETERMINE BRESENHAM PARAMETERS */ + + axial = ((int)absmin << 1); + init = axial - (int)absmaj; + diag = init - (int)absmaj; + + /* ADJUST INITIAL ERROR + * * Adjust by -1 for certain directions so that the vector + * * hits the same pixels when drawn in either direction. + * * The Gamma value is assumed to account for the initial + * * error adjustment for clipped lines. + */ + + init += err; + + /* CALL ROUTINE TO DRAW VECTOR */ + + gfx2_set_pattern_origin(x1, y1); + gfx2_bresenham_line(CALC_FBOFFSET(x1, y1), + (unsigned short)len, (unsigned short)init, + (unsigned short)axial, (unsigned short)diag, + (unsigned short)vector_mode_table[octant]); + +} +#endif + +#if !defined(STB_X) +/*---------------------------------------------------------------------------- + * OPTGX2SetupForCPUToScreenColorExpandFill + * + * Description :This routine is called to setup the background and + * foreground colors,rop and plane mask for future + * color expansion blits from source patterns stored + * in system memory(non durango version). + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * fg :Specifies the foreground color + * bg :Specifies the background color + * rop :Specifies rop values. + * planemask :Specifies the value of masking from rop data + * + * Returns :none. + * + * Comments : + * All the text gets rendered through this i/f. We have given + * the offscreen memory loaction to temporarily put the text + * bitmap. Generaly all the text comes as bitmap and then gets + * rendered via the HOST_SRC(similar to scratchpad in GX1). Now + * since we already have the bitmap in offscreen we can do a + * src_FB_EXPAND. This is the best possible you can do with GX2 + * CPU-to-screen color expansion + * x11perf -ftext (pure indirect): + * x11perf -oddsrect10 + * x11perf -oddsrect100 + * x11perf -bigsrect10 + * x11perf -bigsrect100 + * x11perf -polytext + * x11perf -polytext16 + * x11perf -seg1 + * x11perf -copyplane10 + * x11perf -copyplane100 + * x11perf -putimagexy10 + * x11perf -putimagexy100 +*---------------------------------------------------------------------------- +*/ + +void +OPTGX2SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScreenInfo, + int fg, int bg, int rop, + unsigned int planemask) +{ + int trans = (bg == -1); + + GeodeROP = XAACopyROP_PM[rop]; + + if ((GeodeROP & 0x55) ^ ((GeodeROP >> 1) & 0x55)) { + Geode_blt_mode = MGP_BM_DST_REQ; + } else { + Geode_blt_mode = 0; + } + if (trans) + GeodeROP |= MGP_RM_SRC_TRANS; + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_PAT_COLOR_0, (unsigned long)planemask); + WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GeodeROP); + WRITE_GP32(MGP_SRC_COLOR_FG, fg); + WRITE_GP32(MGP_SRC_COLOR_BG, bg); +} + +/*------------------------------------------------------------------------------- + * OPTGX2SubsequentCPUToScreenColorExpandFill + * + * Description :This routine is used to perform color expansion blits from + * source patterns stored in system memory using the previously + * set rop and plane mask.(non durango version) + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * x and y :Specifies the x and y co-ordinatesarea. + * w and h :Specifies width and height respectively. + * + * Returns :none + * + * Comments :none + *-------------------------------------------------------------------------------- + */ +void +OPTGX2SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_OFFSET, ((unsigned int)(localRecPtr->ColorExpandBase - + pGeode->FBBase))); + WRITE_GP32(MGP_DST_OFFSET, CALC_FBOFFSET(x, y)); + WRITE_GP32(MGP_WID_HEIGHT, (((unsigned long)w) << 16) | h); + WRITE_GP32(MGP_STRIDE, (((w + 31) >> 5) << 18) | pGeode->Pitch); + SetCPUToScreen = 1; +} + +/*---------------------------------------------------------------------------- + * OPTGX2SetupForFillRectSolid. + * + * Description :This routine is called to setup the solid pattern + * color for future rectangular fills or vectors. + * (non durango version) + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * color :Specifies the color to be filled up in defined area. + * rop :Specifies the raster operation value. + * planemask :Specifies the masking value based rop srcdata. + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +OPTGX2SetupForFillRectSolid(ScrnInfoPtr pScreenInfo, + int color, int rop, unsigned int planemask) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_PAT_COLOR_0, (unsigned long)color); + + WRITE_GP32(MGP_STRIDE, pGeode->Pitch); + + if (planemask == 0xFFFFFFFF) { + GeodeROP = XAAPatternROP[rop]; + } else { + WRITE_GP32(MGP_SRC_COLOR_FG, (unsigned long)planemask); + GeodeROP = XAAPatternROP_PM[rop]; + } + + WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GeodeROP); + + Geode_blt_mode = 0; + if (!((GeodeROP & 0x33) ^ ((GeodeROP >> 2) & 0x33))) + Geode_blt_mode = MGP_BM_SRC_MONO; + + if ((GeodeROP & 0x55) ^ ((GeodeROP >> 1) & 0x55)) { + Geode_blt_mode |= MGP_BM_DST_REQ; + Geode_vector_mode = MGP_VM_DST_REQ; + } else { + Geode_vector_mode = 0; + } +} + + /*---------------------------------------------------------------------------- + * OPTGX2SubsequentFillRectSolid. + * + * Description :This routine is used to fill the rectangle of previously + * specified solid pattern. + * (non durango version) + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * x and y :Specifies the x and y co-ordinatesarea. + * w and h :Specifies width and height respectively. + * + * Returns :none + * + * Comments :desired pattern can be set before this function by + * gfx_set_solid_pattern. + * Sample application uses: + * - Window backgrounds. + * - x11perf: rectangle tests (-rect500). + * - x11perf: fill trapezoid tests (-trap100). + * - x11perf: horizontal line segments (-hseg500). + *---------------------------------------------------------------------------- +*/ +void +OPTGX2SubsequentFillRectSolid(ScrnInfoPtr pScreenInfo, + int x, int y, int width, int height) +{ + DEBUGMSG(0, (0, 0, "FillRect %d %d %dx%d\n", x, y, width, height)); + + GFX_PATTERN_FILL(x, y, width, height); +} + +/*---------------------------------------------------------------------------- + * OPTGX2SetupForScreenToScreenCopy + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality. + * (non durango version) + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * xdir :This is set based on rop data. + * ydir :This is set based on rop data. + * rop :sets the raster operation + * transparency:tobeadded + * planemask :Specifies the value of masking from rop data + + * Returns :none + * + * Comments :The patterns specified is ignored inside the function +*---------------------------------------------------------------------------- +*/ +void +OPTGX2SetupForScreenToScreenCopy(ScrnInfoPtr pScreenInfo, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + GeodeROP = XAACopyROP_PM[rop]; + + Geode_blt_mode = MGP_BM_SRC_FB; + + /* CALCULATE THE DIRECTION OF THE BLT */ + if ((GeodeROP & 0x55) ^ ((GeodeROP >> 1) & 0x55)) { + Geode_blt_mode |= MGP_BM_DST_REQ; + } + + GU2_WAIT_PENDING; + + if (transparency_color != -1) { + WRITE_GP32(MGP_SRC_COLOR_FG, transparency_color); + WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF); + GeodeROP = MGP_RM_SRC_TRANS | 0xCC; + } + WRITE_GP32(MGP_PAT_COLOR_0, planemask); + WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GeodeROP); + WRITE_GP32(MGP_STRIDE, pGeode->Pitch | (pGeode->Pitch << 16)); +} + +/*---------------------------------------------------------------------------- + * OPTGX2SubsquentScreenToScreenCopy + * + * Description :This function is called to perform a screen to screen + * BLT using the previously specified planemask,raster + * operation and * transparency flag + * (non durango version) + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * srcx :x -coordinates of the source window + * srcy :y-co-ordinates of the source window + * dstx :x -coordinates of the destination window + * dsty :y-co-ordinates of the destination window + * width :Specifies width of the window to be copied + * height :Height of the window to be copied. + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses (non-transparent): + * - Moving windows. + * - x11perf: scroll tests (-scroll500). + * - x11perf: copy from window to window (-copywinwin500). + * + * No application found using transparency. +*---------------------------------------------------------------------------- +*/ +void +OPTGX2SubsequentScreenToScreenCopy(ScrnInfoPtr pScreenInfo, + int srcx, int srcy, int dstx, int dsty, + int width, int height) +{ + unsigned int srcoffset, dstoffset, blt_mode, size; + + DEBUGMSG(0, (0, 0, "Scr2scr %d %d %d %d %dx%d\n", + srcx, srcy, dstx, dsty, width, height)); + + size = (((unsigned int)width) << 16) | height; + + blt_mode = Geode_blt_mode; + + if (dstx > srcx) { + blt_mode |= MGP_BM_NEG_XDIR; + srcx += width - 1; + dstx += width - 1; + } + if (dsty > srcy) { + blt_mode |= MGP_BM_NEG_YDIR; + srcy += height - 1; + dsty += height - 1; + } + + /* CALCULATE STARTING OFFSETS */ + + srcoffset = CALC_FBOFFSET(srcx, srcy); + dstoffset = CALC_FBOFFSET(dstx, dsty) & 0xFFFFFF; + + /* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */ + /* This is a quirk of the hardware. */ + + if (Geode_blt_mode & MGP_BM_NEG_XDIR) { + srcoffset += (1 << gu2_xshift) - 1; + dstoffset += (1 << gu2_xshift) - 1; + } + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_SRC_OFFSET, srcoffset); + WRITE_GP32(MGP_DST_OFFSET, dstoffset); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_BLT_MODE, blt_mode); +} + +/*---------------------------------------------------------------------------- + * OPTGX2SetupForImageWrite + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality.(non durango version) + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * rop :sets the raster operation + * transparency_color :tobeadded + * planemask :Specifies the value of masking from rop data + * bpp :bits per pixel of the source pixmap + * depth :depth of the source pixmap. + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +OPTGX2SetupForImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth) +{ + OPTGX2SetupForScreenToScreenCopy(pScreenInfo, + 0, 0, rop, planemask, transparency_color); +} + +void +OPTGX2SubsequentImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, int skipleft) +{ + Geodedstx = x; + Geodedsty = y; + Geodewidth = w; + Geodeheight = h; + + SetImageWriteRect = 1; +} + +/*---------------------------------------------------------------------------- + * OPTGX2SetupForScanlineImageWrite + * + * Description :This function is used to set up the planemask and raster + * for future Bliting functionality.(non durango version) + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * rop :sets the raster operation + * transparency_color:tobeadded + * planemask :Specifies the value of masking from rop data + * bpp :bits per pixel of the source pixmap + * depth :depth of the source pixmap. + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +OPTGX2SetupForScanlineImageWrite(ScrnInfoPtr pScreenInfo, + int rop, unsigned int planemask, + int transparency_color, int bpp, int depth) +{ + Geodebpp = bpp; + OPTGX2SetupForScreenToScreenCopy(pScreenInfo, + 0, 0, rop, planemask, transparency_color); +} + +/*---------------------------------------------------------------------------- + * OPTGX2SubsequentScanlineImageWriteRect + * + * Description :This function is used to set up the x,y corordinates and width + * &height for future Bliting functionality.(non durango version) + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x :destination x + * y :destination y + * w :Specifies the width of the rectangle to be copied + * h :Specifies the height of the rectangle to be copied + * Returns :none + * + * Comments :none + *---------------------------------------------------------------------------- +*/ +void +OPTGX2SubsequentScanlineImageWriteRect(ScrnInfoPtr pScreenInfo, + int x, int y, int w, int h, + int skipleft) +{ + Geodedstx = x; + Geodedsty = y; + Geodewidth = w; + Geodeheight = h; + GeodeCounter = 0; +} + +/*---------------------------------------------------------------------------- + * OPTGX2SubsquentImageWriteScanline + * + * Description :This function is called to + * BLT using the previously specified planemask,raster + * operation and transparency flag(non durango version) + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * + * Returns :none + * + * Comments :The patterns specified is ignored inside the function + * Sample application uses (non-transparent): + * - Moving windows. + * - x11perf: scroll tests (-scroll500). + * - x11perf: copy from window to window (-copywinwin500). + * + * No application found using transparency. +*---------------------------------------------------------------------------- +*/ + +void +OPTGX2SubsequentImageWriteScanline(ScrnInfoPtr pScreenInfo, int bufno) +{ + GeodePtr pGeode; + + int blt_height = 0; + char blit = FALSE; + + pGeode = GEODEPTR(pScreenInfo); + GeodeCounter++; + + if ((Geodeheight <= pGeode->NoOfImgBuffers) && + (GeodeCounter == Geodeheight)) { + blit = TRUE; + blt_height = Geodeheight; + } else if ((Geodeheight > pGeode->NoOfImgBuffers) + && (GeodeCounter == pGeode->NoOfImgBuffers)) { + blit = TRUE; + Geodeheight -= pGeode->NoOfImgBuffers; + blt_height = pGeode->NoOfImgBuffers; + } else + return; + + if (blit) { + blit = FALSE; + GeodeCounter = 0; + OPTGX2SubsequentScreenToScreenCopy(pScreenInfo, + Geodesrcx, Geodesrcy, Geodedstx, + Geodedsty, Geodewidth, blt_height); + Geodedsty += blt_height; + GU2_WAIT_BUSY; + } +} + +/*---------------------------------------------------------------------------- + * OPTGX2SetupForSolidLine + * + * Description :This function is used setup the solid line color for + * future line draws. + * + * + * Parameters. + * pScreenInfo :Screen handler pointer having screen information. + * color :Specifies the color value od line + * rop :Specifies rop values. + * Planemask :Specifies planemask value. + * Returns :none + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +void +OPTGX2SetupForSolidLine(ScrnInfoPtr pScreenInfo, + int color, int rop, unsigned int planemask) +{ + OPTGX2SetupForFillRectSolid(pScreenInfo, color, rop, planemask); +} + +/*--------------------------------------------------------------------------- + * OPTGX2SubsequentBresenhamLine + * + * Description :This function is used to render a vector using the + * specified bresenham parameters. + * + * Parameters: + * pScreenInfo :Screen handler pointer having screen information. + * x1 :Specifies the starting x position + * y1 :Specifies starting y possition + * absmaj :Specfies the Bresenman absolute major. + * absmin :Specfies the Bresenman absolute minor. + * err :Specifies the bresenham err term. + * len :Specifies the length of the vector interms of pixels. + * octant :not used in this function,may be added for standard + * interface. + * Returns :none + * + * Comments :none + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-seg500). +*---------------------------------------------------------------------------- +*/ +void +OPTGX2SubsequentBresenhamLine(ScrnInfoPtr pScreenInfo, + int x1, int y1, int absmaj, int absmin, + int err, int len, int octant) +{ + int axial, init, diag; + + DEBUGMSG(0, (0, 0, "BLine %d, %d, %d, %d, %d, %d, %d\n", + x1, y1, absmaj, absmin, err, len, octant)); + + /* DETERMINE BRESENHAM PARAMETERS */ + + axial = ((int)absmin << 1); + init = axial - (int)absmaj; + diag = init - (int)absmaj; + + /* ADJUST INITIAL ERROR + * * Adjust by -1 for certain directions so that the vector + * * hits the same pixels when drawn in either direction. + * * The Gamma value is assumed to account for the initial + * * error adjustment for clipped lines. + */ + + init += err; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, CALC_FBOFFSET(x1, y1)); + WRITE_GP32(MGP_VEC_ERR, + (((unsigned long)axial) << 16) | (unsigned short)diag); + WRITE_GP32(MGP_VEC_LEN, + (((unsigned long)len) << 16) | (unsigned short)init); + WRITE_GP32(MGP_VECTOR_MODE, + (Geode_vector_mode | vector_mode_table[octant])); +} + +void +OPTGX2SubsequentSolidTwoPointLine(ScrnInfoPtr pScreenInfo, + int x0, int y0, int x1, int y1, int flags) +{ + long dx, dy, dmaj, dmin; + long axialerr, diagerr, initerr; + unsigned short vec_flags = 0; + + dx = ABS(x1, x0); + dy = ABS(y1, y0); + if (dx >= dy) { + dmaj = dx; + dmin = dy; + vec_flags = VM_X_MAJOR; + if (x1 > x0) + vec_flags |= VM_MAJOR_INC; + if (y1 > y0) + vec_flags |= VM_MINOR_INC; + } else { + dmaj = dy; + dmin = dx; + vec_flags = VM_Y_MAJOR; + if (x1 > x0) + vec_flags |= VM_MINOR_INC; + if (y1 > y0) + vec_flags |= VM_MAJOR_INC; + } + + axialerr = dmin << 1; + diagerr = (dmin - dmaj) << 1; + initerr = (axialerr - dmaj); + + if (!(vec_flags & VM_MINOR_INC)) + initerr--; + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, CALC_FBOFFSET(x0, y0)); + WRITE_GP32(MGP_VEC_ERR, + (((unsigned long)axialerr) << 16) | (unsigned short)diagerr); + WRITE_GP32(MGP_VEC_LEN, + (((unsigned long)dmaj) << 16) | (unsigned short)initerr); + WRITE_GP32(MGP_VECTOR_MODE, (Geode_vector_mode | vec_flags)); +} + +/*--------------------------------------------------------------------------- + * OPTGX2SubsequentHorVertLine + * + * This routine is called to render a vector using the specified Bresenham + * parameters. + * + * Sample application uses: + * - Window outlines on window move. + * - x11perf: line segments (-hseg500). + * - x11perf: line segments (-vseg500). + *--------------------------------------------------------------------------- + */ +void +OPTGX2SubsequentHorVertLine(ScrnInfoPtr pScreenInfo, + int x, int y, int len, int dir) +{ + DEBUGMSG(0, (0, 0, "HLine %d, %d, %d, %d\n", x, y, len, dir)); +#if 1 + GFX_PATTERN_FILL(x, y, + (unsigned short)((dir == DEGREES_0) ? len : 1), + (unsigned short)((dir == DEGREES_0) ? 1 : len)); +#else + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, CALC_FBOFFSET(x, y)); + WRITE_GP32(MGP_VEC_ERR, 0); + WRITE_GP32(MGP_VEC_LEN, + (((unsigned long)len) << 16) | (unsigned short)-len); + WRITE_GP32(MGP_VECTOR_MODE, + (Geode_vector_mode | + vector_mode_table[(dir == DEGREES_0) ? 2 : 5])); +#endif +} + +#if DASHED_SUPPORT +/* Setup for XAA dashed lines. + + Tests: xtest CH05/stdshs, XFree86/drwln + + x11perf -dseg100 + x11perf -dline100 + x11perf -ddline100 +*/ +void +OPTGX2SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, + unsigned char *pattern) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + CARD32 *pat = (CARD32 *) pattern; + CARD32 pat8x8[2]; + + pat8x8[0] = pat[0]; + switch (length) { + case 2: + pat8x8[0] |= PAT_SHIFT(pat8x8[0], 2); /* fall through */ + case 4: + pat8x8[0] |= PAT_SHIFT(pat8x8[0], 4); /* fall through */ + case 8: + pat8x8[0] |= PAT_SHIFT(pat8x8[0], 8); /* fall through */ + case 16: + pat8x8[0] |= PAT_SHIFT(pat8x8[0], 16); + case 32: + pat8x8[1] = pat8x8[0]; + break; + case 64: + pat8x8[1] = pat[1]; + break; + default: + BuildPattern(pat[0], length, pat8x8); + } + /* LOAD PATTERN COLORS AND DATA */ + + /* SET PATTERN FLAGS */ + + if (planemask == 0xFFFFFFFF) { + GeodeROP = XAAPatternROP[rop & 0x0F]; + } else { + GeodeROP = XAAPatternROP_PM[rop & 0x0F]; + } + if (bg == -1) + GeodeROP |= MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS; + else + GeodeROP |= MGP_RM_PAT_MONO; + + if ((GeodeROP & 0x55) ^ ((GeodeROP >> 1) & 0x55)) { + Geode_blt_mode = MGP_BM_DST_REQ; + Geode_vector_mode = MGP_VM_DST_REQ; + } else { + Geode_blt_mode = MGP_BM_SRC_MONO; + Geode_vector_mode = 0; + } + + /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GeodeROP); + WRITE_GP32(MGP_PAT_COLOR_0, bg); + WRITE_GP32(MGP_PAT_COLOR_1, fg); + WRITE_GP32(MGP_PAT_DATA_0, pat8x8[0]); + WRITE_GP32(MGP_PAT_DATA_1, pat8x8[1]); + WRITE_GP32(MGP_STRIDE, pGeode->Pitch); + +} + +void +OPTGX2SubsequentDashedBresenhamLine(ScrnInfoPtr pScreenInfo, + int x1, int y1, int absmaj, int absmin, + int err, int len, int octant) +{ + int axial, init, diag; + unsigned long gu2_pattern_origin; + + DEBUGMSG(0, (0, 0, "BLine %d, %d, %d, %d, %d, %d, %d\n", + x1, y1, absmaj, absmin, err, len, octant)); + + /* CHECK NULL LENGTH */ + + if (!len) + return; + + /* DETERMINE BRESENHAM PARAMETERS */ + + axial = ((int)absmin << 1); + init = axial - (int)absmaj; + diag = init - (int)absmaj; + + /* ADJUST INITIAL ERROR + * * Adjust by -1 for certain directions so that the vector + * * hits the same pixels when drawn in either direction. + * * The Gamma value is assumed to account for the initial + * * error adjustment for clipped lines. + */ + + init += err; + + /* CALL ROUTINE TO DRAW VECTOR */ + + gu2_pattern_origin = (((unsigned long)(x1 & 7)) << 26) | + (((unsigned long)(y1 & 7)) << 29); + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, (CALC_FBOFFSET(x1, y1) & 0x00FFFFFF) | + gu2_pattern_origin); + WRITE_GP32(MGP_VEC_ERR, + (((unsigned long)axial) << 16) | (unsigned short)diag); + WRITE_GP32(MGP_VEC_LEN, + (((unsigned long)len) << 16) | (unsigned short)init); + WRITE_GP32(MGP_VECTOR_MODE, (Geode_vector_mode | + vector_mode_table[octant])); +} + +void +OPTGX2SubsequentDashedTwoPointLine(ScrnInfoPtr pScreenInfo, + int x0, int y0, int x1, int y1, int flags) +{ + long dx, dy, dmaj, dmin; + long axialerr, diagerr, initerr; + unsigned long gu2_pattern_origin; + unsigned short vec_flags = 0; + + dx = ABS(x1, x0); + dy = ABS(y1, y0); + if (dx >= dy) { + dmaj = dx; + dmin = dy; + vec_flags = VM_X_MAJOR; + if (x1 > x0) + vec_flags |= VM_MAJOR_INC; + if (y1 > y0) + vec_flags |= VM_MINOR_INC; + } else { + dmaj = dy; + dmin = dx; + vec_flags = VM_Y_MAJOR; + if (x1 > x0) + vec_flags |= VM_MINOR_INC; + if (y1 > y0) + vec_flags |= VM_MAJOR_INC; + } + + axialerr = dmin << 1; + diagerr = (dmin - dmaj) << 1; + initerr = (axialerr - dmaj); + + if (!(vec_flags & VM_MINOR_INC)) + initerr--; + + /* CALL ROUTINE TO DRAW VECTOR */ + + gu2_pattern_origin = (((unsigned long)(x0 & 7)) << 26) | + (((unsigned long)(y0 & 7)) << 29); + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, (CALC_FBOFFSET(x0, y0) & 0x00FFFFFF) | + gu2_pattern_origin); + WRITE_GP32(MGP_VEC_ERR, + (((unsigned long)axialerr) << 16) | (unsigned short)diagerr); + WRITE_GP32(MGP_VEC_LEN, + (((unsigned long)dmaj) << 16) | (unsigned short)initerr); + WRITE_GP16(MGP_VECTOR_MODE, (Geode_vector_mode | vec_flags)); +} +#endif /* DASHED_SUPPORT */ +#endif /* STB_X */ + +#if 0 +void +GX2WriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int skipleft, + int fg, int bg, int rop, unsigned int planemask) +{ + GFX(set_solid_pattern(planemask)); + GFX(set_mono_source(bg, fg, (bg == -1))); + + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(windowsROPpatMask[rop & 0x0F])); + GFX(mono_bitmap_to_screen_blt_swp(0, 0, x, y, + srcwidth << 3, h, src, srcwidth)); +} + +void +GX2WritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, /* bytes */ + int rop, unsigned int planemask, int trans, int bpp, int depth) +{ + /* + * ErrorF("GX2WritePixmap %d %d %d %d %X %d %d %d, %d\n", + * x, y, w, h, src, srcwidth, bpp, depth, trans); + */ + GFX(set_solid_pattern(planemask)); + + /* USE NORMAL PATTERN ROPs IF ALL PLANES ARE ENABLED */ + GFX(set_raster_operation(windowsROPpatMask[rop & 0x0F])); + if (trans == -1) { + GFX(color_bitmap_to_screen_blt(0, 0, x, y, w, h, src, srcwidth)); + } else { + GFX(color_bitmap_to_screen_xblt(0, 0, x, y, w, h, src, + srcwidth, trans)); + } +} + +void +GX2ReadPixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned char *dst, int dstwidth, int bpp, int depth) +{ + ErrorF("GX2ReadPixmap %d %d %d %d %X %d %d %d\n", + x, y, w, h, dst, dstwidth, bpp, depth); +} +#endif +/**************************************************************************/ + +/*---------------------------------------------------------------------------- + * GX2AccelInit. + * + * Description :This function sets up the supported acceleration routines and + * appropriate flags. + * + * Parameters: + * pScreen :Screeen pointer structure. + * + * Returns :TRUE on success and FALSE on Failure + * + * Comments :This function is called in GX2ScreenInit in + geode_driver.c to set * the acceleration. +*---------------------------------------------------------------------------- +*/ +Bool +GX2AccelInit(ScreenPtr pScreen) +{ + GeodePtr pGeode; + ScrnInfoPtr pScreenInfo; + + pScreenInfo = xf86Screens[pScreen->myNum]; + pGeode = GEODEPTR(pScreenInfo); + + switch (pScreenInfo->bitsPerPixel) { + case 8: + gu2_bpp = MGP_RM_BPPFMT_332; + break; + case 16: + gu2_bpp = MGP_RM_BPPFMT_565; + break; + case 32: + gu2_bpp = MGP_RM_BPPFMT_8888; + break; + } + + gu2_xshift = pScreenInfo->bitsPerPixel >> 4; + + switch (pGeode->Pitch) { + case 1024: + gu2_yshift = 10; + break; + case 2048: + gu2_yshift = 11; + break; + case 4096: + gu2_yshift = 12; + break; + case 8192: + gu2_yshift = 13; + break; + } + + /* Getting the pointer for acceleration Inforecord */ + pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec(); + + /* SET ACCELERATION FLAGS */ + localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER; + + /* HOOK SYNCRONIZARION ROUTINE */ + localRecPtr->Sync = GX2AccelSync; + + /* HOOK FILLED RECTANGLES */ + localRecPtr->SetupForSolidFill = OPTACCEL(GX2SetupForFillRectSolid); + localRecPtr->SubsequentSolidFillRect = + OPTACCEL(GX2SubsequentFillRectSolid); + localRecPtr->SolidFillFlags = 0; + + /* HOOK 8x8 Mono EXPAND PATTERNS */ + localRecPtr->SetupForMono8x8PatternFill = GX2SetupFor8x8PatternMonoExpand; + localRecPtr->SubsequentMono8x8PatternFillRect = + GX2Subsequent8x8PatternMonoExpand; + localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST | + HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN; + + localRecPtr->SetupForColor8x8PatternFill = + GX2SetupFor8x8PatternColorExpand; + localRecPtr->SubsequentColor8x8PatternFillRect = + GX2Subsequent8x8PatternColorExpand; + /* Color expansion */ + localRecPtr->Color8x8PatternFillFlags = + BIT_ORDER_IN_BYTE_MSBFIRST | + SCANLINE_PAD_DWORD | HARDWARE_PATTERN_SCREEN_ORIGIN; + + /* HOOK SCREEN TO SCREEN COPIES + * * Set flag to only allow copy if transparency is enabled. + */ + localRecPtr->SetupForScreenToScreenCopy = + OPTACCEL(GX2SetupForScreenToScreenCopy); + localRecPtr->SubsequentScreenToScreenCopy = + OPTACCEL(GX2SubsequentScreenToScreenCopy); + localRecPtr->ScreenToScreenCopyFlags = 0; + + /* HOOK BRESENHAM SOLID LINES */ + /* Do not hook unless flag can be set preventing use of planemask. */ + localRecPtr->SolidLineFlags = NO_PLANEMASK; + localRecPtr->SetupForSolidLine = OPTACCEL(GX2SetupForSolidLine); + localRecPtr->SubsequentSolidBresenhamLine = + OPTACCEL(GX2SubsequentBresenhamLine); + localRecPtr->SubsequentSolidHorVertLine = + OPTACCEL(GX2SubsequentHorVertLine); + localRecPtr->SubsequentSolidTwoPointLine = + OPTACCEL(GX2SubsequentSolidTwoPointLine); + localRecPtr->SolidBresenhamLineErrorTermBits = 15; + +#if DASHED_SUPPORT + localRecPtr->SetupForDashedLine = OPTACCEL(GX2SetupForDashedLine); + localRecPtr->SubsequentDashedBresenhamLine = + OPTACCEL(GX2SubsequentDashedBresenhamLine); + localRecPtr->SubsequentSolidTwoPointLine = + OPTACCEL(GX2SubsequentDashedTwoPointLine); + localRecPtr->DashedBresenhamLineErrorTermBits = 15; + localRecPtr->DashPatternMaxLength = 64; + localRecPtr->DashedLineFlags = NO_PLANEMASK | + LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED; +#endif +#if SCR2SCREXP + /* Color expansion */ + localRecPtr->ScreenToScreenColorExpandFillFlags = + BIT_ORDER_IN_BYTE_MSBFIRST | NO_TRANSPARENCY; + + localRecPtr->SetupForScreenToScreenColorExpandFill = + (GX2SetupForScreenToScreenColorExpandFill); + localRecPtr->SubsequentScreenToScreenColorExpandFill = + (GX2SubsequentScreenToScreenColorExpandFill); +#endif + /* + * ImageWrite. + * + * SInce this uses off-screen scanline buffers, it is only of use when + * complex ROPs are used. But since the current XAA pixmap cache code + * only works when an ImageWrite is provided, the NO_GXCOPY flag is + * temporarily disabled. + */ + if (pGeode->AccelImageWriteBufferOffsets) { + /* Color expansion */ + localRecPtr->CPUToScreenColorExpandFillFlags = + BIT_ORDER_IN_BYTE_MSBFIRST | + NO_PLANEMASK | SYNC_AFTER_COLOR_EXPAND | SCANLINE_PAD_DWORD; + localRecPtr->ColorExpandBase = pGeode->AccelImageWriteBufferOffsets[0]; + localRecPtr->ColorExpandRange = pGeode->NoOfImgBuffers << gu2_yshift; + + localRecPtr->SetupForCPUToScreenColorExpandFill = + OPTACCEL(GX2SetupForCPUToScreenColorExpandFill); + localRecPtr->SubsequentCPUToScreenColorExpandFill = + OPTACCEL(GX2SubsequentCPUToScreenColorExpandFill); + +#if IMGWRITE_SUPPORT + localRecPtr->ImageWriteFlags = NO_PLANEMASK | + SCANLINE_PAD_DWORD | SYNC_AFTER_IMAGE_WRITE; + localRecPtr->ImageWriteBase = pGeode->AccelImageWriteBufferOffsets[0]; + localRecPtr->ImageWriteRange = pGeode->NoOfImgBuffers << gu2_yshift; + localRecPtr->SetupForImageWrite = OPTACCEL(GX2SetupForImageWrite); + localRecPtr->SubsequentImageWriteRect = + OPTACCEL(GX2SubsequentImageWriteRect); +#endif /* IMGWRITE_SUPPORT */ + + localRecPtr->ScanlineImageWriteFlags = + localRecPtr->ScreenToScreenCopyFlags; + localRecPtr->ScanlineImageWriteBuffers = + pGeode->AccelImageWriteBufferOffsets; + localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers; + localRecPtr->ImageWriteRange = pGeode->NoOfImgBuffers << gu2_yshift; + localRecPtr->SetupForScanlineImageWrite = + OPTACCEL(GX2SetupForScanlineImageWrite); + localRecPtr->SubsequentScanlineImageWriteRect = + OPTACCEL(GX2SubsequentScanlineImageWriteRect); + localRecPtr->SubsequentImageWriteScanline = + OPTACCEL(GX2SubsequentImageWriteScanline); + + ImgBufOffset = pGeode->AccelImageWriteBufferOffsets[0] - pGeode->FBBase; + Geodesrcy = ImgBufOffset >> gu2_yshift; + + Geodesrcx = ImgBufOffset & (pGeode->Pitch - 1); + Geodesrcx /= (pScreenInfo->bitsPerPixel >> 3); + } else { + localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES; + } +#if 0 +#if !defined(STB_X) + localRecPtr->WriteBitmap = GX2WriteBitmap; +#endif + localRecPtr->WritePixmap = GX2WritePixmap; + localRecPtr->ReadPixmap = GX2ReadPixmap; +#endif + + return (XAAInit(pScreen, localRecPtr)); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_cursor.c new file mode 100644 index 000000000..5e4b35106 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_cursor.c @@ -0,0 +1,393 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_cursor.c,v 1.5 2003/02/21 16:51:09 alanh Exp $ */ +/* + * $Workfile: nsc_gx2_cursor.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: Xfree cursor implementation routines + * for geode HWcursor init.setting cursor color,image etc + * are done here. + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "nsc.h" + +/* Forward declarations of the functions */ +Bool GX2HWCursorInit(ScreenPtr pScreen); +static void GX2SetCursorColors(ScrnInfoPtr pScreenInfo, int bg, int fg); +static void GX2SetCursorPosition(ScrnInfoPtr pScreenInfo, int x, int y); +void GX2LoadCursorImage(ScrnInfoPtr pScreenInfo, unsigned char *src); +void GX2HideCursor(ScrnInfoPtr pScreenInfo); +void GX2ShowCursor(ScrnInfoPtr pScreenInfo); +static Bool GX2UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); +extern void GX2SetVideoPosition(int x, int y, int width, int height, + short src_w, short src_h, short drw_w, + short drw_h, int id, int offset, + ScrnInfoPtr pScrn); + +/*---------------------------------------------------------------------------- + * GX2HWCursorInit. + * + * Description :This function sets the cursor information by probing the + * hardware. + * + * Parameters. + * pScreen :Screeen pointer structure. + * + * Returns :TRUE on success and FALSE on Failure + * + * Comments :Geode supports the hardware_cursor,no need to enable SW + * cursor. +*---------------------------------------------------------------------------- +*/ +Bool +GX2HWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + xf86CursorInfoPtr infoPtr; + + infoPtr = xf86CreateCursorInfoRec(); + if (!infoPtr) + return FALSE; + /* the geode structure is intiallized with the cursor infoRec */ + pGeode->CursorInfo = infoPtr; + infoPtr->MaxWidth = 32; + infoPtr->MaxHeight = 32; + /* seeting up the cursor flags */ + infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; + /* cursor info ptr is intiallized with the values obtained from + * * durnago calls + */ + infoPtr->SetCursorColors = GX2SetCursorColors; + infoPtr->SetCursorPosition = GX2SetCursorPosition; + infoPtr->LoadCursorImage = GX2LoadCursorImage; + infoPtr->HideCursor = GX2HideCursor; + infoPtr->ShowCursor = GX2ShowCursor; + infoPtr->UseHWCursor = GX2UseHWCursor; + return (xf86InitCursor(pScreen, infoPtr)); +} + +/*---------------------------------------------------------------------------- + * GX2SetCursorColors. + * + * Description :This function sets the cursor foreground and background + * colors + * Parameters: + * pScreen: Screeen pointer structure. + * bg: Specifies the color value of cursor background color. + * fg: Specifies the color value of cursor foreground color. + * Returns: none. + * + * Comments: The integer color value passed by this function is + * converted into * RGB value by the gfx_set_color routines. + *---------------------------------------------------------------------------- + */ +static void +GX2SetCursorColors(ScrnInfoPtr pScreenInfo, int bg, int fg) +{ + GFX(set_cursor_colors(bg, fg)); +} + +/*---------------------------------------------------------------------------- + * GX2SetCursorPosition. + * + * Description :This function sets the cursor co -ordinates and enable the + * cursor. + * + * Parameters: + * pScreen: Screeen pointer structure. + * x: Specifies the x-cordinates of the cursor. + * y: Specifies the y co-ordinate of the cursor. + * Returns: none. + * + *---------------------------------------------------------------------------- + */ +static void +GX2SetCursorPosition(ScrnInfoPtr pScreenInfo, int x, int y) +{ + unsigned long offset; + static int panOffset = 0; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + unsigned short xhot = 0, yhot = 0; + + if (x < 0) { + xhot = (unsigned short)(-x); + x = 0; + } + if (y < 0) { + yhot = (unsigned short)(-y); + y = 0; + } + + GFX(set_cursor_position(pGeode->CursorStartOffset, x, y, xhot, yhot)); + GFX(set_cursor_enable(1)); + + if ((pGeode->OverlayON) && (pGeode->Panel)) { +#if defined(STB_X) + Gal_get_display_offset(&offset); +#else + offset = gfx_get_display_offset(); +#endif + if (offset != panOffset) { + GX2SetVideoPosition(pGeode->video_x, pGeode->video_y, + pGeode->video_w, pGeode->video_h, + pGeode->video_srcw, pGeode->video_srch, + pGeode->video_dstw, pGeode->video_dsth, + pGeode->video_id, pGeode->video_offset, + pGeode->video_scrnptr); + panOffset = offset; + } + } +} + +/*---------------------------------------------------------------------------- + * GX2LoadCursorImage + * + * Description :This function loads the 32x32 cursor pattern.The shape + * and color is set by AND and XOR masking of arrays of 32 + * DWORD. + * Parameters: + * pScreen: Screeen pointer structure. + * src : Specifies cursor data. + * Returns : none + * + *---------------------------------------------------------------------------- +*/ +void +GX2LoadCursorImage(ScrnInfoPtr pScreenInfo, unsigned char *src) +{ + int i, j; + unsigned long shape; + unsigned long mask; + unsigned long andMask[32] = { 0, }; + unsigned long xorMask[32] = { 0, }; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + j = 0; + for (i = 0; i < 32; i++) { + if (src) { + shape = ((unsigned long)src[i * 4] << 24) | + ((unsigned long)src[i * 4 + 1] << 16) | + ((unsigned long)src[i * 4 + 2] << 8) | + ((unsigned long)src[i * 4 + 3] << 0); + mask = ((unsigned long)src[i * 4 + 128] << 24) | + ((unsigned long)src[i * 4 + 1 + 128] << 16) | + ((unsigned long)src[i * 4 + 2 + 128] << 8) | + ((unsigned long)src[i * 4 + 3 + 128] << 0); + } else { + mask = 0x0; + shape = 0xFFFFFFFF; + } + + andMask[i] = ~(mask); + xorMask[i] = shape & mask; + } + + GFX(set_cursor_shape32(pGeode->CursorStartOffset, andMask, xorMask)); +} + +/*---------------------------------------------------------------------------- + * GX2HideCursor. + * + * Description :This function will disable the cursor. + * + * Parameters: + * pScreen: Handles to the Screeen pointer structure. + * + * Returns: none. + * + * Comments: gfx_set_cursor enable function is hardcoded to disable + * the cursor. + *---------------------------------------------------------------------------- + */ +void +GX2HideCursor(ScrnInfoPtr pScreenInfo) +{ + GFX(set_cursor_enable(0)); +} + +/*---------------------------------------------------------------------------- + * GX2ShowCursor + * + * Description :This function will enable the cursor. + * + * Parameters: + * pScreen :Handles to the Screeen pointer structure. + * + * Returns :none + * + * Comments :gfx_set_cursor enable function is hardcoded to enable the + * cursor + *---------------------------------------------------------------------------- +*/ +void +GX2ShowCursor(ScrnInfoPtr pScreenInfo) +{ + GFX(set_cursor_enable(1)); +} + +/*---------------------------------------------------------------------------- + * GX2UseHwCursor. + * + * Description :This function will sets the hardware cursor flag in + * pscreen structure. + * + * Parameters. + * pScreen :Handles to the Screeen pointer structure. + * + * Returns :none + * + * Comments :none + * + *---------------------------------------------------------------------------- +*/ +static Bool +GX2UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScreenInfo = XF86SCRNINFO(pScreen); + + if (pScreenInfo->currentMode->Flags & V_DBLSCAN) + return FALSE; + return TRUE; +} + +/* End of File */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c new file mode 100644 index 000000000..2413fb065 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c @@ -0,0 +1,509 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c,v 1.2 2003/01/14 09:34:32 alanh Exp $ */ +/* + * $Workfile: nsc_gx2_dga.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File contents: DGA(Direct Acess Graphics mode) is feature of + * XFree86 that allows the program to access directly to video + * memory on the graphics card.DGA supports the double + * flickering.This file has the functions to support the DGA + * modes. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xaa.h" +#include "xaalocal.h" +#include "nsc.h" +#include "dgaproc.h" + +/* forward declarations */ +Bool GX2DGAInit(ScreenPtr pScreen); +static Bool GX2_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static void GX2_CloseFramebuffer(ScrnInfoPtr pScrn); +static Bool GX2_SetMode(ScrnInfoPtr, DGAModePtr); +static int GX2_GetViewport(ScrnInfoPtr); +static void GX2_SetViewport(ScrnInfoPtr, int, int, int); +static void GX2_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void GX2_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); + +extern void GX2AdjustFrame(int, int, int, int); +extern Bool GX2SwitchMode(int, DisplayModePtr, int); +extern void GX2AccelSync(ScrnInfoPtr pScreenInfo); + +static DGAFunctionRec GX2DGAFuncs = { + GX2_OpenFramebuffer, + GX2_CloseFramebuffer, + GX2_SetMode, + GX2_SetViewport, + GX2_GetViewport, + GX2AccelSync, + GX2_FillRect, + GX2_BlitRect, + NULL +}; + +/*---------------------------------------------------------------------------- + * GX2DGAInit. + * + * Description :This function is used to intiallize the DGA modes and sets the + viewport based on the screen mode. + * Parameters. + * pScreeen :Pointer to screen info structure. + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :This function prepares the DGA mode settings for + * other func reference. + * +*---------------------------------------------------------------------------- +*/ +Bool +GX2DGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GeodePtr pGeode = GEODEPTR(pScrn); + DGAModePtr modes = NULL, newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int Bpp = pScrn->bitsPerPixel >> 3; + int num = 0; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + DEBUGMSG(0, (0, X_NONE, "GX2DGAInit %d\n", Bpp)); + while (pMode) { + + /* redundant but it can be used in future:if(0). */ + if (0) { /*pScrn->displayWidth != pMode->HDisplay */ + /* memory is allocated for dga to + *setup the viewport and mode parameters + */ + newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + /* one record is allocated here */ + newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + if (!newmodes) { + xfree(modes); + return FALSE; + } + modes = newmodes; + + SECOND_PASS: /* DGA mode flgas and viewport parametrs are set here. */ + + currentMode = modes + num; + num++; + currentMode->mode = pMode; + currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if (pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if (pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = pScrn->depth; + currentMode->bitsPerPixel = pScrn->bitsPerPixel; + currentMode->red_mask = pScrn->mask.red; + currentMode->green_mask = pScrn->mask.green; + currentMode->blue_mask = pScrn->mask.blue; + currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 1; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = pGeode->FBBase; + if (oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = + ((pScrn->displayWidth * Bpp) + 3) & ~3L; + currentMode->imageWidth = pScrn->displayWidth; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + } + pMode = pMode->next; + if (pMode == firstMode) + break; + } + pGeode->numDGAModes = num; + pGeode->DGAModes = modes; + return DGAInit(pScreen, &GX2DGAFuncs, modes, num); +} + +/*---------------------------------------------------------------------------- + * GX2_SetMode. + * + * Description :This function is sets into the DGA mode. + *. + * Parameters. + * pScreeen :Pointer to screen info structure. + * pMode :Points to the DGAmode ptr data + * Returns :TRUE on success and FALSE on failure. + * + * Comments :none. + * + * +*---------------------------------------------------------------------------- +*/ +static Bool +GX2_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) +{ + static int OldDisplayWidth[MAXSCREENS]; + int index = pScrn->pScreen->myNum; + GeodePtr pGeode = GEODEPTR(pScrn); + + DEBUGMSG(0, (0, X_NONE, "GX2_SetMode\n")); + if (!pMode) { + /* restore the original mode + * * put the ScreenParameters back + */ + pScrn->displayWidth = OldDisplayWidth[index]; + DEBUGMSG(0, + (0, X_NONE, "GX2_SetMode !pMode %d\n", pScrn->displayWidth)); + GX2SwitchMode(index, pScrn->currentMode, 0); + pGeode->DGAactive = FALSE; + } else { + if (!pGeode->DGAactive) { /* save the old parameters */ + OldDisplayWidth[index] = pScrn->displayWidth; + pGeode->DGAactive = TRUE; + DEBUGMSG(0, + (0, X_NONE, "GX2_SetMode pMode+ NA %d\n", + pScrn->displayWidth)); + } + pScrn->displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + DEBUGMSG(0, + (0, X_NONE, "GX2_SetMode pMode+ %d\n", pScrn->displayWidth)); + GX2SwitchMode(index, pMode->mode, 0); + } + /* enable/disable Compression */ + if (pGeode->Compression) { + GFX(set_compression_enable(!pGeode->DGAactive)); + } + + /* enable/disable cursor */ + if (pGeode->HWCursor) { + GFX(set_cursor_enable(!pGeode->DGAactive)); + } + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX2_GetViewPort. + * + * Description :This function is Gets the viewport window memory. + *. + * Parameters. + * pScrn :Pointer to screen info structure. + * + * Returns :returns the viewport status. + * + * Comments :none. + * + * +*---------------------------------------------------------------------------- +*/ +static int +GX2_GetViewport(ScrnInfoPtr pScrn) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + return pGeode->DGAViewportStatus; +} + +/*---------------------------------------------------------------------------- + * GX2_SetViewPort. + * + * Description :This function is Gets the viewport window memory. + * + * Parameters. + * pScrn :Pointer to screen info structure. + x :x-cordinate of viewport window + * y :y-codinate of the viewport window. + * flags :indicates the viewport to be flipped or not. + * Returns :returns the viewport status as zero. + * + * Comments :none. + * +*---------------------------------------------------------------------------- +*/ +static void +GX2_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + GX2AdjustFrame(pScrn->pScreen->myNum, x, y, flags); + pGeode->DGAViewportStatus = 0; /*GX2AdjustFrame loops until finished */ +} + +/*---------------------------------------------------------------------------- + * GX2_FillRect. + * + * Description :This function is Gets the viewport window memory. + *. + * Parameters. + * pScrn :Pointer to screen info structure. + * x :x-cordinate of viewport window + * y :y-codinate of the viewport window. + * w :width of the rectangle + * h :height of the rectangle. + * color :color to be filled in rectangle. + * + * Returns :returns the viewport status as zero. + * + * Comments :This function is implemented by solidfill routines.. + * +*---------------------------------------------------------------------------- +*/ +static void +GX2_FillRect(ScrnInfoPtr pScrn, int x, int y, + int w, int h, unsigned long color) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + if (pGeode->AccelInfoRec) { + (*pGeode->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0); + (*pGeode->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); + SET_SYNC_FLAG(pGeode->AccelInfoRec); + } +} + +/*---------------------------------------------------------------------------- + * GX2_BlitRect. + * + * Description :This function implementing Blit and it moves a + * Rectangular block of data from one location to other + * Location. + * + * Parameters. + * pScrn :Pointer to screen info structure. + * srcx :x-cordinate of the src rectangle + * srcy :y-codinate of src rectangle. + * w :width of the rectangle + * h :height of the rectangle. + * dstx :x-cordinate of the dst rectangle. + * dsty :y -coordinates of the dst rectangle. + * Returns :none. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static void +GX2_BlitRect(ScrnInfoPtr pScrn, + int srcx, int srcy, int w, int h, int dstx, int dsty) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + if (pGeode->AccelInfoRec) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pGeode->AccelInfoRec->SetupForScreenToScreenCopy) + (pScrn, xdir, ydir, GXcopy, ~0, -1); + (*pGeode->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrn, srcx, + srcy, dstx, dsty, + w, h); + SET_SYNC_FLAG(pGeode->AccelInfoRec); + } +} + +/*---------------------------------------------------------------------------- + * GX2_OpenFramebuffer. + * + * Description :This function open the framebuffer driver for DGA. + * + * Parameters. + * pScrn :Pointer to screen info structure. + * srcx :x-cordinate of the src rectangle + * srcy :y-codinate of src rectangle. + * w :width of the rectangle + * h :height of the rectangle. + * dstx :x-cordinate of the dst rectangle. + * dsty :y -coordinates of the dst rectangle. + * Returns :none. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static Bool +GX2_OpenFramebuffer(ScrnInfoPtr pScrn, + char **name, unsigned char **mem, + int *size, int *offset, int *flags) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char *)pGeode->FBLinearAddr; + *size = pGeode->FBSize; + *offset = 0; + *flags = DGA_NEED_ROOT; + return TRUE; +} + +static void +GX2_CloseFramebuffer(ScrnInfoPtr pScrn) +{ +} + +/* end of file */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_driver.c new file mode 100644 index 000000000..8a0e7f838 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_driver.c @@ -0,0 +1,2398 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_driver.c,v 1.6 2003/02/12 13:08:54 alanh Exp $ */ +/* + * $Workfile: nsc_gx2_driver.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This is the main module configures the interfacing + * with the X server. The individual modules will be + * loaded based upon the options selected from the + * XF86Config. This file also has modules for finding + * supported modes, turning on the modes based on options. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#define DEBUG(x) +#define GEODE_TRACE 0 +#define CFB 0 + +/* Includes that are used by all drivers */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Resources.h" + +/* We may want inb() and outb() */ +#include "compiler.h" + +/* We may want to access the PCI config space */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#define INT10_SUPPORT 1 + +/* Colormap handling stuff */ +#include "xf86cmap.h" + +#define RC_MAX_DEPTH 24 + +/* Frame buffer stuff */ +#if CFB +/* + * If using cfb, cfb.h is required. Select the others for the bpp values + * the driver supports. + */ +#define PSZ 8 /* needed for cfb.h */ +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#else +#include "fb.h" +#endif + +#include "shadowfb.h" + +/* Machine independent stuff */ +#include "mipointer.h" +#include "mibank.h" +#include "micmap.h" +/* All drivers implementing backing store need this */ +#include "mibstore.h" +#include "vgaHW.h" +#include "vbe.h" + +/* Check for some extensions */ +#ifdef XFreeXDGA +#define _XF86_DGA_SERVER_ +#include "extensions/xf86dgastr.h" +#endif /* XFreeXDGA */ + +#ifdef DPMSExtension +#include "globals.h" +#include "opaque.h" +#define DPMS_SERVER +#include "extensions/dpms.h" +#endif /* DPMSExtension */ + +/* Our private include file (this also includes the durango headers) */ +#include "nsc.h" +#if !defined(STB_X) +#include "nsc_gx2_vga.c" +#endif /* STB_X */ + +#if GEODE_TRACE +/* ANSI C does not allow var arg macros */ +#define GeodeDebug(args) DebugPort(DCount++);ErrorF args +#else +#define GeodeDebug(args) +#endif + +extern SymTabRec GeodeChipsets[]; +extern PciChipsets GeodePCIchipsets[]; +extern OptionInfoRec GeodeOptions[]; + +/* Forward definitions */ +static Bool GX2PreInit(ScrnInfoPtr, int); +static Bool GX2ScreenInit(int, ScreenPtr, int, char **); +static Bool GX2EnterVT(int, int); +static void GX2LeaveVT(int, int); +static void GX2FreeScreen(int, int); +void GX2AdjustFrame(int, int, int, int); +Bool GX2SwitchMode(int, DisplayModePtr, int); +static int GX2ValidMode(int, DisplayModePtr, Bool, int); +static void GX2LoadPalette(ScrnInfoPtr pScreenInfo, + int numColors, int *indizes, + LOCO * colors, VisualPtr pVisual); +static Bool GX2MapMem(ScrnInfoPtr); +static Bool GX2UnmapMem(ScrnInfoPtr); +static void gx2_set_DvLineSize(unsigned int pitch); + +extern Bool GX2AccelInit(ScreenPtr pScreen); +extern Bool GX2HWCursorInit(ScreenPtr pScreen); +extern void GX2HideCursor(ScrnInfoPtr pScreenInfo); +extern void GX2ShowCursor(ScrnInfoPtr pScreenInfo); +extern void GX2PointerMoved(int index, int x, int y); +extern void GX2RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void GX2RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void GX2RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void GX2RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void GX2RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern void GX2InitVideo(ScreenPtr pScreen); +extern Bool GX2DGAInit(ScreenPtr pScreen); +extern void GX2LoadCursorImage(ScrnInfoPtr pScreenInfo, unsigned char *src); + +#if !defined(STB_X) +extern unsigned char *XpressROMPtr; +#endif /* STB_X */ + +/* Existing Processor Models */ +#define GX1 0x1 +#define GX2 0x2 +#define GX2_CRT 0x6 +#define GX2_TFT 0xA + +/* List of symbols from other modules that this module references.The purpose +* is that to avoid unresolved symbol warnings +*/ +extern const char *nscVgahwSymbols[]; +extern const char *nscVbeSymbols[]; +extern const char *nscInt10Symbols[]; + +#if CFB +extern const char *nscCfbSymbols[]; +#else +extern const char *nscFbSymbols[]; +#endif +extern const char *nscXaaSymbols[]; +extern const char *nscRamdacSymbols[]; +extern const char *nscShadowSymbols[]; + +void GX2SetupChipsetFPtr(ScrnInfoPtr pScrn); +GeodePtr GX2GetRec(ScrnInfoPtr pScreenInfo); +void get_flatpanel_info(const char *options, int *W, int *H, + int *D, int *C, int *T); +void gx2_clear_screen(int width, int height); +void EnableDACPower(void); +void redcloud_gfx_2_vga_fix(void); + +void +GX2SetupChipsetFPtr(ScrnInfoPtr pScrn) +{ + GeodeDebug(("GX2SetupChipsetFPtr!\n")); + + pScrn->PreInit = GX2PreInit; + pScrn->ScreenInit = GX2ScreenInit; + pScrn->SwitchMode = GX2SwitchMode; + pScrn->AdjustFrame = GX2AdjustFrame; + pScrn->EnterVT = GX2EnterVT; + pScrn->LeaveVT = GX2LeaveVT; + pScrn->FreeScreen = GX2FreeScreen; + pScrn->ValidMode = GX2ValidMode; +} + +/*---------------------------------------------------------------------------- + * GX2GetRec. + * + * Description :This function allocate an GeodeRec and hooked into + * pScreenInfo str driverPrivate member of ScreeenInfo + * structure. + * Parameters. + * pScreenInfo :Pointer handle to the screenonfo structure. + * + * Returns :allocated pScreeninfo structure. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +GeodePtr +GX2GetRec(ScrnInfoPtr pScreenInfo) +{ + if (!pScreenInfo->driverPrivate) { + GeodePtr pGeode; + + pGeode = pScreenInfo->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); +#if INT10_SUPPORT + pGeode->vesa = xcalloc(sizeof(VESARec), 1); +#endif + } + return GEODEPTR(pScreenInfo); +} + +/*---------------------------------------------------------------------------- + * GX2FreeRec. + * + * Description :This function deallocate an GeodeRec and freed from + * pScreenInfo str driverPrivate member of ScreeenInfo + * structure. + * Parameters. + * pScreenInfo :Pointer handle to the screenonfo structure. + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static void +GX2FreeRec(ScrnInfoPtr pScreenInfo) +{ + if (pScreenInfo->driverPrivate == NULL) { + return; + } + xfree(pScreenInfo->driverPrivate); + pScreenInfo->driverPrivate = NULL; +} + +/*---------------------------------------------------------------------------- + * GX2SaveScreen. + * + * Description :This is todo the screen blanking + * + * Parameters. + * pScreen :Handle to ScreenPtr structure. + * mode :mode is used by vgaHWSaveScren to check blnak os on. + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :none +*---------------------------------------------------------------------------- +*/ +static Bool +GX2SaveScreen(ScreenPtr pScreen, int mode) +{ +#if !defined(STB_X) + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + + GeodeDebug(("GX2SaveScreen!\n")); + + if (!pScreenInfo->vtSema) + return vgaHWSaveScreen(pScreen, mode); + +#endif /* STB_X */ + return TRUE; +} + +/*---------------------------------------------------------------------------- + * get_flatpanel_info. + * + * Description :This gets the values of the flatpanel attached. + * + * Parameters: + * options : Pointer to the display options. + * W: Pointer to the width of the panel + * H: Pointer to the height of the panel + * D: Pointer to the depth of the panel. + * C: Pointer to the color of the panel. + * T: Pointer to the type of the panel. + * Returns : none. + * + * Comments :none + *------------------------------------------------------------------------ + */ +void +get_flatpanel_info(const char *options, int *W, int *H, + int *D, int *C, int *T) +{ + char *pnl_opt; + + pnl_opt = strtok((char *)options, ":"); + *W = strtoul(pnl_opt, NULL, 0); + pnl_opt = strtok(NULL, ":"); + *H = strtoul(pnl_opt, NULL, 0); + pnl_opt = strtok(NULL, ":"); + *D = strtoul(pnl_opt, NULL, 0); + pnl_opt = strtok(NULL, ":"); + *C = strtoul(pnl_opt, NULL, 0); + pnl_opt = strtok(NULL, ":"); + *T = strtoul(pnl_opt, NULL, 0); + + *C = (*C) ? PNL_COLOR_PANEL : PNL_MONO_PANEL; + + switch (*T) { + case 0: + *T = PNL_SSTN; + break; + case 1: + *T = PNL_DSTN; + break; + case 2: + default: + *T = PNL_TFT; + break; + } + + if ((*W != 640) && (*W != 800) && (*W != 1024)) + *W = 640; + + if ((*H != 480) && (*H != 600) && (*H != 768)) + *H = 480; +} + +static void +GX2ProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} + +/*---------------------------------------------------------------------------- + * GX2PreInit. + * + * Description :This function is called only once ate teh server startup + * + * Parameters. + * pScreenInfo :Handle to ScreenPtr structure. + * flags :flags may be used to check the probeed one with config. + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :none. + *---------------------------------------------------------------------------- + */ +static Bool +GX2PreInit(ScrnInfoPtr pScreenInfo, int flags) +{ + static ClockRange GeodeClockRange = + { NULL, 25175, 229500, 0, FALSE, TRUE, 1, 1, 0 }; + MessageType from; + int i = 0; + GeodePtr pGeode; + char *mod = NULL; + +#if CFB + char *reqSymbol = NULL; +#endif /* CFB */ +#if defined(STB_X) + GAL_ADAPTERINFO sAdapterInfo; +#endif /* STB_X */ + unsigned int PitchInc = 0, minPitch = 0, maxPitch = 0; + unsigned int minHeight = 0, maxHeight = 0; + unsigned int SupportFlags; + const char *s; + char **modes; + +#if INT10_SUPPORT + VESAPtr pVesa; +#endif + + DCount = 10; + GeodeDebug(("GX2PreInit!\n")); + /* Allocate driver private structure */ + if (!(pGeode = GX2GetRec(pScreenInfo))) + return FALSE; + + /* This is the general case */ + for (i = 0; i < pScreenInfo->numEntities; i++) { + pGeode->pEnt = xf86GetEntityInfo(pScreenInfo->entityList[i]); + if (pGeode->pEnt->resources) + return FALSE; + pGeode->Chipset = pGeode->pEnt->chipset; + pScreenInfo->chipset = (char *)xf86TokenToString(GeodeChipsets, + pGeode->pEnt->chipset); + } + + if (flags & PROBE_DETECT) { + GX2ProbeDDC(pScreenInfo, pGeode->pEnt->index); + return TRUE; + } +#if INT10_SUPPORT + if (!xf86LoadSubModule(pScreenInfo, "int10")) + return FALSE; + xf86LoaderReqSymLists(nscInt10Symbols, NULL); +#endif + pGeode->FBVGAActive = 0; /* KFB will Knock of VGA */ + +#if !defined(STB_X) + /* If the vgahw module would be needed it would be loaded here */ + if (!xf86LoadSubModule(pScreenInfo, "vgahw")) { + return FALSE; + } + xf86LoaderReqSymLists(nscVgahwSymbols, NULL); +#endif /* STB_X */ + GeodeDebug(("GX2PreInit(1)!\n")); + /* Do the durango hardware detection */ +#if defined(STB_X) + if (!Gal_initialize_interface()) { + GeodeDebug(("GALintialize fail GX2PreInit(1.00)!\n")); + return FALSE; + } + + if (Gal_get_adapter_info(&sAdapterInfo)) { + pGeode->cpu_version = sAdapterInfo.dwCPUVersion; + + /* find the base chipset core. Currently there can be only one + * chip active at any time. + */ + if ((pGeode->cpu_version & 0xFF) == GFX_CPU_REDCLOUD) { + if (sAdapterInfo.dwCPUType) + pGeode->DetectedChipSet = GX2_TFT; + else + pGeode->DetectedChipSet = GX2_CRT; + } + + DEBUGMSG(1, + (0, X_NONE, "Detected BaseChip %d, %d\n", + pGeode->DetectedChipSet, sAdapterInfo.dwCPUType)); + + pGeode->vid_version = sAdapterInfo.dwVideoVersion; + pGeode->FBSize = sAdapterInfo.dwFrameBufferSize; + /* update the max clock from the one system suports */ + GeodeClockRange.maxClock = sAdapterInfo.dwMaxSupportedPixelClock; + pGeode->FBLinearAddr = sAdapterInfo.dwFrameBufferBase; +#if 0 + pGeode->FBBase = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_FRAMEBUFFER, + pGeode->FBLinearAddr, + pGeode->FBSize); +#endif + if (!GX2MapMem(pScreenInfo)) + return FALSE; + DEBUGMSG(1, (0, X_NONE, "CPU=%x vid %x FB %x FBAdd %X\n", + pGeode->cpu_version, pGeode->vid_version, pGeode->FBSize, + pGeode->FBLinearAddr)); + } else { + return FALSE; + } +#else /* STB */ + pGeode->cpu_version = gfx_detect_cpu(); + + /* find the base chipset core. Currently there can be only one + * chip active at any time. + */ +/* pGeode->DetectedChipSet = GX1; */ + if ((pGeode->cpu_version & 0xFF) == GFX_CPU_REDCLOUD) + pGeode->DetectedChipSet = GX2; + GeodeDebug(("Detected BaseChip (%d)\n", pGeode->DetectedChipSet)); + { + Q_WORD msrValue; + + /* GX2 : Can have CRT or TFT only */ + gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue); + pGeode->DetectedChipSet = + ((msrValue.low & RCDF_CONFIG_FMT_MASK) == + RCDF_CONFIG_FMT_FP) ? GX2_TFT : GX2_CRT; + GeodeDebug(("Gx2 for %s\n", + ((pGeode->DetectedChipSet == GX2_TFT) ? "TFT" : "CRT"))); + } + GeodeDebug(("GX2PreInit(1.1)!\n")); + pGeode->vid_version = gfx_detect_video(); + GeodeDebug(("GX2PreInit(1.2)!\n")); + pGeode->FBLinearAddr = gfx_get_frame_buffer_base(); + GeodeDebug(("GX2PreInit(1.3)!\n")); + pGeode->FBSize = gfx_get_frame_buffer_size(); + GeodeDebug(("GX2PreInit(1.4)!\n")); + /* update the max clock from the one system suports */ + GeodeClockRange.maxClock = gfx_get_max_supported_pixel_clock(); + + GeodeDebug(("GX2PreInit(1.5)!\n")); + /* SET DURANGO REGISTER POINTERS + * * The method of mapping from a physical address to a linear address + * * is operating system independent. Set variables to linear address. + */ + if (pGeode->DetectedChipSet & GX2) { + pGeode->cpu_reg_size = 0x4000; + pGeode->gp_reg_size = 0x4000; + pGeode->vid_reg_size = 0x4000; + } else { + pGeode->cpu_reg_size = 0x9000; + pGeode->vid_reg_size = 0x1000; + } + + if (!GX2MapMem(pScreenInfo)) + return FALSE; + + /* check if VGA is active */ + /* This routine saves the current VGA state in Durango VGA structure */ + /* check if VGA is active */ + pGeode->FBVGAActive = gu2_get_vga_active(); + +#endif /* STB_X */ + DEBUGMSG(1, (0, X_PROBED, "VGA = %d\n", pGeode->FBVGAActive)); + + /* Fill in the monitor field */ + pScreenInfo->monitor = pScreenInfo->confScreen->monitor; + GeodeDebug(("GX2PreInit(2)!\n")); + SupportFlags = Support24bppFb | Support32bppFb; + GeodeDebug(("GX2PreInit(2)!\n")); + /* Determine depth, bpp, etc. */ + if (!xf86SetDepthBpp(pScreenInfo, 8, 8, 8, SupportFlags)) { + return FALSE; + } else { + if (!((pScreenInfo->depth == 8) || + (pScreenInfo->depth == 16) || + (pScreenInfo->depth == 24) || (pScreenInfo->depth == 32))) { + /* Depth not supported */ + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "Given depth (%d bpp) is not supported by this driver\n", + pScreenInfo->depth)); + return FALSE; + } + } + + /*This must happen after pScreenInfo->display has been set + * * because xf86SetWeight references it. + */ + if (pScreenInfo->depth > 8) { + /* The defaults are OK for us */ + rgb BitsPerComponent = { 0, 0, 0 }; + rgb BitMask = { 0, 0, 0 }; + + if (pScreenInfo->depth > 16) { + /* we are operating in 24 bpp, Readcloud */ + BitsPerComponent.red = 8; + BitsPerComponent.green = 8; + BitsPerComponent.blue = 8; + + BitMask.red = 0xFF0000; + BitMask.green = 0x00FF00; + BitMask.blue = 0x0000FF; + } + if (!xf86SetWeight(pScreenInfo, BitsPerComponent, BitMask)) { + return FALSE; + } else { + /* XXX Check if the returned weight is supported */ + } + } + + xf86PrintDepthBpp(pScreenInfo); + + GeodeDebug(("GX2PreInit(3)!\n")); + + if (!xf86SetDefaultVisual(pScreenInfo, -1)) + return FALSE; + + GeodeDebug(("GX2PreInit(4)!\n")); + + /* The new cmap layer needs this to be initialized */ + if (pScreenInfo->depth > 1) { + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScreenInfo, zeros)) { + return FALSE; + } + } + GeodeDebug(("GX2PreInit(5)!\n")); + + /* We use a programmable clock */ + pScreenInfo->progClock = TRUE; + + /*Collect all of the relevant option flags + * *(fill in pScreenInfo->options) + */ + xf86CollectOptions(pScreenInfo, NULL); + + /*Process the options */ + xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options, + GeodeOptions); + +#if INT10_SUPPORT + pVesa = pGeode->vesa; + /* Initialize Vesa record */ + + if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { + xf86DrvMsg(0, X_ERROR, "Int10 initialization failed.\n"); + return (FALSE); + } +#endif + /*Set the bits per RGB for 8bpp mode */ + if (pScreenInfo->depth == 8) { + /* Default to 8 */ + pScreenInfo->rgbBits = 8; + } + from = X_DEFAULT; + + /* + * *The preferred method is to use the "hw cursor" option as a tri-state + * *option, with the default set above. + */ + pGeode->HWCursor = TRUE; + if (xf86GetOptValBool(GeodeOptions, OPTION_HW_CURSOR, &pGeode->HWCursor)) { + from = X_CONFIG; + } + /* For compatibility, accept this too (as an override) */ + if (xf86ReturnOptValBool(GeodeOptions, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pGeode->HWCursor = FALSE; + } + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, "Using %s cursor\n", + pGeode->HWCursor ? "HW" : "SW")); + + pGeode->Compression = TRUE; + if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOCOMPRESSION, FALSE)) { + pGeode->Compression = FALSE; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "NoCompression\n")); + } + + pGeode->NoAccel = FALSE; + if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOACCEL, FALSE)) { + pGeode->NoAccel = TRUE; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "Acceleration \ + disabled\n")); + } + + if (!xf86GetOptValInteger(GeodeOptions, OPTION_OSM_IMG_BUFS, + &(pGeode->NoOfImgBuffers))) + pGeode->NoOfImgBuffers = DEFAULT_NUM_OF_BUF; /* default # of buffers */ + if (pGeode->NoOfImgBuffers <= 0) + pGeode->NoOfImgBuffers = 0; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "NoOfImgBuffers = %d\n", pGeode->NoOfImgBuffers)); + + pGeode->Panel = FALSE; + if (xf86ReturnOptValBool(GeodeOptions, OPTION_FLATPANEL, FALSE)) { + DEBUGMSG(0, (pScreenInfo->scrnIndex, X_CONFIG, "FlatPanel Selected\n")); + pGeode->Panel = TRUE; + } + + /* Force the Panel on if on a GX2 TFT part, no crt support */ + if (pGeode->DetectedChipSet == GX2_TFT) { + pGeode->Panel = TRUE; + } + + /* If on a CRT and Panel flag set, disable Panel */ + if ((pGeode->DetectedChipSet == GX2_CRT) && (pGeode->Panel)) + pGeode->Panel = FALSE; + + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Quering FP Bios %d\n", pGeode->Panel)); + + /* if FP not supported in BIOS, then turn off user option */ + if (pGeode->Panel) { + /* check if bios supports FP */ +#if defined(STB_X) + Gal_pnl_enabled_in_bios(&pGeode->Panel); + Gal_pnl_info_from_bios(&pGeode->FPBX, &pGeode->FPBY, + &pGeode->FPBB, &pGeode->FPBF); +#else /* STB_X */ + pGeode->Panel = Pnl_IsPanelEnabledInBIOS(); + Pnl_GetPanelInfoFromBIOS(&pGeode->FPBX, &pGeode->FPBY, + &pGeode->FPBB, &pGeode->FPBF); +#endif /* STB_X */ + } + + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Quering FP Bios %d %d %d %d\n", + pGeode->FPBX, pGeode->FPBY, pGeode->FPBB, pGeode->FPBF)); + + /* if panel not selected and Panel can be supported. + * Power down the panel. + */ + if (!pGeode->Panel) { +#if defined(STB_X) + Gal_pnl_powerdown(); +#else /* STB_X */ + Pnl_PowerDown(); +#endif /* STB_X */ + } else { +#if defined(STB_X) + Gal_pnl_powerup(); +#else + Pnl_PowerUp(); +#endif /* STB_X */ + } + + pGeode->ShadowFB = FALSE; + if (xf86ReturnOptValBool(GeodeOptions, OPTION_SHADOW_FB, FALSE)) { + pGeode->ShadowFB = TRUE; + pGeode->NoAccel = TRUE; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Using \"Shadow Framebuffer\" - acceleration disabled\n")); + } + + pGeode->Rotate = 0; + if ((s = xf86GetOptValString(GeodeOptions, OPTION_ROTATE))) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "Rotating - %s\n", s)); + if (!xf86NameCmp(s, "CW")) { + pGeode->ShadowFB = TRUE; + pGeode->NoAccel = TRUE; + pGeode->HWCursor = FALSE; + pGeode->Rotate = 1; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n")); + } else { + if (!xf86NameCmp(s, "CCW")) { + pGeode->ShadowFB = TRUE; + pGeode->NoAccel = TRUE; + pGeode->HWCursor = FALSE; + pGeode->Rotate = -1; + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "Rotating screen counter clockwise - acceleration \ + disabled\n")); + } else { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, + "\"%s\" is not a valid value for Option \"Rotate\"\n", + s)); + DEBUGMSG(1, + (pScreenInfo->scrnIndex, X_INFO, + "Valid options are \"CW\" or \"CCW\"\n")); + } + } + } + + /* XXX Init further private data here */ + + /* + * * This shouldn't happen because such problems should be caught in + * * GeodeProbe(), but check it just in case. + */ + if (pScreenInfo->chipset == NULL) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "ChipID 0x%04X is not recognised\n", pGeode->Chipset)); + return FALSE; + } + if (pGeode->Chipset < 0) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognised\n", + pScreenInfo->chipset)); + return FALSE; + } + GeodeDebug(("GX2PreInit(6)!\n")); + + /* + * * Init the screen with some values + */ +#if !defined(STB_X) + + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, + "Video I/O registers at 0x%08lX\n", + (unsigned long)VGAHW_GET_IOBASE())); +#endif /* STB_X */ + + if (pScreenInfo->memPhysBase == 0) { + from = X_PROBED; +#if defined(STB_X) + pScreenInfo->memPhysBase = sAdapterInfo.dwFrameBufferBase; +#else /* STB_X */ + pScreenInfo->memPhysBase = gfx_get_frame_buffer_base(); +#endif /* STB_X */ + } + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, + "Linear framebuffer at 0x%08lX\n", + (unsigned long)pScreenInfo->memPhysBase)); + + if (pGeode->pEnt->device->videoRam == 0) { + from = X_PROBED; + pScreenInfo->videoRam = pGeode->FBSize / 1024; + } else { + pScreenInfo->videoRam = pGeode->pEnt->device->videoRam; + from = X_CONFIG; + } + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, + "VideoRam: %d kByte\n", + (unsigned long)pScreenInfo->videoRam)); + + GeodeDebug(("GX2PreInit(7)!\n")); + + /* + * * xf86ValidateModes will check that the mode HTotal and VTotal values + * * don't exceed the chipset's limit if pScreenInfo->maxHValue adn + * * pScreenInfo->maxVValue are set. Since our GX2ValidMode() + * * already takes care of this, we don't worry about setting them here. + */ + /* Select valid modes from those available */ + /* + * * min pitch 1024, max 2048 (Pixel count) + * * min height 480, max 1024 (Pixel count) + */ + minPitch = 1024; + maxPitch = 4096; /* Can support upto 1600x1200 32Bpp */ + minHeight = 480; + maxHeight = 1200; /* Can support upto 1600x1200 32Bpp */ + if (pScreenInfo->depth > 16) { + PitchInc = 4096; + } else if (pScreenInfo->depth == 16) { + PitchInc = 2048; + } else { + PitchInc = 1024; + } + PitchInc <<= 3; /* in bits */ + + /* by default use what user sets in the XF86Config file */ + modes = pScreenInfo->display->modes; + + i = xf86ValidateModes(pScreenInfo, + pScreenInfo->monitor->Modes, + modes, + &GeodeClockRange, + NULL, minPitch, maxPitch, + PitchInc, minHeight, maxHeight, + pScreenInfo->display->virtualX, + pScreenInfo->display->virtualY, +#if defined(STB_X) + sAdapterInfo.dwFrameBufferSize, +#else /* STB_X */ + gfx_get_frame_buffer_size(), +#endif /* STB_X */ + LOOKUP_BEST_REFRESH); + + DEBUGMSG(1, (pScreenInfo->scrnIndex, from, + "xf86ValidateModes: %d %d %d\n", + pScreenInfo->virtualX, + pScreenInfo->virtualY, pScreenInfo->displayWidth)); + if (i == -1) { + GX2FreeRec(pScreenInfo); + return FALSE; + } + GeodeDebug(("GX2PreInit(8)!\n")); + + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScreenInfo); + + GeodeDebug(("GX2PreInit(9)!\n")); + if (i == 0 || pScreenInfo->modes == NULL) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "No valid modes found\n")); + GX2FreeRec(pScreenInfo); + return FALSE; + } + GeodeDebug(("GX2PreInit(10)!\n")); + + xf86SetCrtcForModes(pScreenInfo, 0); + GeodeDebug(("GX2PreInit(11)!\n")); + + /* Set the current mode to the first in the list */ + pScreenInfo->currentMode = pScreenInfo->modes; + GeodeDebug(("GX2PreInit(12)!\n")); + + /* Print the list of modes being used */ + xf86PrintModes(pScreenInfo); + GeodeDebug(("GX2PreInit(13)!\n")); + + /* Set the display resolution */ + xf86SetDpi(pScreenInfo, 0, 0); + GeodeDebug(("GX2PreInit(14)!\n")); + + /* Load bpp-specific modules */ + mod = NULL; + +#if CFB + /* Load bpp-specific modules */ + switch (pScreenInfo->bitsPerPixel) { + case 8: + mod = "cfb"; + reqSymbol = "cfbScreenInit"; + break; + case 16: + mod = "cfb16"; + reqSymbol = "cfb16ScreenInit"; + break; + case 24: + mod = "cfb24"; + reqSymbol = "cfb24ScreenInit"; + break; + case 32: + mod = "cfb32"; + reqSymbol = "cfb32ScreenInit"; + break; + default: + return FALSE; + } + if (mod && xf86LoadSubModule(pScreenInfo, mod) == NULL) { + GX2FreeRec(pScreenInfo); + return FALSE; + } + + xf86LoaderReqSymbols(reqSymbol, NULL); +#else + if (xf86LoadSubModule(pScreenInfo, "fb") == NULL) { + GX2FreeRec(pScreenInfo); + return FALSE; + } + + xf86LoaderReqSymLists(nscFbSymbols, NULL); +#endif + GeodeDebug(("GX2PreInit(15)!\n")); + if (pGeode->NoAccel == FALSE) { + if (!xf86LoadSubModule(pScreenInfo, "xaa")) { + GX2FreeRec(pScreenInfo); + return FALSE; + } + xf86LoaderReqSymLists(nscXaaSymbols, NULL); + } + GeodeDebug(("GX2PreInit(16)!\n")); + if (pGeode->HWCursor == TRUE) { + if (!xf86LoadSubModule(pScreenInfo, "ramdac")) { + GX2FreeRec(pScreenInfo); + return FALSE; + } + xf86LoaderReqSymLists(nscRamdacSymbols, NULL); + } + GeodeDebug(("GX2PreInit(17)!\n")); + /* Load shadowfb if needed */ + if (pGeode->ShadowFB) { + if (!xf86LoadSubModule(pScreenInfo, "shadowfb")) { + GX2FreeRec(pScreenInfo); + return FALSE; + } + xf86LoaderReqSymLists(nscShadowSymbols, NULL); + } + GeodeDebug(("GX2PreInit(18)!\n")); + if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR, + "xf86RegisterResources() found resource conflicts\n")); + GX2FreeRec(pScreenInfo); + return FALSE; + } + GX2UnmapMem(pScreenInfo); + GeodeDebug(("GX2PreInit ... done successfully!\n")); + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX2Restore. + * + * Description :This function restores the mode that was saved on server + entry + * Parameters. + * pScreenInfo :Handle to ScreenPtr structure. + * Pmode :poits to screen mode + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static void +GX2Restore(ScrnInfoPtr pScreenInfo) +{ + GeodePtr pGeode; + + GeodeDebug(("GX2Restore!\n")); + /* Get driver private structure */ + if (!(pGeode = GX2GetRec(pScreenInfo))) + return; + if (pGeode->FBVGAActive) { + vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo); + + vgaHWProtect(pScreenInfo, TRUE); + vgaHWRestore(pScreenInfo, &pvgaHW->SavedReg, VGA_SR_ALL); + vgaHWProtect(pScreenInfo, FALSE); + } +} + +/*---------------------------------------------------------------------------- + * GX2CalculatePitchBytes. + * + * Description :This function restores the mode that was saved on server + * + * Parameters. + * pScreenInfo :Handle to ScreenPtr structure. + * Pmode :Points to screenmode + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static int +GX2CalculatePitchBytes(unsigned int width, unsigned int bpp) +{ + int lineDelta = width * (bpp >> 3); + + if (width < 640) { + /* low resolutions have both pixel and line doubling */ + DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n", + width, lineDelta)); + lineDelta <<= 1; + } + /* needed in Rotate mode when in accel is turned off */ + if (1) { /*!pGeode->NoAccel */ + if (lineDelta > 4096) + lineDelta = 8192; + else if (lineDelta > 2048) + lineDelta = 4096; + else if (lineDelta > 1024) + lineDelta = 2048; + else + lineDelta = 1024; + } + + DEBUGMSG(1, (0, X_PROBED, "pitch %d %d\n", width, lineDelta)); + + return lineDelta; +} + +/*---------------------------------------------------------------------------- + * GX2GetRefreshRate. + * + * Description :This function restores the mode that saved on server + * + * Parameters. + * Pmode :Pointer to the screen modes + * + * Returns :It returns the selected refresh rate. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static int +GX2GetRefreshRate(DisplayModePtr pMode) +{ +#define THRESHOLD 2 + unsigned int i; + static int validRates[] = { 50, 56, 60, 70, 72, 75, 85 }; /* Hz */ + unsigned long dotClock; + int refreshRate; + int selectedRate; + + dotClock = pMode->SynthClock * 1000; + refreshRate = dotClock / pMode->CrtcHTotal / pMode->CrtcVTotal; + + if ((pMode->CrtcHTotal < 640) && (pMode->CrtcVTotal < 480)) + refreshRate >>= 2; /* double pixel and double scan */ + + DEBUGMSG(1, (0, X_PROBED, "dotclock %d %d\n", dotClock, refreshRate)); + + selectedRate = validRates[0]; + + for (i = 0; i < (sizeof(validRates) / sizeof(validRates[0])); i++) { + if (validRates[i] < (refreshRate + THRESHOLD)) { + selectedRate = validRates[i]; + } + } + return selectedRate; +} + +void +gx2_clear_screen(int width, int height) +{ + /* clean up the frame buffer memory */ + GFX(set_solid_pattern(0)); + GFX(set_raster_operation(0xF0)); + GFX(pattern_fill(0, 0, width, height)); +} + +void +gx2_set_DvLineSize(unsigned int pitch) +{ + unsigned long temp, dv_size = MDC_DV_LINE_SIZE_1024; + + if (pitch > 1024) { + dv_size = MDC_DV_LINE_SIZE_2048; + } + if (pitch > 2048) { + dv_size = MDC_DV_LINE_SIZE_4096; + } + if (pitch > 4096) { + dv_size = MDC_DV_LINE_SIZE_8192; + } + + /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ + +#if defined(STB_X) + Gal_read_register(GAL_REG, MDC_DV_CTL, &temp, 4); + temp = (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size; + Gal_write_register(GAL_REG, MDC_DV_CTL, temp, 4); +#else + temp = READ_REG32(MDC_DV_CTL); + WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); +#endif +} + +/*---------------------------------------------------------------------------- + * GX2SetMode. + * + * Description :This function sets parametrs for screen mode + * + * Parameters. + * pScreenInfo :Pointer to the screenInfo structure. + * Pmode :Pointer to the screen modes + * + * Returns :TRUE on success and FALSE on Failure. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ + +static Bool +GX2SetMode(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + DCount = 50; + /* unsigned int compOffset, compPitch, compSize; */ + GeodeDebug(("GX2SetMode!\n")); +#if !defined(STB_X) + DEBUGMSG(1, (0, X_NONE, "Set mode %X %X %X %X %X\n", + gfx_virt_regptr, + gfx_virt_gpptr, + gfx_virt_spptr, gfx_virt_vidptr, gfx_virt_fbptr)); +#endif /* STB_X */ + + /* Set the VT semaphore */ + pScreenInfo->vtSema = TRUE; + DEBUGMSG(1, (0, X_NONE, "Set mode")); + + /* The timing will be adjusted later */ + GeodeDebug(("Set display mode: %dx%d-%d (%dHz) Pitch %d\n", + pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, + GX2GetRefreshRate(pMode), pGeode->Pitch)); + + GeodeDebug(("Before setting the mode\n")); + if (1) { + { /* TV not selected */ + + DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT or TFT\n")); + + if (pGeode->Panel) { + DEBUGMSG(0, (0, X_PROBED, "Setting Display for TFT\n")); + DEBUGMSG(1, (0, X_PROBED, "Restore Panel %d %d %d %d %d\n", + pGeode->FPBX, pGeode->FPBY, + pMode->CrtcHDisplay, + pMode->CrtcVDisplay, pScreenInfo->bitsPerPixel)); + + DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "FP Bios %d\n", + pGeode->Panel)); + GFX(set_fixed_timings(pGeode->FPBX, pGeode->FPBY, + pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel)); + } else { + /* display is crt */ + DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT %dx%d-%d@%d\n", + pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, + GX2GetRefreshRate(pMode))); + GFX(set_display_mode(pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, + GX2GetRefreshRate(pMode))); + + /* adjust the pitch */ + GFX(set_display_pitch(pGeode->Pitch)); + } + GFX(set_bpp(pScreenInfo->bitsPerPixel)); + /* enable crt */ + GFX(set_crt_enable(CRT_ENABLE)); + } + GFX(set_display_offset(0L)); + GFX(wait_vertical_blank()); + + DEBUGMSG(1, (0, X_PROBED, "Display mode set\n")); + /* enable compression if option selected */ + if (pGeode->Compression) { + DEBUGMSG(1, (0, X_PROBED, "Compression mode set %d\n", + pGeode->Compression)); + /* set the compression parameters,and it will be turned on later. */ + gx2_set_DvLineSize(pGeode->Pitch); + +#if defined(STB_X) + Gal_set_compression_parameters(GAL_COMPRESSION_ALL, + pGeode->CBOffset, + pGeode->CBPitch, pGeode->CBSize); + + /* set the compression buffer, all parameters already set */ + Gal_set_compression_enable(GAL_COMPRESSION_ENABLE); +#else /* STB_X */ + gfx_set_compression_offset(pGeode->CBOffset); + gfx_set_compression_pitch(pGeode->CBPitch); + gfx_set_compression_size(pGeode->CBSize); + + /* set the compression buffer, all parameters already set */ + gfx_set_compression_enable(1); +#endif /* STB_X */ + + } + if (pGeode->HWCursor) { + /* Load blank cursor */ + GX2LoadCursorImage(pScreenInfo, NULL); + GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); + GFX(set_cursor_enable(1)); + } + } else { + GeodeDebug(("GX2Restore ... ")); + GX2Restore(pScreenInfo); + GeodeDebug(("done.\n")); + } + + GeodeDebug(("done.\n")); + /* Reenable the hardware cursor after the mode switch */ + if (pGeode->HWCursor == TRUE) { + GeodeDebug(("GX2ShowCursor ... ")); + GX2ShowCursor(pScreenInfo); + GeodeDebug(("done.\n")); + } + /* Restore the contents in the screen info */ + GeodeDebug(("After setting the mode\n")); + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX2EnterGraphics. + * + * Description :This function will intiallize the displaytiming + structure for nextmode and switch to VGA mode. + * + * Parameters. + * pScreen :Screen information will be stored in this structure. + * pScreenInfo :Pointer to the screenInfo structure. + * + * Returns :TRUE on success and FALSE on Failure. + * + * Comments :gfx_vga_mode_switch() will start and end the + * switching based on the arguments 0 or 1.soft_vga + * is disabled in this function. +*---------------------------------------------------------------------------- +*/ +static Bool +GX2EnterGraphics(ScreenPtr pScreen, ScrnInfoPtr pScreenInfo) +{ + GeodePtr pGeode = GX2GetRec(pScreenInfo); + +#if defined(STB_X) + Gal_get_display_timing(&pGeode->FBgfxdisplaytiming); + + /* Save Display offset */ + Gal_get_display_offset(&(pGeode->FBDisplayOffset)); + + /* Save the current Compression state */ + Gal_get_compression_enable(&(pGeode->FBCompressionEnable)); + Gal_get_compression_parameters(GAL_COMPRESSION_ALL, + &(pGeode->FBCompressionOffset), + &(pGeode->FBCompressionPitch), + &(pGeode->FBCompressionSize)); + + /* Save Cursor offset */ + { + unsigned short x, y, xhot, yhot; + + Gal_get_cursor_position(&(pGeode->FBCursorOffset), + &x, &y, &xhot, &yhot); + } + /* Save the Panel state */ + Gal_pnl_save(); +#else /* STB_X */ + /* Save CRT State */ + pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); + pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); + pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); + pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); + pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); + pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); + pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); + pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); + pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); + pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); + pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); + pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); + pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); + pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); + pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); + pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); + + /* Save Display offset */ + pGeode->FBDisplayOffset = gfx_get_display_offset(); + + /* Save the current Compression state */ + pGeode->FBCompressionEnable = gfx_get_compression_enable(); + pGeode->FBCompressionOffset = gfx_get_compression_offset(); + pGeode->FBCompressionPitch = gfx_get_compression_pitch(); + pGeode->FBCompressionSize = gfx_get_compression_size(); + + /* Save Cursor offset */ + pGeode->FBCursorOffset = gfx_get_cursor_offset(); + + /* Save the Panel state */ + Pnl_SavePanelState(); + + /* only if comming from VGA */ + if (pGeode->FBVGAActive) { + unsigned short sequencer; + vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo); + + /* Map VGA aperture */ + if (!vgaHWMapMem(pScreenInfo)) + return FALSE; + + /* Unlock VGA registers */ + vgaHWUnlock(pvgaHW); + + /* Save the current state and setup the current mode */ + vgaHWSave(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL); + + /* DISABLE VGA SEQUENCER */ + /* This allows the VGA state machine to terminate. We must delay */ + /* such that there are no pending MBUS requests. */ + + gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); + sequencer = gfx_inb(MDC_SEQUENCER_DATA); + sequencer |= MDC_CLK_MODE_SCREEN_OFF; + gfx_outb(MDC_SEQUENCER_DATA, sequencer); + + gfx_delay_milliseconds(1); + + /* BLANK THE VGA DISPLAY */ + gfx_outw(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_RESET); + sequencer = gfx_inb(MDC_SEQUENCER_DATA); + sequencer &= ~MDC_RESET_VGA_DISP_ENABLE; + gfx_outb(MDC_SEQUENCER_DATA, sequencer); + + gfx_delay_milliseconds(1); + } +#endif /* STB */ + + if (!GX2SetMode(pScreenInfo, pScreenInfo->currentMode)) { + return FALSE; + } + + /* clear the frame buffer, for annoying noise during mode switch */ + gx2_clear_screen(pScreenInfo->currentMode->CrtcHDisplay, + pScreenInfo->currentMode->CrtcVDisplay); + + return TRUE; +} + +#if !defined(STB_X) +void +EnableDACPower(void) +{ + /* enable the DAC POWER */ + gfx_write_vid32(RCDF_VID_MISC, + gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH); +} + +void +redcloud_gfx_2_vga_fix(void) +{ + /* enable the DAC POWER */ + EnableDACPower(); +#if 0 + int i; + + /* set the character width to 9 */ + gfx_outb(0x3C4, 0x1); + gfx_outb(0x3C5, 0x2); + + /* clear the gfx mode bit in VGA Attribute controller */ + gfx_inb(0x3DA); + gfx_outb(0x3C0, 0x30); + gfx_outb(0x3C0, 0xC); + + /* Re init the EGA Palaette */ + for (i = 0; i < 16; i++) { + gfx_inb(0x3DA); + gfx_outb(0x3C0, i); + gfx_outb(0x3C0, i); + } + + /* Re init the Overscan color to black */ + gfx_inb(0x3DA); + gfx_outb(0x3C0, 0x11); + gfx_outb(0x3C0, 0x0); + + /* Re Enable all the 4 color planes */ + gfx_inb(0x3DA); + gfx_outb(0x3C0, 0x12); + gfx_outb(0x3C0, 0xF); + + /* Clear Pixel Panning in VGA Attribute controller */ + gfx_inb(0x3DA); + gfx_outb(0x3C0, 0x33); + gfx_outb(0x3C0, 0x8); + + /* ??????????????????????? */ + gfx_outb(0x3C0, 0x20); + gfx_outb(0x3C0, 0x20); +#endif +} +#endif /* STB_X */ + +/*---------------------------------------------------------------------------- + * GX2LeaveGraphics: + * + * Description :This function will restore the displaymode parameters + * and switches the VGA mode + * + * Parameters. + * pScreen :Screen information will be stored in this structure. + * pScreenInfo :Pointer to the screenInfo structure. + * + * + * Returns :none. + * + * Comments : gfx_vga_mode_switch() will start and end the switching + * based on the arguments 0 or 1.soft_vga is disabled in + * this function. +*---------------------------------------------------------------------------- +*/ +static void +GX2LeaveGraphics(ScrnInfoPtr pScreenInfo) +{ + GeodePtr pGeode = GX2GetRec(pScreenInfo); + + /* Restore VG registers */ +#if defined(STB_X) + Gal_set_display_timing(&pGeode->FBgfxdisplaytiming); + + Gal_set_display_offset(pGeode->FBDisplayOffset); + + /* Restore Cursor */ + Gal_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); + + /* Restore the previous Compression state */ + if (pGeode->FBCompressionEnable) { + Gal_set_compression_parameters(GAL_COMPRESSION_ALL, + pGeode->FBCompressionOffset, + pGeode->FBCompressionPitch, + pGeode->FBCompressionSize); + + Gal_set_compression_enable(GAL_COMPRESSION_ENABLE); + } +#else /* STB_X */ + gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, + pGeode->FBgfxdisplaytiming.wPolarity, + pGeode->FBgfxdisplaytiming.wHActive, + pGeode->FBgfxdisplaytiming.wHBlankStart, + pGeode->FBgfxdisplaytiming.wHSyncStart, + pGeode->FBgfxdisplaytiming.wHSyncEnd, + pGeode->FBgfxdisplaytiming.wHBlankEnd, + pGeode->FBgfxdisplaytiming.wHTotal, + pGeode->FBgfxdisplaytiming.wVActive, + pGeode->FBgfxdisplaytiming.wVBlankStart, + pGeode->FBgfxdisplaytiming.wVSyncStart, + pGeode->FBgfxdisplaytiming.wVSyncEnd, + pGeode->FBgfxdisplaytiming.wVBlankEnd, + pGeode->FBgfxdisplaytiming.wVTotal, + pGeode->FBgfxdisplaytiming.dwDotClock); + + gfx_set_compression_enable(0); + + /* Restore the previous Compression state */ + if (pGeode->FBCompressionEnable) { + gfx_set_compression_offset(pGeode->FBCompressionOffset); + gfx_set_compression_pitch(pGeode->FBCompressionPitch); + gfx_set_compression_size(pGeode->FBCompressionSize); + gfx_set_compression_enable(1); + } + + gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); + + gfx_set_display_offset(pGeode->FBDisplayOffset); + + /* Restore Cursor */ + gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); + + GeodeDebug(("FBVGAActive %d\n", pGeode->FBVGAActive)); + if (pGeode->FBVGAActive) { + pGeode->vesa->pInt->num = 0x10; + pGeode->vesa->pInt->ax = 0x3; + pGeode->vesa->pInt->bx = 0; + xf86ExecX86int10(pGeode->vesa->pInt); + gfx_delay_milliseconds(3); + EnableDACPower(); + } +#endif /* STB_X */ +} + +/*---------------------------------------------------------------------------- + * GX2CloseScreen. + * + * Description :This function will restore the original mode + * and also it unmap video memory + * + * Parameters. + * ScrnIndex :Screen index value of the screen will be closed. + * pScreen :Pointer to the screen structure. + * + * + * Returns :TRUE on success and FALSE on Failure. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static Bool +GX2CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + if (pGeode->ShadowPtr) + xfree(pGeode->ShadowPtr); + + DEBUGMSG(0, (scrnIndex, X_PROBED, "GX2CloseScreen %d\n", + pScreenInfo->vtSema)); + if (pScreenInfo->vtSema) + GX2LeaveGraphics(pScreenInfo); + + if (pGeode->AccelInfoRec) + XAADestroyInfoRec(pGeode->AccelInfoRec); + + if (pGeode->AccelImageWriteBufferOffsets) { + xfree(pGeode->AccelImageWriteBufferOffsets); + pGeode->AccelImageWriteBufferOffsets = 0x0; + } + /* free the allocated off screen area */ + xf86FreeOffscreenArea(pGeode->AccelImgArea); + xf86FreeOffscreenArea(pGeode->CompressionArea); + + pScreenInfo->vtSema = FALSE; + + GX2UnmapMem(pScreenInfo); + if (pGeode && (pScreen->CloseScreen = pGeode->CloseScreen)) { + pGeode->CloseScreen = NULL; + return ((*pScreen->CloseScreen) (scrnIndex, pScreen)); + } + return TRUE; +} + +#ifdef DPMSExtension +/*---------------------------------------------------------------------------- + * GX2DPMSSet. + * + * Description :This function sets geode into Power Management + * Signalling mode. + * + * Parameters. + * pScreenInfo :Pointer to screen info strucrure. + * mode :Specifies the power management mode. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static void +GX2DPMSSet(ScrnInfoPtr pScreenInfo, int mode, int flags) +{ + GeodePtr pGeode; + + pGeode = GEODEPTR(pScreenInfo); + + GeodeDebug(("GX2DPMSSet!\n")); + + /* Check if we are actively controlling the display */ + if (!pScreenInfo->vtSema) { + ErrorF("GX2DPMSSet called when we not controlling the VT!\n"); + return; + } + switch (mode) { + case DPMSModeOn: + /* Screen: On; HSync: On; VSync: On */ + GFX(set_crt_enable(CRT_ENABLE)); +#if defined(STB_X) + if (pGeode->Panel) + Gal_pnl_powerup(); +#else /* STB_X */ + if (pGeode->Panel) + Pnl_PowerUp(); +#endif /* STB_X */ + break; + + case DPMSModeStandby: + /* Screen: Off; HSync: Off; VSync: On */ + GFX(set_crt_enable(CRT_STANDBY)); +#if defined(STB_X) + if (pGeode->Panel) + Gal_pnl_powerdown(); +#else /* STB_X */ + if (pGeode->Panel) + Pnl_PowerDown(); +#endif /* STB_X */ + break; + + case DPMSModeSuspend: + /* Screen: Off; HSync: On; VSync: Off */ + GFX(set_crt_enable(CRT_SUSPEND)); +#if defined(STB_X) + if (pGeode->Panel) + Gal_pnl_powerdown(); +#else /* STB_X */ + if (pGeode->Panel) + Pnl_PowerDown(); +#endif /* STB_X */ + break; + case DPMSModeOff: + /* Screen: Off; HSync: Off; VSync: Off */ + GFX(set_crt_enable(CRT_DISABLE)); +#if defined(STB_X) + if (pGeode->Panel) + Gal_pnl_powerdown(); +#else /* STB_X */ + if (pGeode->Panel) + Pnl_PowerDown(); +#endif /* STB_X */ + break; + } +} +#endif + +/*---------------------------------------------------------------------------- + * GX2ScreenInit. + * + * Description :This function will be called at the each ofserver + * generation. + * + * Parameters. + * scrnIndex :Specfies the screenindex value during generation. + * pScreen :Pointer to screen info strucrure. + * argc :parameters for command line arguments count + * argv :command line arguments if any it is not used. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static Bool +GX2ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + GeodePtr pGeode; + int i; + Bool Inited = FALSE; + unsigned char *FBStart; + unsigned int req_offscreenmem; + int width, height, displayWidth; + VisualPtr visual; + BoxRec AvailBox; + RegionRec OffscreenRegion; + + DCount = 30; + GeodeDebug(("GX2ScreenInit!\n")); + /* Get driver private */ + pGeode = GX2GetRec(pScreenInfo); + GeodeDebug(("GX2ScreenInit(0)!\n")); + /* + * * Allocate a vgaHWRec + */ + GeodeDebug(("FBVGAActive %d\n", pGeode->FBVGAActive)); + if (pGeode->FBVGAActive) { + if (!vgaHWGetHWRec(pScreenInfo)) + return FALSE; + if (!vgaHWMapMem(pScreenInfo)) + return FALSE; + vgaHWGetIOBase(VGAHWPTR(pScreenInfo)); + } + + if (!GX2MapMem(pScreenInfo)) + return FALSE; + + pGeode->Pitch = GX2CalculatePitchBytes(pScreenInfo->virtualX, + pScreenInfo->bitsPerPixel); + + /* SET UP GRAPHICS MEMORY AVAILABLE FOR PIXMAP CACHE */ + AvailBox.x1 = 0; + AvailBox.y1 = pScreenInfo->virtualY; + AvailBox.x2 = pScreenInfo->displayWidth; + AvailBox.y2 = (pGeode->FBSize / pGeode->Pitch); + + pGeode->CursorSize = 16 * 64; /* 64x64 */ + + if (pGeode->HWCursor) { + /* Compute cursor buffer */ + /* Default cursor offset, end of the frame buffer */ + pGeode->CursorStartOffset = pGeode->FBSize - pGeode->CursorSize; + AvailBox.y2 -= 1; + } + + DEBUGMSG(1, (scrnIndex, X_PROBED, + "Memory manager initialized to (%d,%d) (%d,%d) %d %d %d\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2, + pGeode->Pitch, pScreenInfo->displayWidth, + pScreenInfo->bitsPerPixel)); + + /* set the offscreen offset accordingly */ + if (pGeode->Compression) { + + pGeode->CBPitch = 544; + pGeode->CBSize = 544; + + req_offscreenmem = pScreenInfo->virtualY * pGeode->CBPitch; + req_offscreenmem += pGeode->Pitch - 1; + req_offscreenmem /= pGeode->Pitch; + pGeode->CBOffset = AvailBox.y1 * pGeode->Pitch; + AvailBox.y1 += req_offscreenmem; + } + DEBUGMSG(1, (scrnIndex, X_PROBED, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2)); + + if (!pGeode->NoAccel) { + if (pGeode->NoOfImgBuffers > 0) { + if (pGeode->NoOfImgBuffers <= (AvailBox.y2 - AvailBox.y1)) { + pGeode->AccelImageWriteBufferOffsets = + xalloc(sizeof(unsigned long) * pGeode->NoOfImgBuffers); + + pGeode->AccelImageWriteBufferOffsets[0] = + ((unsigned char *)pGeode->FBBase) + + (AvailBox.y1 * pGeode->Pitch); + + for (i = 1; i < pGeode->NoOfImgBuffers; i++) { + pGeode->AccelImageWriteBufferOffsets[i] = + pGeode->AccelImageWriteBufferOffsets[i - 1] + + pGeode->Pitch; + } + + for (i = 0; i < pGeode->NoOfImgBuffers; i++) { + DEBUGMSG(1, (scrnIndex, X_PROBED, + "memory %d %x\n", i, + pGeode->AccelImageWriteBufferOffsets[i])); + } + AvailBox.y1 += pGeode->NoOfImgBuffers; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Unable to reserve scanline area\n"); + } + } + DEBUGMSG(1, (scrnIndex, X_PROBED, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2)); + + REGION_INIT(pScreen, &OffscreenRegion, &AvailBox, 2); + + if (!xf86InitFBManagerRegion(pScreen, &OffscreenRegion)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); + } else { + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); + } + REGION_UNINIT(pScreen, &OffscreenRegion); + } + + /* Initialise graphics mode */ + if (!GX2EnterGraphics(pScreen, pScreenInfo)) + return FALSE; + + GX2AdjustFrame(scrnIndex, pScreenInfo->frameX0, pScreenInfo->frameY0, 0); + GeodeDebug(("GX2ScreenInit(1)!\n")); + + /* Reset visual list */ + miClearVisualTypes(); + GeodeDebug(("GX2ScreenInit(2)!\n")); + + /* Setup the visual we support */ + if (pScreenInfo->bitsPerPixel > 8) { + DEBUGMSG(1, (scrnIndex, X_PROBED, + "miSetVisualTypes %d %X %X %X\n", + pScreenInfo->depth, + TrueColorMask, + pScreenInfo->rgbBits, pScreenInfo->defaultVisual)); + + if (!miSetVisualTypes(pScreenInfo->depth, + TrueColorMask, + pScreenInfo->rgbBits, + pScreenInfo->defaultVisual)) { + return FALSE; + } + } else { + if (!miSetVisualTypes(pScreenInfo->depth, + miGetDefaultVisualMask(pScreenInfo->depth), + pScreenInfo->rgbBits, + pScreenInfo->defaultVisual)) { + return FALSE; + } + } + GeodeDebug(("GX2ScreenInit(3)!\n")); + + /* Set for RENDER extensions */ + miSetPixmapDepths(); + + /* Call the framebuffer layer's ScreenInit function, and fill in other + * * pScreen fields. + */ + + width = pScreenInfo->virtualX; + height = pScreenInfo->virtualY; + + displayWidth = pScreenInfo->displayWidth; + if (pGeode->Rotate) { + width = pScreenInfo->virtualY; + height = pScreenInfo->virtualX; + } + if (pGeode->ShadowFB) { + pGeode->ShadowPitch = BitmapBytePad(pScreenInfo->bitsPerPixel * width); + pGeode->ShadowPtr = xalloc(pGeode->ShadowPitch * height); + displayWidth = pGeode->ShadowPitch / (pScreenInfo->bitsPerPixel >> 3); + FBStart = pGeode->ShadowPtr; + } else { + pGeode->ShadowPtr = NULL; + + FBStart = pGeode->FBBase; + DEBUGMSG(1, (0, X_PROBED, "FBStart %X \n", FBStart)); + } + + switch (pScreenInfo->bitsPerPixel) { +#if CFB + case 8: + Inited = cfbScreenInit(pScreen, FBStart, width, height, + pScreenInfo->xDpi, pScreenInfo->yDpi, + displayWidth); + break; + case 16: + Inited = cfb16ScreenInit(pScreen, FBStart, width, height, + pScreenInfo->xDpi, pScreenInfo->yDpi, + displayWidth); + break; + case 24: + case 32: + Inited = cfb32ScreenInit(pScreen, FBStart, width, height, + pScreenInfo->xDpi, pScreenInfo->yDpi, + displayWidth); + break; +#else + case 8: + case 16: + case 24: + case 32: + Inited = fbScreenInit(pScreen, FBStart, width, height, + pScreenInfo->xDpi, pScreenInfo->yDpi, + displayWidth, pScreenInfo->bitsPerPixel); + break; +#endif + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in ScreenInit\n", + pScreenInfo->bitsPerPixel); + Inited = FALSE; + break; + } + if (!Inited) + return FALSE; + + GeodeDebug(("GX2ScreenInit(4)!\n")); + xf86SetBlackWhitePixels(pScreen); + + if (!pGeode->ShadowFB) { + GX2DGAInit(pScreen); + } + GeodeDebug(("GX2ScreenInit(5)!\n")); + if (pScreenInfo->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScreenInfo->offset.red; + visual->offsetGreen = pScreenInfo->offset.green; + visual->offsetBlue = pScreenInfo->offset.blue; + visual->redMask = pScreenInfo->mask.red; + visual->greenMask = pScreenInfo->mask.green; + visual->blueMask = pScreenInfo->mask.blue; + } + } + } +#if CFB +#else + /* must be after RGB ordering fixed */ + fbPictureInit(pScreen, 0, 0); +#endif + + GeodeDebug(("GX2ScreenInit(6)!\n")); + if (!pGeode->NoAccel) { + GX2AccelInit(pScreen); + } + GeodeDebug(("GX2ScreenInit(7)!\n")); + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + GeodeDebug(("GX2ScreenInit(8)!\n")); + /* Initialise software cursor */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + /* Initialize HW cursor layer. + * * Must follow software cursor initialization + */ + if (pGeode->HWCursor) { + if (!GX2HWCursorInit(pScreen)) + xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + } + GeodeDebug(("GX2ScreenInit(9)!\n")); + /* Setup default colourmap */ + if (!miCreateDefColormap(pScreen)) { + return FALSE; + } + GeodeDebug(("GX2ScreenInit(10)!\n")); + /* Initialize colormap layer. + * * Must follow initialization of the default colormap + */ + if (!xf86HandleColormaps(pScreen, 256, 8, + GX2LoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | + CMAP_RELOAD_ON_MODE_SWITCH)) { + return FALSE; + } + + GeodeDebug(("GX2ScreenInit(11)!\n")); + + if (pGeode->ShadowFB) { + RefreshAreaFuncPtr refreshArea = GX2RefreshArea; + + if (pGeode->Rotate) { + if (!pGeode->PointerMoved) { + pGeode->PointerMoved = pScreenInfo->PointerMoved; + pScreenInfo->PointerMoved = GX2PointerMoved; + } + switch (pScreenInfo->bitsPerPixel) { + case 8: + refreshArea = GX2RefreshArea8; + break; + case 16: + refreshArea = GX2RefreshArea16; + break; + case 24: + refreshArea = GX2RefreshArea24; + break; + case 32: + refreshArea = GX2RefreshArea32; + break; + } + } + ShadowFBInit(pScreen, refreshArea); + } +#ifdef DPMSExtension + xf86DPMSInit(pScreen, GX2DPMSSet, 0); +#endif + GeodeDebug(("GX2ScreenInit(12)!\n")); + + pScreenInfo->memPhysBase = (unsigned long)pGeode->FBBase; + pScreenInfo->fbOffset = 0; + + GeodeDebug(("GX2ScreenInit(13)!\n")); + GX2InitVideo(pScreen); /* needed for video */ + /* Wrap the screen's CloseScreen vector and set its + * SaveScreen vector + */ + pGeode->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = GX2CloseScreen; + + pScreen->SaveScreen = GX2SaveScreen; + GeodeDebug(("GX2ScreenInit(14)!\n")); + + /* Report any unused options */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options); + } + GeodeDebug(("GX2ScreenInit(15)!\n")); + return TRUE; +} + +/*---------------------------------------------------------------------------- + * GX2SwitchMode. + * + * Description :This function will switches the screen mode + * + * Parameters: + * scrnIndex :Specfies the screen index value. + * pMode :pointer to the mode structure. + * flags :may be used for status check?. + * + * Returns :Returns TRUE on success and FALSE on failure. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +Bool +GX2SwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) +{ + GeodeDebug(("GX2SwitchMode!\n")); + return GX2SetMode(xf86Screens[scrnIndex], pMode); +} + +/*---------------------------------------------------------------------------- + * GX2AdjustFrame. + * + * Description :This function is used to intiallize the start + * address of the memory. + * Parameters. + * scrnIndex :Specfies the screen index value. + * x :x co-ordinate value interms of pixels. + * y :y co-ordinate value interms of pixels. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +void +GX2AdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + GeodePtr pGeode = GX2GetRec(pScreenInfo); + unsigned long offset; + + /* y offset */ + offset = (unsigned long)y *(unsigned long)pGeode->Pitch; + + /* x offset */ + offset += x * (pScreenInfo->bitsPerPixel >> 3); + + GFX(set_display_offset(offset)); +} + +/*---------------------------------------------------------------------------- + * GX2EnterVT. + * + * Description :This is called when VT switching back to the X server + * + * Parameters. + * scrnIndex :Specfies the screen index value. + * flags :Not used inside the function. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static Bool +GX2EnterVT(int scrnIndex, int flags) +{ + GeodeDebug(("GX2EnterVT!\n")); + return GX2EnterGraphics(NULL, xf86Screens[scrnIndex]); +} + +/*---------------------------------------------------------------------------- + * GX2LeaveVT. + * + * Description :This is called when VT switching X server text mode. + * + * Parameters. + * scrnIndex :Specfies the screen index value. + * flags :Not used inside the function. + * + * Returns :none. + * + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static void +GX2LeaveVT(int scrnIndex, int flags) +{ + GeodeDebug(("GX2LeaveVT!\n")); + GX2LeaveGraphics(xf86Screens[scrnIndex]); +} + +/*---------------------------------------------------------------------------- + * GX2FreeScreen. + * + * Description :This is called to free any persistent data structures. + * + * Parameters. + * scrnIndex :Specfies the screen index value. + * flags :Not used inside the function. + * + * Returns :none. + * + * Comments :This will be called only when screen being deleted.. +*---------------------------------------------------------------------------- +*/ +static void +GX2FreeScreen(int scrnIndex, int flags) +{ + GeodeDebug(("GX2FreeScreen!\n")); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + GX2FreeRec(xf86Screens[scrnIndex]); +} + +/*---------------------------------------------------------------------------- + * GX2ValidMode. + * + * Description :This function checks if a mode is suitable for selected + * chipset. + * Parameters. + * scrnIndex :Specfies the screen index value. + * pMode :Pointer to the screen mode structure.. + * verbose :not used for implementation. + * flags :not used for implementation + * + * Returns :MODE_OK if the specified mode is supported or + * MODE_NO_INTERLACE. + * Comments :none. +*---------------------------------------------------------------------------- +*/ +static int +GX2ValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) +{ + unsigned int total_memory_required; + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + int ret = -1; + GeodePtr pGeode = GX2GetRec(pScreenInfo); + + DEBUGMSG(1, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n", + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, GX2GetRefreshRate(pMode))); + { + DEBUGMSG(1, (0, X_NONE, "CRT mode\n")); + if (pMode->Flags & V_INTERLACE) + return MODE_NO_INTERLACE; + +#if defined(STB_X) + Gal_is_display_mode_supported(pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, + GX2GetRefreshRate(pMode), &ret); +#else /* STB_X */ + ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScreenInfo->bitsPerPixel, + GX2GetRefreshRate(pMode)); +#endif /* STB_X */ + } + if (ret < 0) + return MODE_NOMODE; + + total_memory_required = GX2CalculatePitchBytes(pMode->CrtcHDisplay, + pScreenInfo->bitsPerPixel) * + pMode->CrtcVDisplay; + + DEBUGMSG(1, (0, X_NONE, "Total Mem %X %X\n", + total_memory_required, pGeode->FBSize)); + + if (total_memory_required > pGeode->FBSize) + return MODE_MEM; + + return MODE_OK; +} + +/*---------------------------------------------------------------------------- + * GX2LoadPalette. + * + * Description :This function sets the palette entry used for graphics data + * + * Parameters. + * pScreenInfo:Points the screeninfo structure. + * numColors:Specifies the no of colors it supported. + * indizes :This is used get index value . + * LOCO :to be added. + * pVisual :to be added. + * + * Returns :MODE_OK if the specified mode is supported or + * MODE_NO_INTERLACE. + * Comments :none. +*---------------------------------------------------------------------------- +*/ + +static void +GX2LoadPalette(ScrnInfoPtr pScreenInfo, + int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) +{ + int i, index, color; + + for (i = 0; i < numColors; i++) { + index = indizes[i] & 0xFF; + color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | + (((unsigned long)(colors[index].green & 0xFF)) << 8) | + ((unsigned long)(colors[index].blue & 0xFF)); + DEBUGMSG(0, (0, X_NONE, "GX2LoadPalette: %d %d %X\n", + numColors, index, color)); + + GFX(set_display_palette_entry(index, color)); + } +} + +static Bool +GX2MapMem(ScrnInfoPtr pScreenInfo) +{ + GeodePtr pGeode = GEODEPTR(pScreenInfo); + +#if defined(STB_X) + pGeode->FBBase = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_FRAMEBUFFER, + pGeode->FBLinearAddr, + pGeode->FBSize); + +#else + gfx_virt_regptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_MMIO, + (unsigned int) + gfx_get_cpu_register_base + (), pGeode->cpu_reg_size); + + if (pGeode->DetectedChipSet & GX2) { + gfx_virt_gpptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_MMIO, + (unsigned int) + gfx_get_graphics_register_base + (), + pGeode->gp_reg_size); + } else { + gfx_virt_spptr = gfx_virt_regptr; + } + + gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_MMIO, + (unsigned int) + gfx_get_vid_register_base + (), pGeode->vid_reg_size); + + gfx_virt_fbptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_FRAMEBUFFER, + pGeode->FBLinearAddr, + pGeode->FBSize); + + pGeode->FBBase = gfx_virt_fbptr; + + DEBUGMSG(1, (0, X_NONE, "Set mode %X %X %X %X %X\n", + gfx_virt_regptr, + gfx_virt_gpptr, + gfx_virt_spptr, gfx_virt_vidptr, gfx_virt_fbptr)); + + /* CHECK IF REGISTERS WERE MAPPED SUCCESSFULLY */ + if ((!gfx_virt_regptr) || + (!gfx_virt_gpptr) || (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) { + DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n")); + return (FALSE); + } + + /* Map the XpressROM ptr to read what platform are we on */ + XpressROMPtr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex, + VIDMEM_FRAMEBUFFER, 0xF0000, + 0x10000); + + DEBUGMSG(1, (0, X_NONE, "adapter info %x %x %x %x, %X\n", + pGeode->cpu_version, + pGeode->vid_version, + pGeode->FBSize, pGeode->FBBase, XpressROMPtr)); +#endif + + return TRUE; +} + +/* + * Unmap the framebuffer and MMIO memory. + */ + +static Bool +GX2UnmapMem(ScrnInfoPtr pScreenInfo) +{ +#if !defined(STB_X) + GeodePtr pGeode = GEODEPTR(pScreenInfo); + + /* unmap all the memory map's */ + xf86UnMapVidMem(pScreenInfo->scrnIndex, + gfx_virt_regptr, pGeode->cpu_reg_size); + if (pGeode->DetectedChipSet & GX2) { + xf86UnMapVidMem(pScreenInfo->scrnIndex, + gfx_virt_gpptr, pGeode->gp_reg_size); + } + xf86UnMapVidMem(pScreenInfo->scrnIndex, + gfx_virt_vidptr, pGeode->vid_reg_size); + xf86UnMapVidMem(pScreenInfo->scrnIndex, gfx_virt_fbptr, pGeode->FBSize); + xf86UnMapVidMem(pScreenInfo->scrnIndex, XpressROMPtr, 0x10000); +#endif /* STB_X */ + return TRUE; +} + +/* End of file */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_shadow.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_shadow.c new file mode 100644 index 000000000..367b9e442 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_shadow.c @@ -0,0 +1,468 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_shadow.c,v 1.2 2003/01/14 09:34:32 alanh Exp $ */ +/* + * $Workfile: nsc_gx2_shadow.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: Direct graphics display routines are implemented and + * graphics rendering are all done in memory. + * + * Project: Geode Xfree Frame buffer device driver. + * + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "nsc.h" +#include "shadowfb.h" +#include "servermd.h" + +void GX2RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void GX2PointerMoved(int index, int x, int y); +void GX2RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void GX2RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void GX2RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void GX2RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + +/*---------------------------------------------------------------------------- + * GX2RefreshArea. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer. + * Parameters. + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns :none + * + * Comments : none + * +*---------------------------------------------------------------------------- +*/ +void +GX2RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + while (num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pGeode->ShadowPtr + (pbox->y1 * pGeode->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pGeode->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + while (height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pGeode->ShadowPitch; + } + + pbox++; + } +} + +/*---------------------------------------------------------------------------- + * GX2PointerMoved. + * + * Description :This function moves one screen memory from one area to other. + * + * Parameters. + * index :Pointer to screen index. + * x :Specifies the new x co-ordinates of new area. + * y :Specifies the new y co-ordinates of new area. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX2PointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + GeodePtr pGeode = GEODEPTR(pScrn); + int newX, newY; + + if (pGeode->Rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + } + (*pGeode->PointerMoved) (index, newX, newY); +} + +/*---------------------------------------------------------------------------- + * GX2RefreshArea8. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 8bpp. + * Parameters. + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX2RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2, + srcPitch3, srcPitch4; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pGeode->Rotate * pGeode->ShadowPitch; + srcPitch2 = srcPitch * 2; + srcPitch3 = srcPitch * 3; + srcPitch4 = srcPitch * 4; + while (num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if (pGeode->Rotate == 1) { + dstPtr = pGeode->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = pGeode->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = pGeode->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pGeode->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + while (width--) { + src = srcPtr; + dst = (CARD32 *) dstPtr; + count = height; + while (count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch2] << 16) | (src[srcPitch3] << 24); + src += srcPitch4; + } + srcPtr += pGeode->Rotate; + dstPtr += dstPitch; + } + pbox++; + } +} + +/*---------------------------------------------------------------------------- + * GX2RefreshArea16. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 16bpp. + * Parameters: + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX2RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pGeode->Rotate * pGeode->ShadowPitch >> 1; + srcPitch2 = srcPitch * 2; + while (num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + if (pGeode->Rotate == 1) { + dstPtr = (CARD16 *) pGeode->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16 *) pGeode->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD16 *) pGeode->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16 *) pGeode->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while (width--) { + src = srcPtr; + dst = (CARD32 *) dstPtr; + count = height; + while (count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch2; + } + srcPtr += pGeode->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + +/*---------------------------------------------------------------------------- + * GX2RefreshArea24. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 24bpp. + * Parameters. + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX2RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2, srcPitch3; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = BitmapBytePad(pScrn->displayWidth * 24); + srcPitch = -pGeode->Rotate * pGeode->ShadowPitch; + srcPitch2 = srcPitch * 2; + srcPitch3 = srcPitch * 3; + while (num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* blocks of 3 dwords */ + if (pGeode->Rotate == 1) { + dstPtr = pGeode->FBBase + + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); + srcPtr = pGeode->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); + } else { + dstPtr = pGeode->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); + srcPtr = pGeode->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; + } + while (width--) { + src = srcPtr; + dst = (CARD32 *) dstPtr; + count = height; + while (count--) { + dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | + (src[srcPitch] << 24); + dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | + (src[srcPitch2] << 16) | (src[srcPitch2 + 1] << 24); + dst[2] = src[srcPitch2 + 2] | (src[srcPitch3] << 8) | + (src[srcPitch3 + 1] << 16) | (src[srcPitch3 + 2] << 24); + dst += 3; + src += srcPitch << 2; + } + srcPtr += pGeode->Rotate * 3; + dstPtr += dstPitch; + } + pbox++; + } +} + +/*---------------------------------------------------------------------------- + * GX2RefreshArea32. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 32bpp. + * Parameters: + * pScrn :Pointer to screen structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * Returns : none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX2RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + int count, width, height, dstPitch, srcPitch; + CARD32 *dstPtr, *srcPtr, *src, *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pGeode->Rotate * pGeode->ShadowPitch >> 2; + while (num--) { + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + if (pGeode->Rotate == 1) { + dstPtr = (CARD32 *) pGeode->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; + srcPtr = (CARD32 *) pGeode->ShadowPtr + + ((1 - pbox->y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD32 *) pGeode->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; + srcPtr = (CARD32 *) pGeode->ShadowPtr + + (pbox->y1 * srcPitch) + pbox->x2 - 1; + } + while (width--) { + src = srcPtr; + dst = dstPtr; + count = height; + while (count--) { + *(dst++) = *src; + src += srcPitch; + } + srcPtr += pGeode->Rotate; + dstPtr += dstPitch; + } + pbox++; + } +} + +/* End of file */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_vga.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_vga.c new file mode 100644 index 000000000..ce1f57539 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_vga.c @@ -0,0 +1,570 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_vga.c,v 1.2 2003/01/14 09:34:32 alanh Exp $ */ +/* + * $Workfile: nsc_gx2_vga.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * This file contains routines to set modes using the VGA registers. + * Since this file is for the first generation graphics unit, it interfaces + * to SoftVGA registers. It works for both VSA1 and VSA2. + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * nsc XFree86 + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* VGA STRUCTURE */ + +#define GU2_STD_CRTC_REGS 25 +#define GU2_EXT_CRTC_REGS 15 +#define GU2_GDC_REGS 9 +#define GU2_SEQ_REGS 5 + +#define GU2_VGA_FLAG_MISC_OUTPUT 0x1 +#define GU2_VGA_FLAG_STD_CRTC 0x2 +#define GU2_VGA_FLAG_EXT_CRTC 0x4 +#define GU2_VGA_FLAG_GDC 0x10 +#define GU2_VGA_FLAG_SEQ 0x20 +#define GU2_VGA_FLAG_PALETTE 0x40 +#define GU2_VGA_FLAG_ATTR 0x80 + +static unsigned int GDCregs[10]; +static unsigned int SEQregs[10]; +static unsigned int palette[256]; +static unsigned int ATTRregs[32]; +static unsigned char *font_data = NULL; + +#define VGA_BLOCK 0x40000 /* 256 k */ + +void gu2_vga_extcrtc(char offset, int reset); +int gu2_get_vga_active(void); +void gu2_vga_font_data(int flag); +void gu2_set_vga(int reset); +int gu2_vga_seq_blanking(void); +int gu2_vga_attr_ctrl(int reset); +void gu2_vga_to_gfx(void); +void gu2_gfx_to_vga(int vga_mode); +int gu2_vga_seq_reset(int reset); +int gu2_vga_save(gfx_vga_struct * vga, int flags); +void gu2_vga_clear_extended(void); +int gu2_vga_restore(gfx_vga_struct * vga, int flags); + +int +gu2_get_vga_active(void) +{ + int data = gfx_read_reg32(MDC_GENERAL_CFG); + + if (data & MDC_GCFG_VGAE) + return 1; + return 0; +} + +void +gu2_vga_font_data(int flag) +{ + if (flag == 0) { + if (font_data == NULL) { + font_data = malloc(VGA_BLOCK); + } + DEBUGMSG(1, (0, X_NONE, "Saving VGA Data\n")); + memcpy(font_data, gfx_virt_fbptr, VGA_BLOCK); + } else { + if (font_data) { + DEBUGMSG(1, (0, X_NONE, "Restore VGA Data\n")); + memcpy(gfx_virt_fbptr, font_data, VGA_BLOCK); + free(font_data); + font_data = NULL; + } + } +} + +void +gu2_set_vga(int reset) +{ + int data = gfx_read_reg32(MDC_GENERAL_CFG); + + if (reset) + data |= MDC_GCFG_VGAE; + else + data &= ~MDC_GCFG_VGAE; + gfx_write_reg32(MDC_GENERAL_CFG, data); +} + +int +gu2_vga_seq_blanking(void) +{ + int tmp; + + gfx_outb(0x3C4, 1); + tmp = gfx_inb(0x3C5); + tmp |= 0x20; + tmp |= tmp << 8; + gfx_outw(0x3C4, tmp); + + gfx_delay_milliseconds(1); + return (GFX_STATUS_OK); +} + +int +gu2_vga_attr_ctrl(int reset) +{ + int tmp; + + tmp = gfx_inb(0x3DA); + gfx_outb(0x3C0, (unsigned char)(reset ? 0x00 : 0x20)); + if (reset) + tmp = gfx_inb(0x3DA); + return (GFX_STATUS_OK); +} + +void +gu2_vga_to_gfx(void) +{ + gu2_vga_attr_ctrl(0); + + gu2_vga_seq_blanking(); + gfx_delay_milliseconds(2); + + gu2_vga_extcrtc(0x3F, 1); +} + +void +gu2_gfx_to_vga(int vga_mode) +{ + int tmp; + char sequencer; + + gu2_vga_extcrtc(0x40, vga_mode); + + /* clear the display blanking bit */ + gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); + sequencer = gfx_inb(MDC_SEQUENCER_DATA); + sequencer &= ~MDC_CLK_MODE_SCREEN_OFF; + sequencer |= 1; + gfx_outb(MDC_SEQUENCER_DATA, sequencer); + + gfx_delay_milliseconds(1); + + /*restart the sequencer */ + gfx_outw(0x3C4, 0x300); + + /* turn on the attribute controler */ + tmp = gfx_inb(0x3DA); + gfx_outb(0x3C0, 0x20); + tmp = gfx_inb(0x3DA); + + gu2_vga_extcrtc(0x3F, 0); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_seq_reset + * + * This routine enables or disables SoftVGA. It is used to make SoftVGA + * "be quiet" and not interfere with any of the direct hardware access from + * Durango. For VSA1, the sequencer is reset to stop text redraws. VSA2 may + * provide a better way to have SoftVGA sit in the background. + *----------------------------------------------------------------------------- + */ +int +gu2_vga_seq_reset(int reset) +{ + gfx_outb(0x3C4, 0); + gfx_outb(0x3C5, (unsigned char)(reset ? 0x00 : 0x03)); + return (GFX_STATUS_OK); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_save + * + * This routine saves the state of the VGA registers into the specified + * structure. Flags indicate what portions of the register state need to + * be saved. + *----------------------------------------------------------------------------- + */ +int +gu2_vga_save(gfx_vga_struct * vga, int flags) +{ + int i; + unsigned short crtcindex, crtcdata; + + crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + /* CHECK MISCELLANEOUS OUTPUT FLAG */ + + if (flags & GU2_VGA_FLAG_MISC_OUTPUT) { + /* SAVE MISCCELLANEOUS OUTPUT REGISTER */ + + vga->miscOutput = gfx_inb(0x3CC); + } + + /* CHECK SEQ */ + + if (flags & GU2_VGA_FLAG_SEQ) { + /* SAVE STANDARD CRTC REGISTERS */ + + for (i = 1; i < GU2_SEQ_REGS; i++) { + gfx_outb(0x3C4, (unsigned char)i); + SEQregs[i] = gfx_inb(0x3C5); + } + } + + /* CHECK STANDARD CRTC FLAG */ + + if (flags & GU2_VGA_FLAG_STD_CRTC) { + /* SAVE STANDARD CRTC REGISTERS */ + + for (i = 0; i < GU2_STD_CRTC_REGS; i++) { + gfx_outb(crtcindex, (unsigned char)i); + vga->stdCRTCregs[i] = gfx_inb(crtcdata); + } + } + + /* CHECK GDC */ + + if (flags & GU2_VGA_FLAG_GDC) { + /* SAVE STANDARD CRTC REGISTERS */ + + for (i = 0; i < GU2_GDC_REGS; i++) { + gfx_outb(0x3CE, (unsigned char)i); + GDCregs[i] = gfx_inb(0x3CF); + } + } + + /* CHECK EXTENDED CRTC FLAG */ + + if (flags & GU2_VGA_FLAG_EXT_CRTC) { + /* SAVE EXTENDED CRTC REGISTERS */ + + for (i = 0; i < GU2_EXT_CRTC_REGS; i++) { + gfx_outb(crtcindex, (unsigned char)(0x40 + i)); + vga->extCRTCregs[i] = gfx_inb(crtcdata); + } + } + + if (flags & GU2_VGA_FLAG_PALETTE) { + /* SAVE PALETTE DATA */ + + for (i = 0; i < 0x100; i++) { + gfx_outb(0x3C7, i); + palette[i] = gfx_inb(0x3C9); + } + } + + if (flags & GU2_VGA_FLAG_ATTR) { + /* SAVE Attribute DATA */ + + for (i = 0; i < 21; i++) { + gfx_inb(0x3DA); + gfx_outb(0x3C0, i); + ATTRregs[i] = gfx_inb(0x3C1); + } + } + /* save the VGA data */ + gu2_vga_font_data(0); + return (0); +} + +/*----------------------------------------------------------------------------- + * gfx_vga_clear_extended + * + * This routine clears the extended SoftVGA register values to have SoftVGA + * behave like standard VGA. + *----------------------------------------------------------------------------- + */ +void +gu2_vga_clear_extended(void) +{ + int i; + unsigned short crtcindex, crtcdata; + + crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + gfx_outb(crtcindex, 0x30); + gfx_outb(crtcdata, 0x57); + gfx_outb(crtcdata, 0x4C); + for (i = 0x41; i <= 0x4F; i++) { + gfx_outb(crtcindex, (unsigned char)i); + gfx_outb(crtcdata, 0); + } + gfx_outb(crtcindex, 0x30); + gfx_outb(crtcdata, 0x00); +} + +void +gu2_vga_extcrtc(char offset, int reset) +{ + unsigned short crtcindex, crtcdata; + + crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + /* UNLOCK EXTENDED CRTC REGISTERS */ + + gfx_outb(crtcindex, 0x30); + gfx_outb(crtcdata, 0x57); + gfx_outb(crtcdata, 0x4C); + + /* RESTORE EXTENDED CRTC REGISTERS */ + + gfx_outb(crtcindex, offset); + gfx_outb(crtcdata, reset); + +#if 0 + /* LOCK EXTENDED CRTC REGISTERS */ + + gfx_outb(crtcindex, 0x30); + gfx_outb(crtcdata, 0x00); +#endif +} + +/*----------------------------------------------------------------------------- + * gfx_vga_restore + * + * This routine restores the state of the VGA registers from the specified + * structure. Flags indicate what portions of the register state need to + * be saved. + *----------------------------------------------------------------------------- + */ +int +gu2_vga_restore(gfx_vga_struct * vga, int flags) +{ + int i; + unsigned short crtcindex, crtcdata; + + crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + /* CHECK MISCELLANEOUS OUTPUT FLAG */ + + if (flags & GU2_VGA_FLAG_MISC_OUTPUT) { + /* RESTORE MISCELLANEOUS OUTPUT REGISTER VALUE */ + + gfx_outb(0x3C2, vga->miscOutput); + } + + /* CHECK SEQ */ + + if (flags & GU2_VGA_FLAG_SEQ) { + /* RESTORE STANDARD CRTC REGISTERS */ + + for (i = 1; i < GU2_SEQ_REGS; i++) { + gfx_outb(0x3C4, (unsigned char)i); + gfx_outb(0x3C5, SEQregs[i]); + } + } + + /* CHECK STANDARD CRTC FLAG */ + + if (flags & GU2_VGA_FLAG_STD_CRTC) { + /* UNLOCK STANDARD CRTC REGISTERS */ + + gfx_outb(crtcindex, 0x11); + gfx_outb(crtcdata, 0); + + /* RESTORE STANDARD CRTC REGISTERS */ + + for (i = 0; i < GU2_STD_CRTC_REGS; i++) { + gfx_outb(crtcindex, (unsigned char)i); + gfx_outb(crtcdata, vga->stdCRTCregs[i]); + } + } + + /* CHECK GDC */ + + if (flags & GU2_VGA_FLAG_GDC) { + /* SAVE STANDARD CRTC REGISTERS */ + + for (i = 0; i < GU2_GDC_REGS; i++) { + gfx_outb(0x3CE, (unsigned char)i); + gfx_outb(0x3CF, GDCregs[i]); + } + } + + /* CHECK EXTENDED CRTC FLAG */ + + if (flags & GU2_VGA_FLAG_EXT_CRTC) { + /* UNLOCK EXTENDED CRTC REGISTERS */ + + gfx_outb(crtcindex, 0x30); + gfx_outb(crtcdata, 0x57); + gfx_outb(crtcdata, 0x4C); + + /* RESTORE EXTENDED CRTC REGISTERS */ + + for (i = 1; i < GU2_EXT_CRTC_REGS; i++) { + gfx_outb(crtcindex, (unsigned char)(0x40 + i)); + gfx_outb(crtcdata, vga->extCRTCregs[i]); + } + + /* LOCK EXTENDED CRTC REGISTERS */ + + gfx_outb(crtcindex, 0x30); + gfx_outb(crtcdata, 0x00); + + /* CHECK IF DIRECT FRAME BUFFER MODE (VESA MODE) */ + + if (vga->extCRTCregs[0x03] & 1) { + /* SET BORDER COLOR TO BLACK */ + /* This really should be another thing saved/restored, but */ + /* Durango currently doesn't do the attr controller registers. */ + + gfx_inb(0x3BA); /* Reset flip-flop */ + gfx_inb(0x3DA); + gfx_outb(0x3C0, 0x11); + gfx_outb(0x3C0, 0x00); + } + } + + if (flags & GU2_VGA_FLAG_PALETTE) { + /* RESTORE PALETTE DATA */ + + for (i = 0; i < 0x100; i++) { + gfx_outb(0x3C8, i); + gfx_outb(0x3C9, palette[i]); + } + } + + if (flags & GU2_VGA_FLAG_ATTR) { + /* RESTORE Attribute DATA */ + + for (i = 0; i < 21; i++) { + gfx_inb(0x3DA); + gfx_outb(0x3C0, i); + gfx_outb(0x3C0, ATTRregs[i]); + } + /* SAVE Attribute DATA */ + + for (i = 0; i < 21; i++) { + gfx_inb(0x3DA); + gfx_outb(0x3C0, i); + } + } + + /* restore the VGA data */ + gu2_vga_font_data(1); + + return (0); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_video.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_video.c new file mode 100644 index 000000000..74d7d4e8d --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_video.c @@ -0,0 +1,1570 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_video.c,v 1.5 2003/02/21 16:51:09 alanh Exp $ */ +/* + * $Workfile: nsc_gx2_video.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file consists of main Xfree video supported routines. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * National Xfree frame buffer driver + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * National Xfree frame buffer driver + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * National Xfree frame buffer driver + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* + * Fixes & Extensions to support Y800 greyscale modes + * Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "nsc.h" +#include "Xv.h" +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" +#include "nsc_fourcc.h" + +#define OFF_DELAY 200 /* milliseconds */ +#define FREE_DELAY 60000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) +#define XV_PROFILE 0 +#define REINIT 1 +#ifndef XvExtension +void +GX2InitVideo(ScreenPtr pScreen) +{ +} + +void +GX2ResetVideo(ScrnInfoPtr pScrn) +{ +} +#else + +#define DBUF 1 +void GX2InitVideo(ScreenPtr pScreen); +void GX2ResetVideo(ScrnInfoPtr pScrn); +static XF86VideoAdaptorPtr GX2SetupImageVideo(ScreenPtr); +static void GX2InitOffscreenImages(ScreenPtr); +static void GX2StopVideo(ScrnInfoPtr, pointer, Bool); +static int GX2SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int GX2GetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); +static void GX2QueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, + unsigned int *, pointer); +static int GX2PutImage(ScrnInfoPtr, short, short, short, short, short, short, + short, short, int, unsigned char *, short, short, Bool, + RegionPtr, pointer); +static int GX2QueryImageAttributes(ScrnInfoPtr, int, unsigned short *, + unsigned short *, int *, int *); + +static void GX2BlockHandler(int, pointer, pointer, pointer); +void GX2SetVideoPosition(int x, int y, int width, int height, + short src_w, short src_h, short drw_w, + short drw_h, int id, int offset, ScrnInfoPtr pScrn); + +extern void GX2AccelSync(ScrnInfoPtr pScreenInfo); + +#if !defined(STB_X) +extern int DeltaX, DeltaY; +#else +int DeltaX, DeltaY; +#endif + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static Atom xvColorKey, xvColorKeyMode, xvFilter +#if DBUF + , xvDoubleBuffer +#endif + ; + +/*---------------------------------------------------------------------------- + * GX2InitVideo + * + * Description :This is the initialization routine.It creates a new video adapter + * and calls GX2SetupImageVideo to initialize the adaptor by filling + * XF86VideoAdaptorREc.Then it lists the existing adaptors and adds the + * new one to it. Finally the list of XF86VideoAdaptorPtr pointers are + * passed to the xf86XVScreenInit(). + * + * Parameters. + * ScreenPtr + * pScreen :Screen handler pointer having screen information. + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +void +GX2InitVideo(ScreenPtr pScreen) +{ + GeodePtr pGeode; + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + + pGeode = GEODEPTR(pScreenInfo); + + if (!pGeode->NoAccel) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + + int num_adaptors; + + newAdaptor = GX2SetupImageVideo(pScreen); + GX2InitOffscreenImages(pScreen); + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if (newAdaptor) { + if (!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); + if (newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if (num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if (newAdaptors) + xfree(newAdaptors); + } +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = { + { + 0, + "XV_IMAGE", + 1024, 1024, + {1, 1} + } +}; + +#define NUM_FORMATS 4 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = { + {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#if DBUF +#define NUM_ATTRIBUTES 4 +#else +#define NUM_ATTRIBUTES 3 +#endif + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { +#if DBUF + {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, +#endif + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, + {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} +}; + +#define NUM_IMAGES 7 + +static XF86ImageRec Images[NUM_IMAGES] = { + XVIMAGE_UYVY, + XVIMAGE_YUY2, + XVIMAGE_Y2YU, + XVIMAGE_YVYU, + XVIMAGE_Y800, + XVIMAGE_I420, + XVIMAGE_YV12 +}; + +typedef struct +{ + FBAreaPtr area; + FBLinearPtr linear; + RegionRec clip; + CARD32 colorKey; + CARD32 colorKeyMode; + CARD32 filter; + CARD32 videoStatus; + Time offTime; + Time freeTime; +#if DBUF + Bool doubleBuffer; + int currentBuffer; +#endif +} +GeodePortPrivRec, *GeodePortPrivPtr; + +#define GET_PORT_PRIVATE(pScrn) \ + (GeodePortPrivPtr)((GEODEPTR(pScrn))->adaptor->pPortPrivates[0].ptr) + +/*---------------------------------------------------------------------------- + * GX2SetColorKey + * + * Description :This function reads the color key for the pallete and + * sets the video color key register. + * + * Parameters. + * ScreenInfoPtr + * pScrn :Screen pointer having screen information. + * pPriv :Video port private data + * + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static INT32 +GX2SetColorkey(ScrnInfoPtr pScrn, GeodePortPrivPtr pPriv) +{ + int red, green, blue; + unsigned long key; + + switch (pScrn->depth) { + case 8: + GFX(get_display_palette_entry(pPriv->colorKey & 0xFF, &key)); + red = ((key >> 16) & 0xFF); + green = ((key >> 8) & 0xFF); + blue = (key & 0xFF); + break; + case 16: + red = (pPriv->colorKey & pScrn->mask.red) >> + pScrn->offset.red << (8 - pScrn->weight.red); + green = (pPriv->colorKey & pScrn->mask.green) >> + pScrn->offset.green << (8 - pScrn->weight.green); + blue = (pPriv->colorKey & pScrn->mask.blue) >> + pScrn->offset.blue << (8 - pScrn->weight.blue); + break; + default: + /* for > 16 bpp we send in the mask in xf86SetWeight. This + * function is providing the offset by 1 more. So we take + * this as a special case and subtract 1 for > 16 + */ + red = (pPriv->colorKey & pScrn->mask.red) >> + (pScrn->offset.red - 1) << (8 - pScrn->weight.red); + green = (pPriv->colorKey & pScrn->mask.green) >> + (pScrn->offset.green - 1) << (8 - pScrn->weight.green); + blue = (pPriv->colorKey & pScrn->mask.blue) >> + (pScrn->offset.blue - 1) << (8 - pScrn->weight.blue); + break; + } + + GFX(set_video_color_key((blue | (green << 8) | (red << 16)), 0xFFFFFF, + (pPriv->colorKeyMode == 0))); + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + return 0; +} + +/*---------------------------------------------------------------------------- + * GX2ResetVideo + * + * Description : This function resets the video + * + * Parameters. + * ScreenInfoPtr + * pScrn :Screen pointer having screen information. + * + * Returns :None + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ + +void +GX2ResetVideo(ScrnInfoPtr pScrn) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + if (!pGeode->NoAccel) { + GeodePortPrivPtr pPriv = pGeode->adaptor->pPortPrivates[0].ptr; + + GX2AccelSync(pScrn); + GFX(set_video_palette(NULL)); + GX2SetColorkey(pScrn, pPriv); + GFX(set_video_filter(pPriv->filter, pPriv->filter)); + } +} + +/*---------------------------------------------------------------------------- + * GX2SetupImageVideo + * + * Description : This function allocates space for a Videoadaptor and initializes + * the XF86VideoAdaptorPtr record. + * + * Parameters. + * ScreenPtr + * pScreen :Screen handler pointer having screen information. + * + * Returns :XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ + +static XF86VideoAdaptorPtr +GX2SetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GeodePtr pGeode = GEODEPTR(pScrn); + XF86VideoAdaptorPtr adapt; + GeodePortPrivPtr pPriv; + + if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "National Semiconductor Corporation"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion *) (&adapt[1]); + pPriv = (GeodePortPrivPtr) (&adapt->pPortPrivates[1]); + adapt->pPortPrivates[0].ptr = (pointer) (pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = GX2StopVideo; + adapt->SetPortAttribute = GX2SetPortAttribute; + adapt->GetPortAttribute = GX2GetPortAttribute; + adapt->QueryBestSize = GX2QueryBestSize; + adapt->PutImage = GX2PutImage; + adapt->QueryImageAttributes = GX2QueryImageAttributes; + + pPriv->colorKey = pGeode->videoKey; + pPriv->colorKeyMode = 0; + pPriv->filter = 0; + pPriv->videoStatus = 0; +#if DBUF + pPriv->doubleBuffer = TRUE; + pPriv->currentBuffer = 0; /* init to first buffer */ +#endif + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + pGeode->adaptor = adapt; + + pGeode->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = GX2BlockHandler; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); + xvFilter = MAKE_ATOM("XV_FILTER"); +#if DBUF + xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); +#endif + + GX2ResetVideo(pScrn); + + return adapt; +} + +#if REINIT +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if (num != REGION_NUM_RECTS(B)) + return FALSE; + + if ((A->extents.x1 != B->extents.x1) || + (A->extents.x2 != B->extents.x2) || + (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) + return FALSE; + + dataA = (int *)REGION_RECTS(A); + dataB = (int *)REGION_RECTS(B); + + while (num--) { + if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; +} +#endif + +/*---------------------------------------------------------------------------- + * GX2StopVideo + * + * Description :This function is used to stop input and output video + * + * Parameters. + * pScreenInfo + * pScrn :Screen handler pointer having screen information. + * data :Pointer to the video port's private data + * exit :Flag indicating whether the offscreen areas used for video + * to be deallocated or not. + * Returns :none + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static void +GX2StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) +{ + GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; + GeodePtr pGeode = GEODEPTR(pScrn); + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + GX2AccelSync(pScrn); + if (exit) { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + GFX(set_video_enable(0)); + } + if (pPriv->area) { + xf86FreeOffscreenArea(pPriv->area); + pPriv->area = NULL; + } + pPriv->videoStatus = 0; + pGeode->OverlayON = FALSE; + } else { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + } + } +} + +/*---------------------------------------------------------------------------- + * GX2SetPortAttribute + * + * Description :This function is used to set the attributes of a port like colorkeymode, + * double buffer support and filter. + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * data :Pointer to the video port's private data + * attribute :The port attribute to be set + * value :Value of the attribute to be set. + * + * Returns :Sucess if the attribute is supported, else BadMatch + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static int +GX2SetPortAttribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 value, pointer data) +{ + GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; + + GX2AccelSync(pScrn); + if (attribute == xvColorKey) { + pPriv->colorKey = value; + GX2SetColorkey(pScrn, pPriv); + } +#if DBUF + else if (attribute == xvDoubleBuffer) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->doubleBuffer = value; + } +#endif + else if (attribute == xvColorKeyMode) { + pPriv->colorKeyMode = value; + GX2SetColorkey(pScrn, pPriv); + } else if (attribute == xvFilter) { + pPriv->filter = value; + GFX(set_video_filter(pPriv->filter, pPriv->filter)); + } else + return BadMatch; + + return Success; +} + +/*---------------------------------------------------------------------------- + * GX2GetPortAttribute + * + * Description :This function is used to get the attributes of a port like hue, + * saturation,brightness or contrast. + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * data :Pointer to the video port's private data + * attribute :The port attribute to be read + * value :Pointer to the value of the attribute to be read. + * + * Returns :Sucess if the attribute is supported, else BadMatch + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static int +GX2GetPortAttribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 * value, pointer data) +{ + GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; + + if (attribute == xvColorKey) { + *value = pPriv->colorKey; + } +#if DBUF + else if (attribute == xvDoubleBuffer) { + *value = (pPriv->doubleBuffer) ? 1 : 0; + } +#endif + else if (attribute == xvColorKeyMode) { + *value = pPriv->colorKeyMode; + } else if (attribute == xvFilter) { + *value = pPriv->filter; + } else + return BadMatch; + + return Success; +} + +/*---------------------------------------------------------------------------- + * GX2QueryBestSize + * + * Description :This function provides a way to query what the destination dimensions + * would end up being if they were to request that an area vid_w by vid_h + * from the video stream be scaled to rectangle of drw_w by drw_h on + * the screen. + * + * Parameters. + * ScreenInfoPtr + * pScrn :Screen handler pointer having screen information. + * data :Pointer to the video port's private data + * vid_w,vid_h :Width and height of the video data. + * drw_w,drw_h :Width and height of the scaled rectangle. + * p_w,p_h :Width and height of the destination rectangle. + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ +static void +GX2QueryBestSize(ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, pointer data) +{ + *p_w = drw_w; + *p_h = drw_h; + + if (*p_w > 16384) + *p_w = 16384; +} + +static void +GX2CopyGreyscale(unsigned char *src, + unsigned char *dst, int srcPitch, int dstPitch, int h, int w) +{ + int i; + unsigned char *src2 = src; + unsigned char *dst2 = dst; + unsigned char *dst3; + unsigned char *src3; + + dstPitch <<= 1; + + while (h--) { + dst3 = dst2; + src3 = src2; + for (i = 0; i < w; i++) { + *dst3++ = *src3++; /* Copy Y data */ + *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ + } + src3 = src2; + for (i = 0; i < w; i++) { + *dst3++ = *src3++; /* Copy Y data */ + *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ + } + dst2 += dstPitch; + src2 += srcPitch; + } +} + +/*---------------------------------------------------------------------------- + * GX2CopyData420 + * + * Description : Copies data from src to destination + * + * Parameters. + * src : pointer to the source data + * dst : pointer to destination data + * srcPitch : pitch of the srcdata + * dstPitch : pitch of the destination data + * h & w : height and width of source data + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static void +GX2CopyData420(unsigned char *src, unsigned char *dst, + int srcPitch, int dstPitch, int h, int w) +{ + while (h--) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } +} + +/*---------------------------------------------------------------------------- + * GX2CopyData422 + * + * Description : Copies data from src to destination + * + * Parameters. + * src : pointer to the source data + * dst : pointer to destination data + * srcPitch : pitch of the srcdata + * dstPitch : pitch of the destination data + * h & w : height and width of source data + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static void +GX2CopyData422(unsigned char *src, unsigned char *dst, + int srcPitch, int dstPitch, int h, int w) +{ + w <<= 1; + while (h--) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } +} + +static FBAreaPtr +GX2AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int numlines) +{ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + FBAreaPtr new_area; + + if (area) { + if ((area->box.y2 - area->box.y1) >= numlines) + return area; + + if (xf86ResizeOffscreenArea(area, pScrn->displayWidth, numlines)) + return area; + + xf86FreeOffscreenArea(area); + } + + new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + numlines, 0, NULL, NULL, NULL); + + if (!new_area) { + int max_w, max_h; + + xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0, + FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); + + if ((max_w < pScrn->displayWidth) || (max_h < numlines)) + return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + numlines, 0, NULL, NULL, NULL); + } + + return new_area; +} + +static BoxRec dstBox; +static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0; +static INT32 Bx1, Bx2, By1, By2; +static int top, left, npixels, nlines; +static int offset, s1offset = 0, s2offset = 0, s3offset = 0; +static unsigned char *dst_start; +static int d2offset = 0, d3offset = 0; +static Bool +RegionsIntersect(BoxPtr pRcl1, BoxPtr pRcl2, BoxPtr pRclResult) +{ + pRclResult->x1 = max(pRcl1->x1, pRcl2->x1); + pRclResult->x2 = min(pRcl1->x2, pRcl2->x2); + + if (pRclResult->x1 <= pRclResult->x2) { + pRclResult->y1 = max(pRcl1->y1, pRcl2->y1); + pRclResult->y2 = min(pRcl1->y2, pRcl2->y2); + + if (pRclResult->y1 <= pRclResult->y2) { + return (TRUE); + } + } + + return (FALSE); +} + +void +GX2SetVideoPosition(int x, int y, int width, int height, + short src_w, short src_h, short drw_w, short drw_h, + int id, int offset, ScrnInfoPtr pScrn) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + long xstart, ystart, xend, yend; + unsigned long lines = 0; + unsigned long y_extra, uv_extra = 0; + BoxRec ovly, display, result; + +#if defined(STB_X) + unsigned long startAddress = 0; +#endif + + xend = x + drw_w; + yend = y + drw_h; + + /* Take care of panning when panel is present */ + +#if defined(STB_X) + Gal_get_display_offset(&startAddress); + DeltaY = startAddress / pGeode->Pitch; + DeltaX = startAddress & (pGeode->Pitch - 1); + DeltaX /= (pScrn->bitsPerPixel >> 3); +#endif + + if (pGeode->Panel) { + ovly.x1 = x; + ovly.x2 = x + pGeode->video_dstw; + ovly.y1 = y; + ovly.y2 = y + pGeode->video_dsth; + + display.x1 = DeltaX; + display.x2 = DeltaX + pGeode->FPBX; + display.y1 = DeltaY; + display.y2 = DeltaY + pGeode->FPBY; + x = xend = 0; + if (RegionsIntersect(&display, &ovly, &result)) { + x = ovly.x1 - DeltaX; + xend = ovly.x2 - DeltaX; + y = ovly.y1 - DeltaY; + yend = ovly.y2 - DeltaY; + } + } + + /* LEFT CLIPPING */ + + if (x < 0) { + xstart = 0; + } else { + xstart = (unsigned long)x; + } + drw_w -= (xstart - x); + + /* TOP CLIPPING */ + + if (y < 0) { + lines = (-y) * src_h / drw_h; + ystart = 0; + drw_h += y; + y_extra = lines * dstPitch; + uv_extra = (lines >> 1) * (dstPitch2); + } else { + ystart = y; + lines = 0; + y_extra = 0; + } + GFX(set_video_window(xstart, ystart, xend - xstart, yend - ystart)); + if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) { + GFX(set_video_yuv_offsets(offset + y_extra, + offset + d3offset + uv_extra, + offset + d2offset + uv_extra)); + } else { + GFX(set_video_offset(offset + y_extra)); + } + GFX(set_video_left_crop(xstart - x)); +} + +/*---------------------------------------------------------------------------- + * GX2DisplayVideo + * + * Description : This function sets up the video registers for playing video + * It sets up the video format,width, height & position of the + * video window ,video offsets( y,u,v) and video pitches(y,u,v) + * Parameters. + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static void +GX2DisplayVideo(ScrnInfoPtr pScrn, + int id, + int offset, + short width, short height, + int pitch, + int x1, int y1, int x2, int y2, + BoxPtr dstBox, + short src_w, short src_h, short drw_w, short drw_h) +{ + GeodePtr pGeode = GEODEPTR(pScrn); + + GX2AccelSync(pScrn); + + GFX(set_video_enable(1)); + + switch (id) { + case FOURCC_UYVY: /* UYVY */ + GFX(set_video_format(VIDEO_FORMAT_UYVY)); + GFX(set_video_size(width, height)); + break; + case FOURCC_Y800: /* Y800 - greyscale - we munge it! */ + case FOURCC_YV12: /* YV12 */ + case FOURCC_I420: /* I420 */ + GFX(set_video_format(VIDEO_FORMAT_Y0Y1Y2Y3)); + GFX(set_video_size(width, height)); + GFX(set_video_yuv_pitch(dstPitch, dstPitch2)); + break; + case FOURCC_YUY2: /* YUY2 */ + GFX(set_video_format(VIDEO_FORMAT_YUYV)); + GFX(set_video_size(width, height)); + break; + case FOURCC_Y2YU: /* Y2YU */ + GFX(set_video_format(VIDEO_FORMAT_Y2YU)); + GFX(set_video_size(width, height)); + break; + case FOURCC_YVYU: /* YVYU */ + GFX(set_video_format(VIDEO_FORMAT_YVYU)); + GFX(set_video_size(width, height)); + break; + } + if (pGeode->Panel) { + pGeode->video_x = dstBox->x1; + pGeode->video_y = dstBox->y1; + pGeode->video_w = width; + pGeode->video_h = height; + pGeode->video_srcw = src_w; + pGeode->video_srch = src_h; + pGeode->video_dstw = drw_w; + pGeode->video_dsth = drw_h; + pGeode->video_offset = offset; + pGeode->video_id = id; + pGeode->video_scrnptr = pScrn; + } + GFX(set_video_scale(width, height, drw_w, drw_h)); + GX2SetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, + src_h, drw_w, drw_h, id, offset, pScrn); + +} + +/*---------------------------------------------------------------------------- + * GX2PutImage : This function writes a single frame of video into a drawable. + * The position and size of the source rectangle is specified by src_x,src_y, + * src_w and src_h. This data is stored in a system memory buffer at buf. + * The position and size of the destination rectangle is specified by drw_x, + * drw_y,drw_w,drw_h.The data is in the format indicated by the image descriptor + * and represents a source of size width by height. If sync is TRUE the driver + * should not return from this function until it is through reading the data from + * buf. Returning when sync is TRUE indicates that it is safe for the data at buf + * to be replaced,freed, or modified. + * + * + * Description : + * Parameters. + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static int +GX2PutImage(ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char *buf, + short width, short height, + Bool sync, RegionPtr clipBoxes, pointer data) +{ + GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data; + GeodePtr pGeode = GEODEPTR(pScrn); + int new_h; + +#if REINIT + BOOL ReInitVideo = FALSE; +#endif + +#if XV_PROFILE + long oldtime, newtime; + + UpdateCurrentTime(); + oldtime = currentTime.milliseconds; +#endif + +#if REINIT +/* update cliplist */ + if (!RegionsEqual(&pPriv->clip, clipBoxes)) { + ReInitVideo = TRUE; + } + if (ReInitVideo) { + DEBUGMSG(1, (0, X_NONE, "Regional Not Equal - Init\n")); +#endif + + if (drw_w > 16384) + drw_w = 16384; + + /* Clip */ + Bx1 = src_x; + Bx2 = src_x + src_w; + By1 = src_y; + By2 = src_y + src_h; + + if ((Bx1 >= Bx2) || (By1 >= By2)) + return Success; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + + srcPitch = (width + 3) & ~3; /* of luma */ + dstPitch = (width + 31) & ~31; + + s2offset = srcPitch * height; + d2offset = dstPitch * height; + + srcPitch2 = ((width >> 1) + 3) & ~3; + dstPitch2 = ((width >> 1) + 15) & ~15; + + s3offset = (srcPitch2 * (height >> 1)) + s2offset; + d3offset = (dstPitch2 * (height >> 1)) + d2offset; + + new_h = dstPitch * height; /* Y */ + new_h += (dstPitch2 * height); /* U+V */ + new_h += pGeode->Pitch - 1; + new_h /= pGeode->Pitch; + break; + + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + default: + dstPitch = ((width << 1) + 3) & ~3; + srcPitch = (width << 1); + new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; + break; + } + +#if DBUF + if (pPriv->doubleBuffer) + new_h <<= 1; +#endif + + if (!(pPriv->area = GX2AllocateMemory(pScrn, pPriv->area, new_h))) + return BadAlloc; + + /* copy data */ + top = By1; + left = Bx1 & ~1; + npixels = ((Bx2 + 1) & ~1) - left; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + { + int tmp; + + top &= ~1; + offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch); + +#if DBUF + if (pPriv->doubleBuffer && pPriv->currentBuffer) + offset += (new_h >> 1) * pGeode->Pitch; +#endif + + dst_start = pGeode->FBBase + offset + left; + tmp = ((top >> 1) * srcPitch2) + (left >> 1); + s2offset += tmp; + s3offset += tmp; + if (id == FOURCC_I420) { + tmp = s2offset; + s2offset = s3offset; + s3offset = tmp; + } + nlines = ((By2 + 1) & ~1) - top; + } + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + default: + left <<= 1; + buf += (top * srcPitch) + left; + nlines = By2 - top; + offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch); +#if DBUF + if (pPriv->doubleBuffer && pPriv->currentBuffer) + offset += (new_h >> 1) * pGeode->Pitch; +#endif + + dst_start = pGeode->FBBase + offset + left; + break; + } + s1offset = (top * srcPitch) + left; + +#if REINIT + /* update cliplist */ + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + if (pPriv->colorKeyMode == 0) { + /* draw these */ + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); + } + GX2DisplayVideo(pScrn, id, offset, width, height, dstPitch, + Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, + drw_h); + } +#endif + + switch (id) { + + case FOURCC_Y800: + GX2CopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); + break; + case FOURCC_YV12: + case FOURCC_I420: + GX2CopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines, + npixels); + GX2CopyData420(buf + s2offset, dst_start + d2offset, srcPitch2, + dstPitch2, nlines >> 1, npixels >> 1); + GX2CopyData420(buf + s3offset, dst_start + d3offset, srcPitch2, + dstPitch2, nlines >> 1, npixels >> 1); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + GX2CopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); + break; + } +#if !REINIT + /* update cliplist */ + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + if (pPriv->colorKeyMode == 0) { + /* draw these */ + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); + } + GX2DisplayVideo(pScrn, id, offset, width, height, dstPitch, + Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); +#endif + +#if XV_PROFILE + UpdateCurrentTime(); + newtime = currentTime.milliseconds; + DEBUGMSG(1, (0, X_NONE, "PI %d\n", newtime - oldtime)); +#endif + +#if DBUF + pPriv->currentBuffer ^= 1; +#endif + + pPriv->videoStatus = CLIENT_VIDEO_ON; + pGeode->OverlayON = TRUE; + return Success; +} + +/*---------------------------------------------------------------------------- + * GX2QueryImageAttributes + * + * Description :This function is called to let the driver specify how data + * for a particular image of size width by height should be + * stored. + * + * Parameters. + * pScreenInfo + * Ptr :Screen handler pointer having screen information. + * id :Id for the video format + * width :width of the image (can be modified by the driver) + * height :height of the image (can be modified by the driver) + * Returns : Size of the memory required for storing this image + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ +static int +GX2QueryImageAttributes(ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets) +{ + int size; + int tmp; + + DEBUGMSG(0, (0, X_NONE, "QueryImageAttributes %X\n", id)); + + if (*w > 1024) + *w = 1024; + if (*h > 1024) + *h = 1024; + + *w = (*w + 1) & ~1; + if (offsets) + offsets[0] = 0; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if (pitches) + pitches[0] = size; + size *= *h; + if (offsets) + offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if (pitches) + pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if (offsets) + offsets[2] = size; + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + default: + size = *w << 1; + if (pitches) + pitches[0] = size; + size *= *h; + break; + } + return size; +} + +static void +GX2BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[i]; + ScrnInfoPtr pScrn = xf86Screens[i]; + GeodePtr pGeode = GEODEPTR(pScrn); + GeodePortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + + pScreen->BlockHandler = pGeode->BlockHandler; + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScreen->BlockHandler = GX2BlockHandler; + + GX2AccelSync(pScrn); + if (pPriv->videoStatus & TIMER_MASK) { + UpdateCurrentTime(); + if (pPriv->videoStatus & OFF_TIMER) { + if (pPriv->offTime < currentTime.milliseconds) { + GFX(set_video_enable(0)); + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } + } else { /* FREE_TIMER */ + if (pPriv->freeTime < currentTime.milliseconds) { + if (pPriv->area) { + xf86FreeOffscreenArea(pPriv->area); + pPriv->area = NULL; + } + pPriv->videoStatus = 0; + } + } + } +} + +/****************** Offscreen stuff ***************/ + +typedef struct +{ + FBAreaPtr area; + FBLinearPtr linear; + Bool isOn; +} +OffscreenPrivRec, *OffscreenPrivPtr; + +/*---------------------------------------------------------------------------- + * GX2AllocateSurface + * + * Description :This function allocates an area of w by h in the offscreen + * Parameters. + * ScreenPtr + * pScreen :Screen handler pointer having screen information. + * + * Returns :None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ + +static int +GX2AllocateSurface(ScrnInfoPtr pScrn, + int id, + unsigned short w, unsigned short h, XF86SurfacePtr surface) +{ + FBAreaPtr area; + int pitch, fbpitch, numlines; + OffscreenPrivPtr pPriv; + + if ((w > 1024) || (h > 1024)) + return BadAlloc; + + w = (w + 1) & ~1; + pitch = ((w << 1) + 15) & ~15; + fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; + numlines = ((pitch * h) + fbpitch - 1) / fbpitch; + + if (!(area = GX2AllocateMemory(pScrn, NULL, numlines))) + return BadAlloc; + + surface->width = w; + surface->height = h; + + if (!(surface->pitches = xalloc(sizeof(int)))) + return BadAlloc; + if (!(surface->offsets = xalloc(sizeof(int)))) { + xfree(surface->pitches); + return BadAlloc; + } + if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { + xfree(surface->pitches); + xfree(surface->offsets); + return BadAlloc; + } + + pPriv->area = area; + pPriv->isOn = FALSE; + + surface->pScrn = pScrn; + surface->id = id; + surface->pitches[0] = pitch; + surface->offsets[0] = area->box.y1 * fbpitch; + surface->devPrivate.ptr = (pointer) pPriv; + + return Success; +} + +static int +GX2StopSurface(XF86SurfacePtr surface) +{ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; + + if (pPriv->isOn) { + pPriv->isOn = FALSE; + } + + return Success; +} + +static int +GX2FreeSurface(XF86SurfacePtr surface) +{ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; + + if (pPriv->isOn) + GX2StopSurface(surface); + xf86FreeOffscreenArea(pPriv->area); + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); + + return Success; +} + +static int +GX2GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 * value) +{ + return GX2GetPortAttribute(pScrn, attribute, value, + (pointer) (GET_PORT_PRIVATE(pScrn))); +} + +static int +GX2SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value) +{ + return GX2SetPortAttribute(pScrn, attribute, value, + (pointer) (GET_PORT_PRIVATE(pScrn))); +} + +static int +GX2DisplaySurface(XF86SurfacePtr surface, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, RegionPtr clipBoxes) +{ + OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; + ScrnInfoPtr pScrn = surface->pScrn; + GeodePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn); + INT32 x1, y1, x2, y2; + BoxRec dstBox; + + DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + if ((x1 >= x2) || (y1 >= y2)) + return Success; + + dstBox.x1 -= pScrn->frameX0; + dstBox.x2 -= pScrn->frameX0; + dstBox.y1 -= pScrn->frameY0; + dstBox.y2 -= pScrn->frameY0; + + xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); + + GX2DisplayVideo(pScrn, surface->id, surface->offsets[0], + surface->width, surface->height, surface->pitches[0], + x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); + + pPriv->isOn = TRUE; + if (portPriv->videoStatus & CLIENT_VIDEO_ON) { + REGION_EMPTY(pScrn->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } + + return Success; +} + +/*---------------------------------------------------------------------------- + * GX2InitOffscreenImages + * + * Description :This function sets up the offscreen memory management.It fills + * in the XF86OffscreenImagePtr structure with functions to handle + * offscreen memory operations. + * + * Parameters. + * ScreenPtr + * pScreen :Screen handler pointer having screen information. + * + * Returns : None + * + * Comments :None + * +*---------------------------------------------------------------------------- +*/ +static void +GX2InitOffscreenImages(ScreenPtr pScreen) +{ + XF86OffscreenImagePtr offscreenImages; + + /* need to free this someplace */ + if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) + return; + + offscreenImages[0].image = &Images[0]; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].alloc_surface = GX2AllocateSurface; + offscreenImages[0].free_surface = GX2FreeSurface; + offscreenImages[0].display = GX2DisplaySurface; + offscreenImages[0].stop = GX2StopSurface; + offscreenImages[0].setAttribute = GX2SetSurfaceAttribute; + offscreenImages[0].getAttribute = GX2GetSurfaceAttribute; + offscreenImages[0].max_width = 1024; + offscreenImages[0].max_height = 1024; + offscreenImages[0].num_attributes = NUM_ATTRIBUTES; + offscreenImages[0].attributes = Attributes; + + xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); +} + +#endif /* !XvExtension */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S new file mode 100644 index 000000000..c0c4a3cc9 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S @@ -0,0 +1,229 @@ +/* +# $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S,v 1.1 2002/12/12 22:13:34 dawes Exp $ +########################################################################## +# NSC_LIC_ALTERNATIVE_PREAMBLE +# +# Revision 1.0 +# +# National Semiconductor Alternative GPL-BSD License +# +# National Semiconductor Corporation licenses this software +# ("Software"): +# +# Geode Xfree frame buffer driver +# +# under one of the two following licenses, depending on how the +# Software is received by the Licensee. +# +# If this Software is received as part of the Linux Framebuffer or +# other GPL licensed software, then the GPL license designated +# NSC_LIC_GPL applies to this Software; in all other circumstances +# then the BSD-style license designated NSC_LIC_BSD shall apply. +# +# END_NSC_LIC_ALTERNATIVE_PREAMBLE +########################################################################## +# NSC_LIC_BSD +# +# National Semiconductor Corporation Open Source License for +# +# Geode Xfree frame buffer driver +# +# (BSD License with Export Notice) +# +# Copyright (c) 1999-2001 +# National Semiconductor Corporation. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of the National Semiconductor Corporation nor +# the names of its contributors may be used to endorse or promote +# products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, +# INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. +# +# EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF +# YOUR JURISDICTION. It is licensee's responsibility to comply with +# any export regulations applicable in licensee's jurisdiction. Under +# CURRENT (2001) U.S. export regulations this software +# is eligible for export from the U.S. and can be downloaded by or +# otherwise exported or reexported worldwide EXCEPT to U.S. embargoed +# destinations which include Cuba, Iraq, Libya, North Korea, Iran, +# Syria, Sudan, Afghanistan and any other country to which the U.S. +# has embargoed goods and services. +# +# END_NSC_LIC_BSD +########################################################################## +# NSC_LIC_GPL +# +# National Semiconductor Corporation Gnu General Public License for +# +# Geode Xfree frame buffer driver +# +# (GPL License with Export Notice) +# +# Copyright (c) 1999-2001 +# National Semiconductor Corporation. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted under the terms of the GNU General +# Public License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version +# +# In addition to the terms of the GNU General Public License, neither +# the name of the National Semiconductor Corporation nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, +# INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. See the GNU General Public License for more details. +# +# EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF +# YOUR JURISDICTION. It is licensee's responsibility to comply with +# any export regulations applicable in licensee's jurisdiction. Under +# CURRENT (2001) U.S. export regulations this software +# is eligible for export from the U.S. and can be downloaded by or +# otherwise exported or reexported worldwide EXCEPT to U.S. embargoed +# destinations which include Cuba, Iraq, Libya, North Korea, Iran, +# Syria, Sudan, Afghanistan and any other country to which the U.S. +# has embargoed goods and services. +# +# You should have received a copy of the GNU General Public License +# along with this file; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# END_NSC_LIC_GPL +*/ + +#include "assyntax.h" + + FILE("nsc_msr_asm.s") + + AS_BEGIN + + SEG_TEXT + + ALIGNTEXT4 + + GLOBL GLNAME(nsc_asm_msr_vsa_rd) + +GLNAME(nsc_asm_msr_vsa_rd): + + PUSH_L (EBP) + MOV_L (ESP,EBP) + + PUSH_L (EAX) + PUSH_L (EBX) + PUSH_L (ECX) + PUSH_L (EDX) + + MOV_L (REGOFF(8,EBP),ECX) + + /* unlock */ + MOV_W (CONST(0x0ac1c),DX) + MOV_W (CONST(0x0fc53),AX) + OUT_W + + MOV_W (CONST(0x0ac1c),DX) + MOV_W (CONST(0x0007),AX) + OUT_W + + MOV_W (CONST(0x0ac1e),DX) + IN_W + + MOV_L (REGOFF(12,EBP),EBX) + MOV_L (EDX,REGIND(EBX)) + MOV_L (REGOFF(16,EBP),EBX) + MOV_L (EAX,REGIND(EBX)) + + POP_L (EDX) + POP_L (ECX) + POP_L (EBX) + POP_L (EAX) + + LEAVE + RET + +/*###################################*/ + + + ALIGNTEXT4 + + GLOBL GLNAME(nsc_asm_msr_vsa_wr) + +GLNAME(nsc_asm_msr_vsa_wr): + + PUSH_L (EBP) + MOV_L (ESP,EBP) + + PUSH_L (EAX) + PUSH_L (EBX) + PUSH_L (ECX) + PUSH_L (EDX) + PUSH_L (EDI) + PUSH_L (ESI) + + MOV_L (REGOFF(8,EBP),ECX) + + /* unlock */ + MOV_W (CONST(0x0ac1c),DX) + MOV_L (CONST(0x0fc530007),EAX) + OUT_L + + MOV_L (REGOFF(12,EBP),EBX) + MOV_L (REGOFF(16,EBP),EAX) + + XOR_L (ESI,ESI) + XOR_L (EDI,EDI) + + MOV_W (CONST(0x0ac1e),DX) + + OUT_W + + POP_L (ESI) + POP_L (EDI) + POP_L (EDX) + POP_L (ECX) + POP_L (EBX) + POP_L (EAX) + + LEAVE + RET + +/*###################################*/ + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_regacc.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_regacc.c new file mode 100644 index 000000000..e0152709c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_regacc.c @@ -0,0 +1,421 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_regacc.c,v 1.2 2003/01/14 09:34:32 alanh Exp $ */ +/* + * $Workfile: nsc_regacc.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * This is the main file used to add Durango graphics support to a software + * project. The main reason to have a single file include the other files + * is that it centralizes the location of the compiler options. This file + * should be tuned for a specific implementation, and then modified as needed + * for new Durango releases. The releases.txt file indicates any updates to + * this main file, such as a new definition for a new hardware platform. + * + * In other words, this file should be copied from the Durango source files + * once when a software project starts, and then maintained as necessary. + * It should not be recopied with new versions of Durango unless the + * developer is willing to tune the file again for the specific project. + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Durango + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +void gfx_write_reg8(unsigned long offset, unsigned char value); +void gfx_write_reg16(unsigned long offset, unsigned short value); +void gfx_write_reg32(unsigned long offset, unsigned long value); +unsigned short gfx_read_reg16(unsigned long offset); +unsigned long gfx_read_reg32(unsigned long offset); +void gfx_write_vid32(unsigned long offset, unsigned long value); +unsigned long gfx_read_vid32(unsigned long offset); +unsigned long gfx_read_vip32(unsigned long offset); +void gfx_write_vip32(unsigned long offset, unsigned long value); +void gfx_mono_bitmap_to_screen_blt_swp(unsigned short srcx, + unsigned short srcy, + unsigned short dstx, + unsigned short dsty, + unsigned short width, + unsigned short height, + unsigned char *data, short pitch); +unsigned int GetVideoMemSize(void); + +/* ROUTINES added accessing hardware reg */ +void +gfx_write_reg8(unsigned long offset, unsigned char value) +{ + WRITE_REG8(offset, value); +} + +void +gfx_write_reg16(unsigned long offset, unsigned short value) +{ + WRITE_REG16(offset, value); +} + +void +gfx_write_reg32(unsigned long offset, unsigned long value) +{ + WRITE_REG32(offset, value); +} +unsigned short +gfx_read_reg16(unsigned long offset) +{ + unsigned short value; + + value = READ_REG16(offset); + return value; +} +unsigned long +gfx_read_reg32(unsigned long offset) +{ + unsigned long value; + + value = READ_REG32(offset); + return value; +} + +void +gfx_write_vid32(unsigned long offset, unsigned long value) +{ + WRITE_VID32(offset, value); +} +unsigned long +gfx_read_vid32(unsigned long offset) +{ + unsigned long value; + + value = READ_VID32(offset); + return value; +} + +/*Addition for the VIP code */ +unsigned long +gfx_read_vip32(unsigned long offset) +{ + unsigned long value; + + value = READ_VIP32(offset); + return value; +} + +void +gfx_write_vip32(unsigned long offset, unsigned long value) +{ + WRITE_VIP32(offset, value); +} + +#define SWAP_BITS_IN_BYTES(v) \ + (((0x01010101 & (v)) << 7) | ((0x02020202 & (v)) << 5) | \ + ((0x04040404 & (v)) << 3) | ((0x08080808 & (v)) << 1) | \ + ((0x10101010 & (v)) >> 1) | ((0x20202020 & (v)) >> 3) | \ + ((0x40404040 & (v)) >> 5) | ((0x80808080 & (v)) >> 7)) + +#define WRITE_GPREG_STRING32_SWP(regoffset, dwords, counter, array, array_offset, temp) \ +{ \ + temp = (unsigned long)array + (array_offset); \ + for (counter = 0; counter < dwords; counter++) \ + WRITE_GP32 (regoffset, SWAP_BITS_IN_BYTES(*((unsigned long *)temp + counter))); \ +} + +void +gfx_mono_bitmap_to_screen_blt_swp(unsigned short srcx, unsigned short srcy, + unsigned short dstx, unsigned short dsty, + unsigned short width, unsigned short height, + unsigned char *data, short pitch) +{ + unsigned long dstoffset, size, bytes; + unsigned long offset, temp_offset, temp1 = 0, temp2 = 0; + unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; + unsigned long shift = 0; + + size = (((unsigned long)width) << 16) | height; + + /* CALCULATE STARTING OFFSETS */ + + offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3); + + dstoffset = (unsigned long)dsty *gu2_pitch + + (((unsigned long)dstx) << gu2_xshift); + + /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ + + if (GFXpatternFlags) { + /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ + + dstoffset |= ((unsigned long)(dstx & 7)) << 26; + dstoffset |= ((unsigned long)(dsty & 7)) << 29; + } + + bytes = ((srcx & 7) + width + 7) >> 3; + fifo_lines = bytes >> 5; + dwords_extra = (bytes & 0x0000001Cl) >> 2; + bytes_extra = bytes & 0x00000003l; + + /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ + /* Put off poll for as long as possible (do most calculations first). */ + /* The source offset is always 0 since we allow misaligned dword reads. */ + /* Need to wait for busy instead of pending, since hardware clears */ + /* the host data FIFO at the beginning of a BLT. */ + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); + WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26); + WRITE_GP32(MGP_DST_OFFSET, dstoffset); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_STRIDE, gu2_pitch); + WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST | MGP_BM_SRC_MONO); + + /* WAIT FOR BLT TO BE LATCHED */ + + GU2_WAIT_PENDING; + + /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */ + + while (height--) { + temp_offset = offset; + + /* WRITE ALL FULL FIFO LINES */ + + for (i = 0; i < fifo_lines; i++) { + GU2_WAIT_HALF_EMPTY; + WRITE_GPREG_STRING32_SWP(MGP_HST_SOURCE, 8, j, data, temp_offset, + temp1); + temp_offset += 32; + } + + /* WRITE ALL FULL DWORDS */ + + GU2_WAIT_HALF_EMPTY; + if (dwords_extra) { + WRITE_GPREG_STRING32_SWP(MGP_HST_SOURCE, dwords_extra, i, data, + temp_offset, temp1); + temp_offset += (dwords_extra << 2); + } + + /* WRITE REMAINING BYTES */ + + shift = 0; + if (bytes_extra) + WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, + temp_offset, temp1, temp2); + + offset += pitch; + } +} +unsigned int +GetVideoMemSize(void) +{ + unsigned int graphicsMemBaseAddr; + unsigned int totalMem = 0; + int i; + unsigned int graphicsMemMask, graphicsMemShift; + + /* Read graphics base address. */ + + graphicsMemBaseAddr = gfx_read_reg32(0x8414); + + if (1) { + unsigned int mcBankCfg = gfx_read_reg32(0x8408); + unsigned int dimmShift = 4; + + graphicsMemMask = 0x7FF; + graphicsMemShift = 19; + + /* Calculate total memory size for GXm. */ + + for (i = 0; i < 2; i++) { + if (((mcBankCfg >> dimmShift) & 0x7) != 0x7) { + switch ((mcBankCfg >> (dimmShift + 4)) & 0x7) { + case 0: + totalMem += 0x400000; + break; + case 1: + totalMem += 0x800000; + break; + case 2: + totalMem += 0x1000000; + break; + case 3: + totalMem += 0x2000000; + break; + case 4: + totalMem += 0x4000000; + break; + case 5: + totalMem += 0x8000000; + break; + case 6: + totalMem += 0x10000000; + break; + case 7: + totalMem += 0x20000000; + break; + default: + break; + } + } + dimmShift += 16; + } + } else { + unsigned int mcMemCntrl1 = gfx_read_reg32(0x8400); + unsigned int bankSizeShift = 12; + + graphicsMemMask = 0x3FF; + graphicsMemShift = 17; + + /* Calculate total memory size for GX. */ + + for (i = 0; i < 4; i++) { + switch ((mcMemCntrl1 >> bankSizeShift) & 0x7) { + case 1: + totalMem += 0x200000; + break; + case 2: + totalMem += 0x400000; + break; + case 3: + totalMem += 0x800000; + break; + case 4: + totalMem += 0x1000000; + break; + case 5: + totalMem += 0x2000000; + break; + default: + break; + } + bankSizeShift += 3; + } + } + + /* Calculate graphics memory base address */ + + graphicsMemBaseAddr &= graphicsMemMask; + graphicsMemBaseAddr <<= graphicsMemShift; + + return (totalMem - graphicsMemBaseAddr); +} + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel.c new file mode 100644 index 000000000..38f7b734a --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel.c @@ -0,0 +1,175 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel.c,v 1.3 2003/01/14 09:34:32 alanh Exp $ */ +/* + * $Workfile: panel.c $ + * $Revision: 1.2 $ + * $Author: alanh $ + * + * File Contents: This file contailns the panel include files and + * external pointer to the hardware. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#if defined(linux) /* Linux */ + +#ifdef __KERNEL__ + +#include <linux/string.h> +#include <asm/io.h> + +#elif !defined(XFree86Server) + +#include <linux/fs.h> +#include <asm/mman.h> + +#endif /* __KERNEL__ */ +#elif defined(_WIN32) /* windows */ + +#include <windows.h> + +#endif + +#include "panel.h" +#include "gfx_defs.h" +#include "nsc.h" + +#define PLATFORM_DYNAMIC 1 /* runtime selection */ +#define PLATFORM_DRACO 0 /* Draco + 9210 */ +#define PLATFORM_CENTAURUS 1 /* Centaurus + 9211 RevA */ +#define PLATFORM_DORADO 1 /* Dorado + 9211 RevC */ +#define PLATFORM_GX2BASED 1 /* Redcloud */ + +unsigned char *XpressROMPtr; + +#include "pnl_init.c" +#include "pnl_bios.c" diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/92xx.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/92xx.h new file mode 100644 index 000000000..cf51db8e1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/92xx.h @@ -0,0 +1,466 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/92xx.h,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/* + * $Workfile: 92xx.h $ + * $Revision: 1.2 $ + * + * File Contents: This header file defines the Durango routines and + * variables used to access the memory mapped regions. + * + * SubModule: Geode FlatPanel library + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef _92XX_h +#define _92XX_h + +typedef unsigned long ULONG; +typedef unsigned char UCHAR; + +#define FALSE 0 +#define TRUE 1 +#define NUM_92XX_MODES 13 +#define ONE_BYTE 1 +#define TWO_BYTES 2 +#define FOUR_BYTES 4 + +/* LCD Registers + * The LCD memory area is shared by both TV and LCD. + * This offset is for LCD access. + */ + +#define CS92xx_LCD_OFFSET 0x00000400 + +/* LCD CONTROL REGISTERS */ + +#define CS92xx_LCD_PAN_TIMING1 CS92xx_LCD_OFFSET + 0x00 + +/* flat panel(FP) timings */ +#define CS92xx_LCD_PAN_TIMING2 CS92xx_LCD_OFFSET + 0x04 + +/* FP panel timings */ +#define CS92xx_LCD_PWR_MAN CS92xx_LCD_OFFSET + 0x08 + +/* FP power management */ +#define CS92xx_LCD_DITH_FR_CNTRL CS92xx_LCD_OFFSET + 0x0C + +/* FP dither and frame rate + * these defines are in revisions prior to C + */ +#define CS92xx_LCD_BLOCK_SEL1 CS92xx_LCD_OFFSET + 0x10 + +/* FRM register */ +#define CS92xx_LCD_BLOCK_SEL2 CS92xx_LCD_OFFSET + 0x14 + +/* FRM register */ +#define CS92xx_LCD_DISPER1 CS92xx_LCD_OFFSET + 0x18 + +/* FRM register */ +#define CS92xx_LCD_DISPER2 CS92xx_LCD_OFFSET + 0x1C + +/* FRM register + * these defines are revision C + */ +#define CS92xx_BLUE_LSFR_SEED CS92xx_LCD_OFFSET + 0x10 + +/* FRM register */ +#define CS92xx_RED_GREEN_LSFR_SEED CS92xx_LCD_OFFSET + 0x14 + +/* FRM register */ +#define CS92xx_FRM_MEMORY_INDEX CS92xx_LCD_OFFSET + 0x18 + +/* FRM register */ +#define CS92xx_FRM_MEMORY_DATA CS92xx_LCD_OFFSET + 0x1C + +/* FRM register */ +#define CS92xx_LCD_MEM_CNTRL CS92xx_LCD_OFFSET + 0x20 + +/* memory PLL register */ +#define CS92xx_LCD_RAM_CNTRL CS92xx_LCD_OFFSET + 0x24 + +/* ram control */ + +#define CS92xx_LCD_RAM_DATA CS92xx_LCD_OFFSET + 0x28 /* ram data */ + +#define CS92xx_LCD_PAN_CRC_SIG CS92xx_LCD_OFFSET + 0x2C + +/* FP CRC signature */ +#define CS92xx_DEV_REV_ID CS92xx_LCD_OFFSET + 0x30 + +/* Device and revision id */ +#define CS92xx_LCD_GPIO_DATA CS92xx_LCD_OFFSET + 0x34 /* GPIO Data */ + +#define CS92xx_LCD_GPIO_CNTRL CS92xx_LCD_OFFSET + 0x38 + +/* GPIO Control */ +int Pnl_Rev_ID; + +typedef struct +{ + /* DISPLAY MODE PARAMETERS */ + int xres; + int yres; + int bpp; + int panel_type; + int color_type; + /* VALUES USED TO SET THE FLAT PANEL DISPLAY CONTROLLER */ + unsigned long panel_timing1; + unsigned long panel_timing2; + unsigned long power_management; + /* the following 5 registers are prior to revision C */ + unsigned long pre_C_dither_frc; + unsigned long block_select1; + unsigned long block_select2; + unsigned long dispersion1; + unsigned long dispersion2; + /* the following 4 registers are revision C only */ + unsigned long rev_C_dither_frc; + unsigned long blue_lsfr_seed; + unsigned long red_green_lsfr_seed; + unsigned long frm_memory_index; + unsigned long frm_memory_data; + unsigned long memory_control; + +} +CS92xx_MODE; + +/* VALUES USED TO SAVE AND RESTORE 9211 REGISTERS. */ +typedef struct +{ + unsigned long panel_state; + /* VALUES USED TO SET THE FLAT PANEL DISPLAY CONTROLLER */ + unsigned long panel_timing1; + unsigned long panel_timing2; + unsigned long power_management; + unsigned long dither_frc_ctrl; + unsigned long blue_lsfr_seed; + unsigned long red_green_lsfr_seed; + unsigned long frm_memory_index; + unsigned long frm_memory_data; + unsigned long memory_control; +} +CS92xx_REGS; + +CS92xx_REGS cs9211_regs; + +/* + *------------------------------------------------------------------------ + * PANEL MODE TABLES: + * GLOBAL ARRAY OF FLAT PANEL MODE STRUCTURES + *------------------------------------------------------------------------ + */ +CS92xx_MODE FPModeParams[] = { + + {640, 480, 8, PNL_SSTN, PNL_COLOR_PANEL, /* display parameters */ + 0x01e00000, 0x00034000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x25cf3096, 0xad47b81e, /* block select 1, block select 2 */ + 0x21446450, 0x21446450, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000000, /* memory control */ + }, + + {640, 480, 12, PNL_TFT, PNL_COLOR_PANEL, /* display parameters */ + 0x01e00000, 0x0f100000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* block select 1, block select 2 */ + 0x00000000, 0x00000000, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000000, /* memory control */ + }, + + {640, 480, 18, PNL_TFT, PNL_COLOR_PANEL, /* display parameters */ + 0x01e00000, 0x0f100000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* block select 1, block select 2 */ + 0x00000000, 0x00000000, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000000, /* memory control */ + }, + + {640, 480, 16, PNL_DSTN, PNL_COLOR_PANEL, /* display parameters */ + 0x01e00000, 0x00014000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x048c26ae, 0x048c26ae, /* block select 1, block select 2 */ + 0x02468ace, 0x13579bdf, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x0000004b, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000007, /* memory control */ + }, + + {640, 480, 8, PNL_DSTN, PNL_MONO_PANEL, /* display parameters */ + 0x01e00000, 0x00084000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x0000004b, /* dither and frame rate control */ + 0x25cf3096, 0xad47b81e, /* block select 1, block select 2 */ + 0x21446450, 0x21446450, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000007, /* memory control */ + }, + + {640, 480, 16, PNL_DSTN, PNL_MONO_PANEL, /* display parameters */ + 0x01e00000, 0x00094000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x25cf3096, 0xad47b81e, /* block select 1, block select 2 */ + 0x81a5d470, 0x29cfb63e, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000007, /* memory control */ + }, + + {800, 600, 12, PNL_TFT, PNL_COLOR_PANEL, /* display parameters */ + 0x02580000, 0x0f100000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* block select 1, block select 2 */ + 0x00000000, 0x00000000, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000000, /* memory control */ + }, + + {800, 600, 18, PNL_TFT, PNL_COLOR_PANEL, /* display parameters */ + 0x02580000, 0x0f100000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* block select 1, block select 2 */ + 0x00000000, 0x00000000, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000000, /* memory control */ + }, + + {800, 600, 16, PNL_DSTN, PNL_COLOR_PANEL, /* display parameters */ + 0x02580000, 0x00014000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x048c26ae, 0x048c26ae, /* block select 1, block select 2 */ + 0x02468ace, 0x13579bdf, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x0000004b, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000007, /* memory control */ + }, + + {800, 600, 8, PNL_DSTN, PNL_MONO_PANEL, /* display parameters */ + 0x02580000, 0x00084000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x25cf3096, 0xad47b81e, /* block select 1, block select 2 */ + 0x21446450, 0x21446450, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x0000004b, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000007, /* memory control */ + }, + + {800, 600, 16, PNL_DSTN, PNL_MONO_PANEL, /* display parameters */ + 0x02580000, 0x00094000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /* The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x25cf3096, 0xad47b81e, /* block select 1, block select 2 */ + 0x81a5d470, 0x29cfb63e, /* dispersion 1, dispersion 2 */ + /* The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000007, /* memory control */ + }, + + {1024, 768, 18, PNL_TFT, PNL_COLOR_PANEL, /* display parameters */ + 0x03000000, 0x0f100000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /*The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* block select 1, block select 2 */ + 0x00000000, 0x00000000, /* dispersion 1, dispersion 2 */ + /*The next 5 values are for revision C */ + 0x00000050, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000000, /* memory control */ + }, + + {1024, 768, 24, PNL_DSTN, PNL_COLOR_PANEL, /* display parameters */ + 0x03000000, 0x80024000, /* panel timing reg 1, panel timing reg 2 */ + 0x01000000, /* power management */ + /*The next 5 values are prior to revision C */ + 0x00000050, /* dither and frame rate control */ + 0x048c26ae, 0x048c26ae, /* block select 1, block select 2 */ + 0x02468ace, 0x13579bdf, /* dispersion 1, dispersion 2 */ + /*The next 5 values are for revision C */ + 0x0000004b, /* dither and frame rate control */ + 0x00000000, 0x00000000, /* blue LSFR, red and green LSFR */ + 0x00000000, 0x00000000, /* FRM memory index, FRM memory data */ + 0x00000005, /* memory control */ + } +}; + +#endif /* !_92XX_h */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.c new file mode 100644 index 000000000..85aecdfe3 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.c @@ -0,0 +1,971 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.c,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/* + * $Workfile: cen9211.c $ + * + * File Contents: This file contains panel functions to interface with + * the centaraus platform. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Geode graphics driver for panel support + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "cen9211.h" + +static unsigned char sioc2_orig_val; +static unsigned char must_restore_97317 = FALSE; + +/******************************************************************** + * + * PASS_FAIL init_GPIO(void); + * Initializes the GPIO pins in the Cx5530 or the National PC97317 + * for use with a 9211 on a Marmot or Centaurus board. Uses + * the global variables RdPCIVal and sioc2_orig_val. + * + *********************************************************************/ + +unsigned char +init_Centaurus_GPIO(void) +{ + unsigned char reg_val; + static unsigned char first_time = TRUE; + + /* The Centaurus board uses ports 1 and 2 of the 97317 for GPIO. + * These ports require bank 0 to be active. The first thing we will + * do is verify that bank 0 is active and set it if it is not. + */ + + /* set the index for access to the configuration register */ + gfx_outb(CENT_CONFIG_INDEX, CENT_SIOC2); + reg_val = gfx_inb(CENT_CONFIG_DATA); + + /* set to bank 0 */ + if (reg_val & CENT_GPIO_BANK_SELECT) { + gfx_outb(CENT_CONFIG_DATA, + (unsigned char)(reg_val & ~CENT_GPIO_BANK_SELECT)); + } + + /* If this is the first time we have modified sioc2, we must + * save the current value (set by the BIOS) for restoration by + * the calling program, set the global flag must_restore_97317, and set + * first_time to FALSE. + */ + + if (first_time == TRUE) { + sioc2_orig_val = reg_val; + must_restore_97317 = TRUE; + first_time = FALSE; + } + + /* set port 1 direction */ + reg_val = gfx_inb(CENT_PORT1_DIRECTION); + + /* make GPIO 14 and 17 outputs */ + reg_val |= CENT_97317_CLOCK_MASK | CENT_97317_DATA_OUT_MASK; + gfx_outb(CENT_PORT1_DIRECTION, reg_val); + + /* set port 2 direction */ + reg_val = gfx_inb(CENT_PORT2_DIRECTION); + + /* make GPIO 20 an output */ + + reg_val |= CENT_97317_CHIP_SEL_MASK; + + /* make GPIO 21 an input */ + + reg_val &= ~CENT_97317_DATA_IN_MASK; + gfx_outb(CENT_PORT2_DIRECTION, reg_val); + + /* make GPIO 14 and 17 push-pull */ + + reg_val = gfx_inb(CENT_PORT1_OUTPUT_TYPE); + reg_val |= CENT_97317_CLOCK_MASK | CENT_97317_DATA_OUT_MASK; + gfx_outb(CENT_PORT1_OUTPUT_TYPE, reg_val); + + /* make GPIO 20 and 21 push-pull */ + reg_val = gfx_inb(CENT_PORT2_OUTPUT_TYPE); + reg_val |= CENT_97317_CHIP_SEL_MASK | CENT_97317_DATA_IN_MASK; + gfx_outb(CENT_PORT2_OUTPUT_TYPE, reg_val); + return CENT_PASS; + +} /* end init_GPIO() */ + +/********************************************************************* + * + * PASS_FAIL init_9211(void); + * Initializes (sets to 0) the clock, chip select, and data pins + * of the Cx9211 on a Marmot or Centaurus board. + * + **********************************************************************/ + +unsigned char +init_Centaurus_9211(void) +{ + unsigned char ReadData; + + /* Uses the 97317 for GPIO. + * we will use the clock port define for port 1 + */ + ReadData = gfx_inb(CENT_97317_CLOCK_PORT); + ReadData &= ~CENT_97317_CLOCK_MASK & ~CENT_97317_DATA_OUT_MASK; + gfx_outb(CENT_97317_CLOCK_PORT, ReadData); + /* we will use the chip select port define for port 2 */ + ReadData = gfx_inb(CENT_97317_CHIP_SELECT); + ReadData &= ~CENT_97317_CHIP_SEL_MASK & ~CENT_97317_DATA_IN_MASK; + gfx_outb(CENT_97317_CHIP_SELECT, ReadData); + return (CENT_PASS); + +} /*end init_9211() */ + +/****************************************************************** + * + * PASS_FAIL restore_97317_SIOC2(void); + * Restores the original value to the 97317 SIOC2 register using + * the global variable sioc2_orig_val. Returns PASS if the value + * was written, FAIL if not. + * + *******************************************************************/ + +unsigned char +restore_Centaurus_97317_SIOC2(void) +{ + /* set the global flag */ + if (must_restore_97317 == TRUE) { + unsigned char cfg; + + /* set the index for access to the configuration register */ + gfx_outb(CENT_CONFIG_INDEX, CENT_SIOC2); + + /* restore the value */ + gfx_outb(CENT_CONFIG_DATA, sioc2_orig_val); + + /* now read and verify */ + cfg = gfx_inb(CENT_CONFIG_DATA); + if (cfg == sioc2_orig_val) + return (CENT_PASS); + else + return (CENT_FAIL); + + } /* end if() */ + return (CENT_FAIL); + +} /* end restore_97317_SIOC2bank() */ + +/* ----------------------------------------------------------------------- + * + * SET_FLAT_PANEL_MODE + * + * This routine sets the specified flat panel moden parameters in + * the 9211. + * Returns PASS if successful, FAIL if the mode parameters could + * not be set. + * + *------------------------------------------------------------------------*/ + +unsigned char +set_Centaurus_92xx_mode(Pnl_PanelStat * pstat) +{ + int mode; + + /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ + + for (mode = 0; mode < NUM_92XX_MODES; mode++) { + if ((FPModeParams[mode].xres == pstat->XRes) && + (FPModeParams[mode].yres == pstat->YRes) && + (FPModeParams[mode].bpp == pstat->Depth) && + (FPModeParams[mode].panel_type == pstat->Type) && + (FPModeParams[mode].color_type == pstat->MonoColor)) { + + /* SET THE 92xx FOR THE SELECTED MODE */ + set_Centaurus_92xx_mode_params(mode); + return (CENT_PASS); + } /* end if() */ + } /* end for() */ + return (CENT_FAIL); + +} /* end set_Centaurus_92xx_mode() */ + +/*------------------------------------------------------------------- + * + * SET_92XX_MODE_PARAMS + * This routine sets the 9211 mode parameters. + * + *-------------------------------------------------------------------*/ + +void +set_Centaurus_92xx_mode_params(int mode) +{ + CS92xx_MODE *pMode = &FPModeParams[mode]; + unsigned long off_data = 0; + + /* Turn the 92xx power off before setting any new parameters. + * Since we are going to reset all the power bit positions, we will + * force the power register to 0. + */ + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, off_data); + + /* set 9211 registers using the desired panel settings */ + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_PAN_TIMING1, pMode->panel_timing1); + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_PAN_TIMING2, pMode->panel_timing2); + + if (Pnl_Rev_ID == PNL_9211_C) { + + /* load the LSFR seeds */ + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_DITH_FR_CNTRL, pMode->rev_C_dither_frc); + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_BLUE_LSFR_SEED, pMode->blue_lsfr_seed); + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_RED_GREEN_LSFR_SEED, + pMode->red_green_lsfr_seed); + } else { + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_DITH_FR_CNTRL, pMode->pre_C_dither_frc); + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_BLOCK_SEL1, pMode->block_select1); + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_BLOCK_SEL2, pMode->block_select2); + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_DISPER1, pMode->dispersion1); + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_DISPER2, pMode->dispersion2); + + CentaurusProgramFRMload(); + } + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_MEM_CNTRL, + pMode->memory_control); + + /* Set the power register last. This will turn the panel on at the 9211. */ + + Centaurus_write_gpio(FOUR_BYTES, + CS92xx_LCD_PWR_MAN, pMode->power_management); + +} /* end set_Centaurus_92xx_mode_params() */ + +void +Centaurus_write_gpio(int width, ULONG address, unsigned long data) +{ + int num_clock_toggles; + int count; + unsigned long Addr = address; + + enable_Centaurus_9211_chip_select(); + + /* Write 1 Clock period of no valid transfer */ + write_Centaurus_CX9211_GPIO(CENT_NO_DATA); + + /* Write 1 control bit (the data book calls this the control bar write) */ + write_Centaurus_CX9211_GPIO(0x1); + + /* Write the 12-bit address */ + for (count = 0; count < 12; count++) { + write_Centaurus_CX9211_GPIO((unsigned char)(Addr & 0x01)); + /*the 9211 expects data LSB->MSB */ + Addr = Addr >> 1; + } + + /* write */ + write_Centaurus_CX9211_DWdata(data); + + /* a write will require four toggles after disabling CS */ + num_clock_toggles = CENT_NUM_WRITE_CLOCK_TOGGLES; + disable_Centaurus_9211_chip_select(); + + /* now toggle the clock */ + for (count = 0; count < num_clock_toggles; count++) { + toggle_Centaurus_9211_clock(); + } + return; + +} /* end Centaurus_write_gpio() */ + +unsigned long +Centaurus_read_gpio(int width, unsigned long address) +{ + int num_clock_toggles; + int count; + unsigned long Addr = address; + unsigned long data; + + enable_Centaurus_9211_chip_select(); + + /* Write 1 Clock period of no valid transfer */ + write_Centaurus_CX9211_GPIO(CENT_NO_DATA); + + /* Write 1 control bit (the data book calls this the control bar write) */ + write_Centaurus_CX9211_GPIO(0x1); + + /* Write the 12-bit address */ + for (count = 0; count < 12; count++) { + write_Centaurus_CX9211_GPIO((unsigned char)(Addr & 0x01)); + + /*the 9211 expects data LSB->MSB */ + Addr = Addr >> 1; + } + + data = read_Centaurus_CX9211_DWdata(); + + /* a read will require one toggle after disabling CS */ + num_clock_toggles = CENT_NUM_READ_CLOCK_TOGGLES; + disable_Centaurus_9211_chip_select(); + + /* now toggle the clock */ + for (count = 0; count < num_clock_toggles; count++) { + toggle_Centaurus_9211_clock(); + } + return data; + +} /* end Centaurus_read_gpio() */ + +/******************************************************************* + * + * void enable_Centaurus_9211_chip_select(void); + * Enables the chip select of the CX9211 using the National 97317 + * on a Centaurus board. + * + *******************************************************************/ + +void +enable_Centaurus_9211_chip_select(void) +{ + unsigned char cs_port_val; + + /* Set the chip select (GPIO20) high */ + cs_port_val = gfx_inb(CENT_97317_CHIP_SELECT); + gfx_outb(CENT_97317_CHIP_SELECT, + (unsigned char)(cs_port_val | CENT_97317_CHIP_SEL_MASK)); + return; + +} /* end enable_Centaurus_9211_chip_select() */ + +/******************************************************************** + * + * void disable_Centaurus_9211_chip_select(void); + * Disables the chip select of the CX9211 using the National 97317 + * on a Centaurus board. + * + *******************************************************************/ + +void +disable_Centaurus_9211_chip_select(void) +{ + unsigned char cs_port_val; + + /* Set the chip select (GPIO20) low */ + cs_port_val = gfx_inb(CENT_97317_CHIP_SELECT); + gfx_outb(CENT_97317_CHIP_SELECT, + (unsigned char)(cs_port_val & ~CENT_97317_CHIP_SEL_MASK)); + return; + +} /* end disable_Centaurus_9211_chip_select() */ + +/********************************************************************** + * + * void toggle_Centaurus_9211_clock(void); + * Toggles the clock bit of the CX9211 using the National 97317 on a + * Centaurus board. Assumes the 9211 clock bit has previously been + * initialized to 0 (this way we do not have to waste GPIO cycles + * windowing the clock pulse). + * + **********************************************************************/ + +void +toggle_Centaurus_9211_clock(void) +{ + unsigned char port_val; + + /* get the 97317 GPIO port contents for the 9211 clock */ + + port_val = gfx_inb(CENT_97317_CLOCK_PORT); + /* set the clock bit high */ + gfx_outb(CENT_97317_CLOCK_PORT, + (unsigned char)(port_val | CENT_97317_CLOCK_MASK)); + + /* set the clock bit low */ + gfx_outb(CENT_97317_CLOCK_PORT, + (unsigned char)(port_val & ~CENT_97317_CLOCK_MASK)); + +} /* end toggle_Centaurus_9211_clock() */ + +/******************************************************************** + * + * void write_Centaurus_CX9211_GPIO(unsigned char databit); + * Writes the value in bit 0 of the value passed in databit to + * the 9211 through the GPIO interface of the National 97317 on a + * Centaurus board. + * NOTE: This function does not set or reset the chip select line! + * + *******************************************************************/ + +void +write_Centaurus_CX9211_GPIO(unsigned char databit) +{ + unsigned char data_port_val; + + /* Set the data bit for (GPIO17) */ + databit <<= 7; + + /* read the value of the other bits in the 97317 data port */ + data_port_val = gfx_inb(CENT_97317_DATA_OUTPORT); + + /* set the bit accordingly */ + data_port_val &= ~CENT_97317_DATA_OUT_MASK; + data_port_val |= databit; + gfx_outb(CENT_97317_DATA_OUTPORT, data_port_val); + + /* clock the data */ + toggle_Centaurus_9211_clock(); + return; + +} /* end write_Centaurus_CX9211_GPIO() */ + +/***************************************************************** + * + * void write_Centaurus_CX9211_DWdata(unsigned long data); + * Writes the doubleword value passed in data to the CX9211 + * using GPIO Pins of the National 97317 on a Centaurus board. + * This function assumes the Direction register of the 97317 + * and the address register of the CX9211 have been previously set. + * Uses the global variable count. + * NOTE: This function does not set or reset the chip select line! + * + ******************************************************************/ + +void +write_Centaurus_CX9211_DWdata(unsigned long data) +{ + int count; + + /* Send the read/write command to the 9211 first. */ + + write_Centaurus_CX9211_GPIO(CENT_WRITE); + + /* Now write the 32-bit Data */ + for (count = 0; count < 32; count++) { + write_Centaurus_CX9211_GPIO((unsigned char)(data & 0x01)); + + /* the 9211 expects the data LSB->MSB */ + data >>= 1; + } + return; + +} /* end write_Centaurus_CX9211_DWdata() */ + +/********************************************************************* + * + * unsigned char read_Centaurus_CX9211_GPIO(void); + * Returns the current value of the databit of the 9211 in bit 0 + * using the GPIO interface of the National 97317 on a Centaurus board. + * NOTE: This function does not set or reset the chip select line! + * + *********************************************************************/ + +unsigned char +read_Centaurus_CX9211_GPIO(void) +{ + unsigned char data_port_val; + + toggle_Centaurus_9211_clock(); + + /* read the data */ + data_port_val = gfx_inb(CENT_97317_DATA_INPORT); + + /* Save the data from (GPIO21) as bit 0 */ + data_port_val >>= 1; + return (data_port_val & 0x1); + +} /* end read_Centaurus_CX9211_GPIO() */ + +/********************************************************************** + * + * void read_Centaurus_CX9211_DWdata(unsigned long *data); + * Reads a doubleword value from the CX9211 using GPIO Pins of + * the National 97317 on a Centaurus board. + * This function assumes the Direction register of the 97317 and + * the address register of the CX9211 have been previously set. + * NOTE: This function does not set or reset the chip select line! + * + ***********************************************************************/ + +unsigned long +read_Centaurus_CX9211_DWdata(void) +{ + unsigned char ReadData; + int count; + unsigned long Data; + + /* Send read/write command word to the 9211 first. */ + write_Centaurus_CX9211_GPIO(CENT_READ); + + /* The data book (revision 0.1) states 8 clock periods of no valid data. + * However, the data becomes valid on the eighth clock, making the eighth + * clock valid. Since read_Centaurus_GPIO() toggles the clock before + * reading, we will only toggle the clock 7 times here. + */ + for (count = 0; count < 7; count++) /* works */ + toggle_Centaurus_9211_clock(); + + /* Now read the 32-bit Data, bit by bit in a single loop. */ + Data = 0; + for (count = 0; count < 32; count++) { + ReadData = read_Centaurus_CX9211_GPIO(); + /* 9211 sends data LSB->MSB */ + Data = Data | (((unsigned long)ReadData) << count); + } /* end for() */ + + return Data; + +} /* end read_Centaurus_CX9211_DWdata() */ + +void +Centaurus_Get_9211_Details(unsigned long flags, PPnl_PanelParams pParam) +{ + unsigned long PanelType; + int i; + + for (i = 0; i < 0x7fff; i++) { + } + + init_Centaurus_GPIO(); + + for (i = 0; i < 5; i++) + toggle_Centaurus_9211_clock(); + + if (flags & PNL_PANELCHIP) { + + PanelType = Centaurus_read_gpio(FOUR_BYTES, 0x430); + PanelType = Centaurus_read_gpio(FOUR_BYTES, 0x430); + if ((PanelType & 0xFFFF0000) == 0x92110000) { + + /* found 9211 */ + /* check the values for revision ID */ + if (PanelType >= 0x92110301) + pParam->PanelChip = PNL_9211_C; + else if ((PanelType >= 0x92110101) && (PanelType < 0x92110301)) + pParam->PanelChip = PNL_9211_A; + else + pParam->PanelChip = PNL_UNKNOWN_CHIP; + } else { /* no 9211 present */ + pParam->PanelChip = PNL_UNKNOWN_CHIP; + } + Pnl_Rev_ID = pParam->PanelChip; + } + /* if end */ + if ((pParam->PanelChip != PNL_UNKNOWN_CHIP) && (flags & PNL_PANELSTAT)) { + PanelType = Centaurus_read_gpio(FOUR_BYTES, 0x438); + PanelType &= 0x00f8f8f8; + PanelType |= 0x00070000; + Centaurus_write_gpio(FOUR_BYTES, 0x438, PanelType); + PanelType = 0; + PanelType = Centaurus_read_gpio(FOUR_BYTES, 0x434); + PanelType = (PanelType >> 8); + PanelType &= 0x7; + + switch (PanelType) { + case 0: + pParam->PanelStat.XRes = 800; + pParam->PanelStat.YRes = 600; + pParam->PanelStat.Depth = 18; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_TFT; + break; + case 1: + pParam->PanelStat.XRes = 640; + pParam->PanelStat.YRes = 480; + pParam->PanelStat.Depth = 8; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_SSTN; + break; + case 2: + pParam->PanelStat.XRes = 1024; + pParam->PanelStat.YRes = 768; + pParam->PanelStat.Depth = 18; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_TFT; + break; + case 3: + pParam->PanelStat.XRes = 640; + pParam->PanelStat.YRes = 480; + pParam->PanelStat.Depth = 16; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_DSTN; + break; + case 4: + pParam->PanelStat.XRes = 640; + pParam->PanelStat.YRes = 480; + pParam->PanelStat.Depth = 18; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_TFT; + break; + case 5: + pParam->PanelStat.XRes = 1024; + pParam->PanelStat.YRes = 768; + pParam->PanelStat.Depth = 24; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_DSTN; + break; + case 6: + pParam->PanelStat.XRes = 640; + pParam->PanelStat.YRes = 480; + pParam->PanelStat.Depth = 8; + pParam->PanelStat.MonoColor = PNL_MONO_PANEL; + pParam->PanelStat.Type = PNL_DSTN; + break; + case 7: + pParam->PanelStat.XRes = 800; + pParam->PanelStat.YRes = 600; + pParam->PanelStat.Depth = 16; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_DSTN; + break; + default: + break; + } + } + +} + +void +CentaurusProgramFRMload(void) +{ + unsigned long CentaurusFRMtable[] = { + 0x00000000, + 0x00000000, + 0x01000100, + 0x01000100, + 0x01010101, + 0x01010101, + 0x02081041, + 0x02081041, + 0x10111111, + 0x11111101, + 0x49249241, + 0x12412492, + 0x92244891, + 0x92244891, + 0x22252525, + 0x22252525, + 0x528294a5, + 0x2528494a, + 0x294a5295, + 0x294a5295, + 0x54a54a95, + 0x2952a52a, + 0x2a552a55, + 0x2a552a55, + 0x554aa955, + 0x2a9552aa, + 0x2aaa5555, + 0x2aaa5555, + 0x55555555, + 0x2aaaaaaa, + 0x55555555, + 0x55555555, + 0xaaaaaaab, + 0x55555555, + 0x5555aaab, + 0x5555aaab, + 0xaab556ab, + 0x556aad55, + 0x55ab55ab, + 0x55ab55ab, + 0xab5ab56b, + 0x56ad5ad5, + 0x56b5ad6b, + 0x56b5ad6b, + 0xad6d6b5b, + 0x5ad6b6b6, + 0x5b5b5b5b, + 0x5b5b5b5b, + 0x5F6db6db, + 0x5F6db6db, + 0xF776F776, + 0xF776F776, + 0xFBDEFBDE, + 0xFBDEFBDE, + 0x7eFFBFF7, + 0x7eFFBFF7, + 0xFF7FF7F7, + 0xFF7FF7F7, + 0xFF7FFF7F, + 0xFF7FFF7F, + 0xFFF7FFFF, + 0xFFF7FFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + }; + + unsigned char i; + unsigned short index; + unsigned long data; + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_INDEX, 0); + index = CS92xx_FRM_MEMORY_DATA; + for (i = 0; i < 64; i += 2) { + data = CentaurusFRMtable[i]; + Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_DATA, data); + data = CentaurusFRMtable[i + 1]; + Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_DATA, data); + } + + /* + * The first FRM location (64 bits) does not program correctly. + * This location always reads back with the last value programmed. + * ie. If 32 64-bit values are programmed, location 0 reads + * back as the 32nd If 30 locations are programmed, location 0 + * reads back as the 30th, etc. + * Fix this by re-writing location 0 after programming all 64 in + * the writeFRM loop in RevCFrmload() in CS9211. + */ + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_INDEX, 0); + Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_DATA, 0); + Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_DATA, 0); +} + +/******************************************************************** + * + * void Centaurus_Enable_Power((void); + * Enables the power of the CX9211 using the National 97317 on + * a Centaurus board. + * + ********************************************************************/ + +void +Centaurus_Power_Up(void) +{ + unsigned long off_data = 0x01000000; + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, off_data); + return; + +} /* Centaurus_Disable_Power */ + +/*********************************************************************** + * + * void Centaurus_Disable_Power((void); + * Disables the power of the CX9211 using the National 97317 + * on a Centaurus board. + * + **********************************************************************/ + +void +Centaurus_Power_Down(void) +{ + unsigned long off_data = 0; + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, off_data); + return; + +} /* Centaurus_Disable_Power */ + +void +Centaurus_9211init(Pnl_PanelStat * pstat) +{ + init_Centaurus_GPIO(); + init_Centaurus_9211(); + set_Centaurus_92xx_mode(pstat); + restore_Centaurus_97317_SIOC2(); +} + +void +Centaurus_Save_Panel_State(void) +{ + /* set 9211 registers using the desired panel settings */ + + cs9211_regs.panel_timing1 = + Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_PAN_TIMING1); + cs9211_regs.panel_timing2 = + Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_PAN_TIMING2); + cs9211_regs.dither_frc_ctrl = + Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_DITH_FR_CNTRL); + cs9211_regs.blue_lsfr_seed = + Centaurus_read_gpio(FOUR_BYTES, CS92xx_BLUE_LSFR_SEED); + + cs9211_regs.red_green_lsfr_seed = + Centaurus_read_gpio(FOUR_BYTES, CS92xx_RED_GREEN_LSFR_SEED); + /* CentaurusProgramFRMload(); */ + + cs9211_regs.memory_control = + Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_MEM_CNTRL); + + /* Set the power register last. + * This will turn the panel on at the 9211. + */ + cs9211_regs.power_management = + Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN); +} + +void +Centaurus_Restore_Panel_State(void) +{ + + unsigned long off_data = 0; + + /* Before restoring the 9211 registers, power off the 9211. */ + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, off_data); + + /* set 9211 registers using the desired panel settings */ + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PAN_TIMING1, + cs9211_regs.panel_timing1); + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PAN_TIMING2, + cs9211_regs.panel_timing2); + + /* load the LSFR seeds */ + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_DITH_FR_CNTRL, + cs9211_regs.dither_frc_ctrl); + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_BLUE_LSFR_SEED, + cs9211_regs.blue_lsfr_seed); + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_RED_GREEN_LSFR_SEED, + cs9211_regs.red_green_lsfr_seed); + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_MEM_CNTRL, + cs9211_regs.memory_control); + + /* Set the power register last. This will turn the panel on at the 9211. */ + + Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, + cs9211_regs.power_management); + +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.h new file mode 100644 index 000000000..e1c46c900 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.h @@ -0,0 +1,209 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.h,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/* + * $Workfile: cen9211.h $ + * $Revision: 1.2 $ + * + * File Contents: This header file defines the Durango routines and + * variables used to access the memory mapped regions. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "92xx.h" +#include "panel.h" + +#ifndef _CEN9211_h +#define _CEN9211_h + +/* Centaurus/97317 GPIO PORT defines */ + +#define CENT_97317_CLOCK_PORT 0xE0 +#define CENT_97317_DATA_OUTPORT 0xE0 +#define CENT_97317_CHIP_SELECT 0xE4 +#define CENT_97317_DATA_INPORT 0xE4 +#define CENT_PORT1_DIRECTION 0xE1 +#define CENT_PORT2_DIRECTION 0xE5 +#define CENT_PORT1_OUTPUT_TYPE 0xE2 +#define CENT_PORT2_OUTPUT_TYPE 0xE6 + +/* + * Centaurus/97317 GPIO bit masks. + * In and out are with respect to the 97317. + */ + +#define CENT_97317_CLOCK_MASK 0x10 +#define CENT_97317_CHIP_SEL_MASK 0x01 +#define CENT_97317_DATA_IN_MASK 0x02 +#define CENT_97317_DATA_OUT_MASK 0x80 + +#define CENT_PASS 1 +#define CENT_FAIL 0 +#define CENT_READ 0x0000 +#define CENT_WRITE 0x0001 +#define CENT_NO_DATA 0 + +#define CENT_CONFIG_INDEX 0x2E +#define CENT_SIOC2 0x22 +#define CENT_CONFIG_DATA 0x2F +#define CENT_GPIO_BANK_SELECT 0x80 + +#define CENT_NUM_READ_CLOCK_TOGGLES 1 +#define CENT_NUM_WRITE_CLOCK_TOGGLES 4 + +/* local functions */ +void set_Centaurus_92xx_mode_params(int mode); +void enable_Centaurus_9211_chip_select(void); +void disable_Centaurus_9211_chip_select(void); +void toggle_Centaurus_9211_clock(void); +void write_Centaurus_CX9211_GPIO(unsigned char databit); +void write_Centaurus_CX9211_DWdata(unsigned long data); +void Centaurus_write_gpio(int width, unsigned long address, + unsigned long data); +void Centaurus_Power_Up(void); +void Centaurus_Power_Down(void); +unsigned long Centaurus_read_gpio(int width, unsigned long address); +unsigned char read_Centaurus_CX9211_GPIO(void); +unsigned long read_Centaurus_CX9211_DWdata(void); +unsigned char restore_Centaurus_97317_SIOC2(void); +unsigned char init_Centaurus_GPIO(void); +unsigned char init_Centaurus_9211(void); +unsigned char set_Centaurus_92xx_mode(Pnl_PanelStat * pstat); +void CentaurusProgramFRMload(void); +void Centaurus_Get_9211_Details(unsigned long flags, PPnl_PanelParams pParam); +void Centaurus_Save_Panel_State(void); +void Centaurus_Restore_Panel_State(void); +void Centaurus_9211init(Pnl_PanelStat * pstat); + +#endif /* !_CEN9211_h */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/dora9211.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/dora9211.c new file mode 100644 index 000000000..f5449a432 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/dora9211.c @@ -0,0 +1,713 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/dora9211.c,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/* + * $Workfile: dora9211.c $ + * $Revision: 1.2 $ + * + * File Contents: This file contains the panel functions to interface + * the dorado platform. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "dora9211.h" + +void +Dorado_Get_9211_Details(unsigned long flags, PPnl_PanelParams pParam) +{ + unsigned long DPanelType; + int i; + + for (i = 0; i < 0x7fff; i++) { + } + + Dorado9211GpioInit(); + + for (i = 0; i < 5; i++) + toggle_Centaurus_9211_clock(); + + if (flags & PNL_PANELCHIP) { + DPanelType = Dorado9211ReadReg(0x430); + + if ((DPanelType & 0xFFFF0000) == 0x92110000) { /* found 9211 */ + /* check the values for revision ID */ + if (DPanelType >= 0x92110301) + pParam->PanelChip = PNL_9211_C; + else if ((DPanelType >= 0x92110101) && (DPanelType < 0x92110301)) + pParam->PanelChip = PNL_9211_A; + else + pParam->PanelChip = PNL_UNKNOWN_CHIP; + } else { /* no 9211 present */ + pParam->PanelChip = PNL_UNKNOWN_CHIP; + } + } + + if ((pParam->PanelChip != PNL_UNKNOWN_CHIP) && (flags & PNL_PANELSTAT)) { + unsigned long PanelTypeOrg; + unsigned char Panel_2Byte; + + DPanelType = Dorado9211ReadReg(0x438); + DPanelType &= 0x00e8e8e8; + DPanelType |= 0x00170000; + Dorado9211WriteReg(0x438, DPanelType); + DPanelType = 0; + + DPanelType = Dorado9211ReadReg(0x434); + DPanelType = (DPanelType >> (DRD_LCDRESGPIO1 + 1)); + PanelTypeOrg = DPanelType >> 8; + Panel_2Byte = (unsigned char)PanelTypeOrg; + Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO2 - DRD_LCDRESGPIO1 - 1)); + DPanelType = (DPanelType | ((unsigned int)Panel_2Byte << 8)); + DPanelType = DPanelType >> 1; + PanelTypeOrg = DPanelType >> 8; + Panel_2Byte = (unsigned char)PanelTypeOrg; + Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO3 - DRD_LCDRESGPIO2 - 1)); + DPanelType = (DPanelType | ((unsigned int)Panel_2Byte << 8)); + DPanelType = DPanelType >> 1; + PanelTypeOrg = DPanelType >> 8; + Panel_2Byte = (unsigned char)PanelTypeOrg; + Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO4 - DRD_LCDRESGPIO3 - 1)); + DPanelType = (DPanelType | ((unsigned int)Panel_2Byte << 8)); + DPanelType = DPanelType >> 5; + DPanelType &= 0xf; + + switch (DPanelType) { + case 8: + pParam->PanelStat.XRes = 800; + pParam->PanelStat.YRes = 600; + pParam->PanelStat.Depth = 18; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_TFT; + break; + + case 9: + pParam->PanelStat.XRes = 640; + pParam->PanelStat.YRes = 480; + pParam->PanelStat.Depth = 8; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_SSTN; + break; + + case 10: + pParam->PanelStat.XRes = 1024; + pParam->PanelStat.YRes = 768; + pParam->PanelStat.Depth = 18; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_TFT; + break; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 11: + pParam->PanelStat.XRes = 640; + pParam->PanelStat.YRes = 480; + pParam->PanelStat.Depth = 16; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_DSTN; + break; + case 12: + pParam->PanelStat.XRes = 640; + pParam->PanelStat.YRes = 480; + pParam->PanelStat.Depth = 18; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_TFT; + break; + case 13: + pParam->PanelStat.XRes = 1024; + pParam->PanelStat.YRes = 768; + pParam->PanelStat.Depth = 24; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_DSTN; + break; + case 14: + pParam->PanelStat.XRes = 640; + pParam->PanelStat.YRes = 480; + pParam->PanelStat.Depth = 8; + pParam->PanelStat.MonoColor = PNL_MONO_PANEL; + pParam->PanelStat.Type = PNL_DSTN; + break; + case 15: + pParam->PanelStat.XRes = 800; + pParam->PanelStat.YRes = 600; + pParam->PanelStat.Depth = 16; + pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; + pParam->PanelStat.Type = PNL_DSTN; + break; + default: + break; + } + } + /* if block end */ +} + +void +Dorado9211Init(Pnl_PanelStat * pstat) +{ + int mode; + unsigned long orig_value, pm_value; + + gfx_delay_milliseconds(100); + Dorado9211GpioInit(); + + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + + gfx_delay_milliseconds(100); + + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + + Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x0); + + gfx_delay_milliseconds(100); + gfx_delay_milliseconds(100); + + /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ + for (mode = 0; mode < NUM_92XX_MODES; mode++) { + if ((FPModeParams[mode].xres == pstat->XRes) && + (FPModeParams[mode].yres == pstat->YRes) && + (FPModeParams[mode].bpp == pstat->Depth) && + (FPModeParams[mode].panel_type == pstat->Type) && + (FPModeParams[mode].color_type == pstat->MonoColor)) { + + /* SET THE 92xx FOR THE SELECTED MODE */ + CS92xx_MODE *pMode = &FPModeParams[mode]; + + Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING1, pMode->panel_timing1); + Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING2, pMode->panel_timing2); + Dorado9211WriteReg(CS92xx_LCD_DITH_FR_CNTRL, + pMode->rev_C_dither_frc); + Dorado9211WriteReg(CS92xx_BLUE_LSFR_SEED, pMode->blue_lsfr_seed); + Dorado9211WriteReg(CS92xx_RED_GREEN_LSFR_SEED, + pMode->red_green_lsfr_seed); + DoradoProgramFRMload(); + Dorado9211WriteReg(CS92xx_LCD_MEM_CNTRL, pMode->memory_control); + Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, pMode->power_management); + gfx_delay_milliseconds(100); + gfx_delay_milliseconds(100); + Dorado9211ClearCS(); + + /* This code is added to take care of Panel initialization. + * Irrespective of Xpressrom is enabling the panel or not. + */ + orig_value = READ_VID32(0X04); + WRITE_VID32(0x04, 0x00200141); + gfx_delay_milliseconds(21); + pm_value = gfx_ind(0x9030); + + pm_value |= 0x400; + gfx_outd(0x9030, pm_value); + gfx_delay_milliseconds(4); + orig_value &= 0xfff1ffff; + WRITE_VID32(0X4, orig_value); + return; + } /*end if() */ + } /*end for() */ + +} + +void +Dorado9211SetCS(void) +{ + unsigned long value; + + value = gfx_ind(DRD_CSP9211IN); + gfx_outd(DRD_CSP9211OUT, value | DRD_CS9211); +} + +void +Dorado9211ClearCS(void) +{ + unsigned long value; + + value = gfx_ind(DRD_CSP9211IN); + gfx_outd(DRD_CSP9211OUT, value & (~DRD_CS9211)); +} + +void +Dorado9211SetDataOut(void) +{ + unsigned long value; + + value = gfx_ind(DRD_DATAOUTP9211IN); + gfx_outd(DRD_DATAOUTP9211OUT, value | DRD_DATAIN9211); +} + +void +Dorado9211ClearDataOut(void) +{ + unsigned long value; + + value = gfx_ind(DRD_DATAOUTP9211IN); + gfx_outd(DRD_DATAOUTP9211OUT, value & (~DRD_DATAIN9211)); +} + +unsigned char +Dorado9211ReadDataIn(void) +{ + unsigned char readdata = 0; + unsigned long value; + + /* why to read 4 times ??? */ + value = gfx_ind(DRD_DATAINP9211IN); + value = gfx_ind(DRD_DATAINP9211IN); + value = gfx_ind(DRD_DATAINP9211IN); + value = gfx_ind(DRD_DATAINP9211IN); + if (value & DRD_DATAOUT9211) + readdata = 1; + return (readdata); +} + +void +Dorado9211ToggleClock(void) +{ + Dorado9211SetClock(); + Dorado9211ClearClock(); +} + +void +Dorado9211SetClock(void) +{ + unsigned long value; + + value = gfx_ind(DRD_CLOCKP9211IN); + gfx_outd(DRD_CLOCKP9211OUT, value | DRD_CLOCK9211); +} + +void +Dorado9211ClearClock(void) +{ + unsigned long value; + + value = gfx_ind(DRD_CLOCKP9211IN); + gfx_outd(DRD_CLOCKP9211OUT, value & (~DRD_CLOCK9211)); +} + +void +Dorado9211GpioInit(void) +{ + unsigned long value; + + /* set output enable on gpio 7, 9, 11 */ + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_CLOCK9211CFG); + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); + /* set output enable on gpio 7, 9, 11 */ + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_CS9211CFG); + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); + /* set output enable on gpio 7, 9, 18 */ + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_DATAIN9211CFG); + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); + /* disable on gpio 11 - This is the output from the 9211 */ + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_DATAOUT9211CFG); + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 0); + /* Set all PINS low */ + value = gfx_ind(DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDI0); + value &= ~(DRD_CS9211 | DRD_CLOCK9211 | DRD_DATAIN9211); + gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDO0), value); +} + +unsigned long +Dorado9211ReadReg(unsigned short index) +{ + + unsigned char i, readbit; + unsigned long data; + + Dorado9211ClearDataOut(); + + Dorado9211SetCS(); + Dorado9211ToggleClock(); + + Dorado9211SetDataOut(); + Dorado9211ToggleClock(); + + for (i = 0; i < 12; i++) { + if (index & 0x1) { + Dorado9211SetDataOut(); + } else { + Dorado9211ClearDataOut(); + } + Dorado9211ToggleClock(); + index >>= 1; + } + + Dorado9211ClearDataOut(); + Dorado9211ToggleClock(); + + /* Idle clock, 7 clocks, no data set */ + + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + + data = 0; + for (i = 0; i < 32; i++) { + Dorado9211ToggleClock(); + readbit = Dorado9211ReadDataIn(); + data |= (((unsigned long)readbit) << i); + } + + Dorado9211ClearCS(); + Dorado9211ToggleClock(); + return (data); + +} + +void +Dorado9211WriteReg(unsigned short index, unsigned long data) +{ + + unsigned char i; + + Dorado9211ClearDataOut(); + Dorado9211SetDataOut(); + Dorado9211SetCS(); + Dorado9211ToggleClock(); + Dorado9211SetDataOut(); + Dorado9211ToggleClock(); + + for (i = 0; i < 12; i++) { + if (index & 0x1) { + Dorado9211SetDataOut(); + } else { + Dorado9211ClearDataOut(); + } + Dorado9211ToggleClock(); + index >>= 1; + } + + Dorado9211SetDataOut(); + Dorado9211ToggleClock(); + + for (i = 0; i < 32; i++) { + if (data & 0x1) { + Dorado9211SetDataOut(); + } else { + Dorado9211ClearDataOut(); + } + Dorado9211ToggleClock(); + data >>= 1; + } + + Dorado9211ClearCS(); + + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); + Dorado9211ToggleClock(); +} + +void +DoradoProgramFRMload(void) +{ + unsigned long DoradoFRMtable[] = { + + 0x00000000, + 0x00000000, + 0x01000100, + 0x01000100, + 0x01010101, + 0x01010101, + 0x02081041, + 0x02081041, + 0x10111111, + 0x11111101, + 0x49249241, + 0x12412492, + 0x92244891, + 0x92244891, + 0x22252525, + 0x22252525, + 0x528294a5, + 0x2528494a, + 0x294a5295, + 0x294a5295, + 0x54a54a95, + 0x2952a52a, + 0x2a552a55, + 0x2a552a55, + 0x554aa955, + 0x2a9552aa, + 0x2aaa5555, + 0x2aaa5555, + 0x55555555, + 0x2aaaaaaa, + 0x55555555, + 0x55555555, + 0xaaaaaaab, + 0x55555555, + 0x5555aaab, + 0x5555aaab, + 0xaab556ab, + 0x556aad55, + 0x55ab55ab, + 0x55ab55ab, + 0xab5ab56b, + 0x56ad5ad5, + 0x56b5ad6b, + 0x56b5ad6b, + 0xad6d6b5b, + 0x5ad6b6b6, + 0x5b5b5b5b, + 0x5b5b5b5b, + 0x5F6db6db, + 0x5F6db6db, + 0xF776F776, + 0xF776F776, + 0xFBDEFBDE, + 0xFBDEFBDE, + 0x7eFFBFF7, + 0x7eFFBFF7, + 0xFF7FF7F7, + 0xFF7FF7F7, + 0xFF7FFF7F, + 0xFF7FFF7F, + 0xFFF7FFFF, + 0xFFF7FFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + }; + + unsigned char i; + unsigned short index; + unsigned long data; + + Dorado9211WriteReg(CS92xx_FRM_MEMORY_INDEX, 0); + index = CS92xx_FRM_MEMORY_DATA; + for (i = 0; i < 64; i += 2) { + data = DoradoFRMtable[i]; + Dorado9211WriteReg(index, data); + data = DoradoFRMtable[i + 1]; + Dorado9211WriteReg(index, data); + } + +/* + * The first FRM location (64 bits) does not program correctly. + * This location always reads back with the last value programmed. + * ie. If 32 64-bit values are programmed, location 0 reads back as the 32nd + * If 30 locations are programmed, location 0 reads back as the 30th, etc. + * Fix this by re-writing location 0 after programming all 64 in the writeFRM + * loop in RevCFrmload() in CS9211. + */ + + Dorado9211WriteReg(CS92xx_FRM_MEMORY_INDEX, 0); + Dorado9211WriteReg(CS92xx_FRM_MEMORY_DATA, 0); + Dorado9211WriteReg(CS92xx_FRM_MEMORY_DATA, 0); + +} + +/****************************************************************************** + * void Dorado_Enable_Power((void); + * Enables the power of the CX9211 on Dorado board. + ****************************************************************************** + */ + +void +Dorado_Power_Up(void) +{ + Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x01000000); + return; + +} /* disable_Centaurus_Power */ + +/****************************************************************************** + * void Dorado_Disable_Power((void); + * Disables the power of the CX9211 on Dorado board. + ***************************************************************************** + */ + +void +Dorado_Power_Down(void) +{ + Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x0); + return; + +} /* disable_Centaurus_Power */ + +void +Dorado_Save_Panel_State(void) +{ + + /* set 9211 registers using the desired panel settings */ + cs9211_regs.panel_timing1 = Dorado9211ReadReg(CS92xx_LCD_PAN_TIMING1); + cs9211_regs.panel_timing2 = Dorado9211ReadReg(CS92xx_LCD_PAN_TIMING2); + + cs9211_regs.dither_frc_ctrl = Dorado9211ReadReg(CS92xx_LCD_DITH_FR_CNTRL); + cs9211_regs.blue_lsfr_seed = Dorado9211ReadReg(CS92xx_BLUE_LSFR_SEED); + cs9211_regs.red_green_lsfr_seed = + Dorado9211ReadReg(CS92xx_RED_GREEN_LSFR_SEED); + + /* CentaurusProgramFRMload(); */ + cs9211_regs.memory_control = Dorado9211ReadReg(CS92xx_LCD_MEM_CNTRL); + + /* Set the power register last. This will turn the panel on at the 9211. */ + cs9211_regs.power_management = Dorado9211ReadReg(CS92xx_LCD_PWR_MAN); + cs9211_regs.panel_state = cs9211_regs.power_management; +} + +void +Dorado_Restore_Panel_State(void) +{ + unsigned long off_data = 0; + + /* Before restoring the 9211 registers, power off the 9211. */ + + Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, off_data); + + /* set 9211 registers using the desired panel settings */ + Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING1, cs9211_regs.panel_timing1); + Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING2, cs9211_regs.panel_timing2); + /* load the LSFR seeds */ + Dorado9211WriteReg(CS92xx_LCD_DITH_FR_CNTRL, cs9211_regs.dither_frc_ctrl); + Dorado9211WriteReg(CS92xx_BLUE_LSFR_SEED, cs9211_regs.blue_lsfr_seed); + Dorado9211WriteReg(CS92xx_RED_GREEN_LSFR_SEED, + cs9211_regs.red_green_lsfr_seed); + + Dorado9211WriteReg(CS92xx_LCD_MEM_CNTRL, cs9211_regs.memory_control); + /* Set the power register last. This will turn the panel on at the 9211. */ + Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, cs9211_regs.power_management); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/dora9211.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/dora9211.h new file mode 100644 index 000000000..cef4454ab --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/dora9211.h @@ -0,0 +1,203 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/dora9211.h,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/* + * $Workfile: dora9211.h $ + * $Revision: 1.2 $ + * + * File Contents: This header file defines the Durango routines and + * variables used to access the memory mapped regions. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Geode graphics driver for panel support + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "panel.h" +#include "92xx.h" + +#ifndef _DORA9211_h +#define _DORA9211_h + +/* 9211 Rev.C3 Dorado */ + +/* GPIO Pin Configuration Registers */ + +#define DRD_GEODE_GPPIN_SEL 0x20 /* GPIO Pin Configuration Select */ +#define DRD_GEODE_GPPIN_CFG 0x24 /* GPIO Pin Configuration Access */ +#define DRD_GEODE_GPPIN_RESET 0x28 /* GPIO Pin Reset */ + +#define DRD_GEODE_GPIO_BASE 0x6400 /* F0 GPIO, IO mapped */ +#define DRD_GEODE_GPDI0 0x04 /* GPIO Data In 0 */ +#define DRD_GEODE_GPDO0 0x00 /* GPIO Data Out 0 */ + +/* Data Ports in */ +#define DRD_CLOCKP9211IN DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDI0 +#define DRD_DATAINP9211IN DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDI0 +#define DRD_DATAOUTP9211IN DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDI0 +#define DRD_CSP9211IN DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDI0 + +/* Data Ports out */ +#define DRD_CLOCKP9211OUT DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDO0 +#define DRD_DATAINP9211OUT DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDO0 +#define DRD_DATAOUTP9211OUT DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDO0 +#define DRD_CSP9211OUT DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDO0 + +/* Pin MASKS */ +#define DRD_CLOCK9211 0x00000080 /*;gpio 7, clock output to 9211 */ +#define DRD_DATAIN9211 0x00040000 /*;gpio 18, data output to 9211 */ +#define DRD_DATAOUT9211 0x00000800 /*;gpio 11, data input from 9211 */ +#define DRD_CS9211 0x00000200 /*;gpio 9, chip select output to 9211 */ + +/* Gpio CFG values to select in */ +#define DRD_CLOCK9211CFG 0x00000007 /* ;gpio 7 */ +#define DRD_DATAIN9211CFG 0x00000012 /* ;gpio 18 */ +#define DRD_DATAOUT9211CFG 0x0000000B /* ;gpio 11 */ +#define DRD_CS9211CFG 0x00000009 /* ;gpio 9 */ + +#define DRD_LCDRESGPIO1 0x00 +#define DRD_LCDRESGPIO2 0x01 +#define DRD_LCDRESGPIO3 0x02 +#define DRD_LCDRESGPIO4 0x04 + +void Dorado9211SetCS(void); +void Dorado9211ClearCS(void); +void Dorado9211SetDataOut(void); +void Dorado9211ClearDataOut(void); +unsigned char Dorado9211ReadDataIn(void); +void Dorado9211ToggleClock(void); +void Dorado9211SetClock(void); +void Dorado9211ClearClock(void); +void Dorado9211GpioInit(void); +unsigned long Dorado9211ReadReg(unsigned short index); +void Dorado9211WriteReg(unsigned short index, unsigned long data); +void DoradoProgramFRMload(void); +void Dorado_Get_9211_Details(unsigned long flags, PPnl_PanelParams pParam); +void Dorado_Power_Up(void); +void Dorado_Power_Down(void); +void Dorado_Save_Panel_State(void); +void Dorado_Restore_Panel_State(void); +void Dorado9211Init(Pnl_PanelStat * pstat); + +#endif /* !_DORA9211_h */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/drac9210.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/drac9210.c new file mode 100644 index 000000000..0dc4afdce --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/drac9210.c @@ -0,0 +1,820 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/drac9210.c,v 1.2 2003/01/14 09:34:35 alanh Exp $ */ +/* + * $Workfile: drac9210.c $ + * $Revision: 1.2 $ + * + * File Contents: This file contains the panel library files to the + * platforms with 9210, and 9211 support. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "drac9210.h" + +#define CS9210 0x40 /* Chip select pin */ + +/* 9210 on Draco */ +#define CLOCK9210 0x04 /* Clock pin */ +#define DATAIN9210 0x20 /* Data from 9210 */ +#define DATAOUT9210 0x80 /* Data to 9210 */ + +static void DracoWriteData(unsigned char data); +static void DracoReadData(unsigned char *data); +static void Draco9210GpioInit(); +static void Draco9210SetCS(void); +static unsigned char Draco9210ReadReg(unsigned char index); +static void Draco9210WriteReg(unsigned char index, unsigned char data); +static void Draco9210ClearCS(void); +static void Draco9210SetDataOut(void); +static void Draco9210ClearDataOut(void); +static unsigned char Draco9210ReadDataIn(void); +static void Draco9210ToggleClock(void); + +void +Draco9210Init(Pnl_PanelStat * pstat) +{ + unsigned char panelvalues[] = { + 0x2, 0x80, + 0x2, 0x24, + 0x03, 0x00, + 0xc0, 0x00, + 0xc1, 0x00, + 0xc2, 0x00, + 0xc3, 0x00, + 0xc4, 0x00, + 0xc5, 0x01, + 0xc6, 0xff, + 0xc7, 0xff, + 0xc8, 0x3, + 0xc9, 0xfe, + 0xca, 0x0, + 0xcb, 0x3f, + 0xcc, 0xc, + 0xcd, 0x1, + 0xce, 0xff, + 0xcf, 0xc1, + 0xd0, 0x0, + 0xd1, 0x7e, + 0xd2, 0x3, + 0xd3, 0xfe, + 0xd4, 0x3, + 0xd5, 0x81, + 0xd6, 0xfc, + 0xd7, 0x3f, + 0xd8, 0x14, + 0xd9, 0x1e, + 0xda, 0x0f, + 0xdb, 0xc7, + 0xdc, 0x29, + 0xdd, 0xe1, + 0xde, 0xf1, + 0xdf, 0xf9, + 0xe0, 0x2, + 0xe1, 0xe, + 0xe2, 0x1e, + 0xe3, 0x3e, + 0xe4, 0x04, + 0xe5, 0x71, + 0xe6, 0xe3, + 0xe7, 0xcf, + 0xe8, 0x1, + 0xe9, 0x86, + 0xea, 0x3c, + 0xeb, 0xf3, + 0xec, 0xa, + 0xed, 0x39, + 0xee, 0xc7, + 0xef, 0x3d, + + 0xf0, 0x14, + 0xf1, 0xc6, + 0xf2, 0x39, + 0xf3, 0xce, + 0xf4, 0x3, + 0xf5, 0x19, + 0xf6, 0xce, + 0xf7, 0x77, + 0xf8, 0x0, + 0xf9, 0x66, + 0xfa, 0x33, + 0xfb, 0xbb, + 0xfc, 0x2d, + 0xfd, 0x99, + 0xfe, 0xdd, + 0xff, 0xdd, + + 0x3, 0x1, + 0xc0, 0x2, + 0xc1, 0x22, + 0xc2, 0x66, + 0xc3, 0x66, + 0xc4, 0x0, + 0xc5, 0xcd, + 0xc6, 0x99, + 0xc7, 0xbb, + 0xc8, 0x5, + 0xc9, 0x32, + 0xca, 0x66, + 0xcb, 0xdd, + 0xcc, 0x1a, + 0xcd, 0x4d, + 0xce, 0x9b, + 0xcf, 0x6f, + 0xd0, 0x0, + 0xd1, 0x92, + 0xd2, 0x6d, + 0xd3, 0xb6, + 0xd4, 0x5, + 0xd5, 0x25, + 0xd6, 0xb6, + 0xd7, 0xdb, + 0xd8, 0x2, + 0xd9, 0x5a, + 0xda, 0x4b, + 0xdb, 0x6d, + 0xdc, 0x29, + 0xdd, 0xa5, + 0xde, 0xb5, + 0xdf, 0xb7, + 0xe0, 0x4, + 0xe1, 0x4a, + 0xe2, 0x5a, + 0xe3, 0xda, + 0xe4, 0x12, + 0xe5, 0x95, + 0xe6, 0xad, + 0xe7, 0x6f, + 0xe8, 0x1, + 0xe9, 0x2a, + 0xea, 0x56, + 0xeb, 0xb5, + 0xec, 0xe, + 0xed, 0x55, + 0xee, 0xab, + 0xef, 0x5f, + 0xf0, 0x0, + 0xf1, 0xaa, + 0xf2, 0x55, + 0xf3, 0xea, + 0xf4, 0x1, + 0xf5, 0x55, + 0xf6, 0xaa, + 0xf7, 0xbf, + 0xf8, 0x6, + 0xf9, 0xaa, + 0xfa, 0x55, + 0xfb, 0x55, + 0xfc, 0x39, + 0xfd, 0x55, + 0xfe, 0xff, + 0xff, 0xff, + + 0x3, 0x2, + 0xc0, 0x0, + 0xc1, 0x0, + 0xc2, 0xaa, + 0xc3, 0xaa, + 0xc4, 0x6, + 0xc5, 0xab, + 0xc6, 0x55, + 0xc7, 0x55, + 0xc8, 0x01, + 0xc9, 0x54, + 0xca, 0xaa, + 0xcb, 0xbf, + 0xcc, 0x8, + 0xcd, 0xab, + 0xce, 0x55, + 0xcf, 0xeb, + 0xd0, 0x6, + 0xd1, 0x54, + 0xd2, 0xab, + 0xd3, 0x5e, + 0xd4, 0x1, + 0xd5, 0x2b, + 0xd6, 0x56, + 0xd7, 0xb5, + 0xd8, 0x12, + 0xd9, 0x94, + 0xda, 0xad, + 0xdb, 0x6f, + 0xdc, 0x2d, + 0xdd, 0x4b, + 0xde, 0x5b, + 0xdf, 0xdb, + 0xe0, 0x0, + 0xe1, 0xa4, + 0xe2, 0xb4, + 0xe3, 0xb6, + 0xe4, 0x2, + 0xe5, 0x5b, + 0xe6, 0x4b, + 0xe7, 0x6d, + 0xe8, 0x5, + 0xe9, 0x24, + 0xea, 0xb6, + 0xeb, 0xdb, + 0xec, 0x8, + 0xed, 0x93, + 0xee, 0x6d, + 0xef, 0xb7, + 0xf0, 0x12, + 0xf1, 0x4c, + 0xf2, 0x9b, + 0xf3, 0x6e, + 0xf4, 0x5, + 0xf5, 0x33, + 0xf6, 0x66, + 0xf7, 0xdd, + 0xf8, 0x0, + 0xf9, 0xcc, + 0xfa, 0x99, + 0xfb, 0xbb, + 0xfc, 0x2b, + 0xfd, 0x33, + 0xfe, 0x77, + 0xff, 0x77, + + 0x3, 0x3, + 0xc0, 0x4, + 0xc1, 0x88, + 0xc2, 0xcc, + 0xc3, 0xcc, + 0xc4, 0x0, + 0xc5, 0x67, + 0xc6, 0x33, + 0xc7, 0xbb, + 0xc8, 0x3, + 0xc9, 0x18, + 0xca, 0xce, + 0xcb, 0x77, + 0xcc, 0x1c, + 0xcd, 0xc7, + 0xce, 0x39, + 0xcf, 0xcf, + + 0xd0, 0x2, + 0xd1, 0x38, + 0xd2, 0xc7, + 0xd3, 0x3c, + 0xd4, 0x1, + 0xd5, 0x87, + 0xd6, 0x3c, + 0xd7, 0xf3, + 0xd8, 0x4, + 0xd9, 0x70, + 0xda, 0xe3, + 0xdb, 0xcf, + 0xdc, 0x2b, + 0xdd, 0xf, + 0xde, 0x1f, + 0xdf, 0x3f, + 0xe0, 0x00, + 0xe1, 0xe0, + 0xe2, 0xf0, + 0xe3, 0xf8, + 0xe4, 0x14, + 0xe5, 0x1f, + 0xe6, 0xf, + 0xe7, 0xc7, + 0xe8, 0x3, + 0xe9, 0x80, + 0xea, 0xfc, + 0xeb, 0x3f, + 0xec, 0x8, + 0xed, 0x7f, + 0xee, 0x3, + 0xef, 0xff, + 0xf0, 0x4, + 0xf1, 0x0, + 0xf2, 0xff, + 0xf3, 0xc0, + 0xf4, 0x3, + 0xf5, 0xff, + 0xf6, 0x0, + 0xf7, 0x3f, + 0xf8, 0x0, + 0xf9, 0x0, + 0xfa, 0xff, + 0xfb, 0xff, + 0xfc, 0x3f, + 0xfd, 0xff, + 0xfe, 0xff, + 0xff, 0xff, + 0x3, 0x4, + + /* Setup the Diter to Pattern33 */ + 0x80, 0xdd, + 0x81, 0xdd, + 0x82, 0x33, + 0x83, 0x33, + 0x84, 0xdd, + 0x85, 0xdd, + 0x86, 0x33, + 0x87, 0x33, + 0x88, 0x33, + 0x89, 0x33, + 0x8a, 0x77, + 0x8b, 0x77, + 0x8c, 0x33, + 0x8d, 0x33, + 0x8e, 0x77, + 0x8f, 0x77, + 0x90, 0xdd, + 0x91, 0xdd, + 0x92, 0x33, + 0x93, 0x33, + 0x94, 0xdd, + 0x95, 0xdd, + 0x96, 0x33, + 0x97, 0x33, + 0x98, 0x33, + 0x99, 0x33, + 0x9a, 0x77, + 0x9b, 0x77, + 0x9c, 0x33, + 0x9d, 0x33, + 0x9e, 0x77, + 0x9f, 0x77, + + 0x4, 0x20, + 0x5, 0x3, + 0x6, 0x56, + 0x7, 0x2, + 0x8, 0x1c, + 0x9, 0x0, + 0xa, 0x26, + 0xb, 0x0, + 0xc, 0x15, + 0xd, 0x4, + 0xe, 0x50, + 0xf, 0x4, + 0x10, 0xfa, + 0x11, 0x0, + 0x12, 0xc8, + 0x13, 0x0, + 0x14, 0x31, + 0x15, 0x23, + 0x16, 0x0, + + /* Enable DSTN panel */ + 0x2, 0x64 + }; + unsigned char index, data; + int i; + + gfx_delay_milliseconds(100); + Draco9210GpioInit(); + Draco9210SetCS(); + Draco9210ToggleClock(); + Draco9210ToggleClock(); + Draco9210ToggleClock(); + Draco9210ToggleClock(); + Draco9210ClearCS(); + +#if defined(_WIN32) /* For Windows */ + for (i = 0; i < 10; i++) { + _asm { + out 0EDh, al} + } + +#elif defined(linux) /* Linux */ + +#endif + + for (i = 0; i < 630; i += 2) { + index = panelvalues[i]; + data = panelvalues[i + 1]; + Draco9210WriteReg(index, data); + } + +} + +static void +DracoWriteData(unsigned char data) +{ + int i; + unsigned char mask = 0x80, databit; + + for (i = 0; i < 8; i++) { + + databit = data & mask; + if (data & mask) { + Draco9210SetDataOut(); + } else { + Draco9210ClearDataOut(); + } + mask >>= 1; + Draco9210ToggleClock(); + } +} + +static void +DracoReadData(unsigned char *data) +{ + int i; + unsigned char tmp = 0, readbit; + + Draco9210ClearDataOut(); + Draco9210ToggleClock(); + for (i = 0; i < 7; i++) { + readbit = Draco9210ReadDataIn(); + tmp |= (readbit & 0x1); + tmp <<= 1; + Draco9210ToggleClock(); + } + readbit = Draco9210ReadDataIn(); + tmp |= (readbit & 0x1); + *data = tmp; +} + +#if defined(_WIN32) /* For Windows */ + +void +Draco9210GpioInit() +{ + _asm { + pushf + cli + mov dx, 0CF8h + mov eax, CX55x0_ID + 090h + out dx, eax + mov dx, 0CFCh + mov al, 0CFh + mov ah, 00h + out dx, ax + popf + } +} + +void +Draco9210SetCS() +{ + _asm { + pushf + ;Point to PCI address register + mov dx, 0CF8h + ;55 XX GPIO data register + mov eax, CX55x0_ID + 090h + out dx, eax + ;Point to PCI data register (CFCh) + mov dx, 0CFCh + + in ax, dx + and ah, 30h + mov ah, c92DataReg + or ah, CS9210 + mov c92DataReg, ah + out dx, ax + popf + } +} + +void +Draco9210ClearCS() +{ + _asm { + pushf + ;Point to PCI address register + mov dx, 0CF8h + ;55 XX GPIO data register + mov eax, CX55x0_ID + 090h + out dx, eax + ;Point to PCI data register (CFCh) + mov dx, 0CFCh + ;Set CS LOW + in ax, dx + mov ah, c92DataReg + and ah, NOT CS9210 + mov c92DataReg, ah + out dx, ax + popf + } +} + +void +Draco9210SetDataOut() +{ + _asm { + pushf + ;Point to PCI address register + mov dx, 0CF8h + ;55 XX GPIO data register + mov eax, CX55x0_ID + 090h + out dx, eax + ;Point to PCI data register (CFCh) + mov dx, 0CFCh + ;Set DATA HIGH + in ax, dx + mov ah, c92DataReg + or ah, DATAOUT9210 + mov c92DataReg, ah + out dx, ax + popf + } +} + +void +Draco9210ClearDataOut() +{ + _asm { + pushf + ;Point to PCI address register + mov dx, 0CF8h + mov eax, CX55x0_ID + 090h; + ;55 XX GPIO data register + out dx, eax + ;Point to PCI data register (CFCh) + mov dx, 0CFCh + ;Set Data LOW + in ax, dx + mov ah, c92DataReg + and ah, NOT DATAOUT9210 + mov c92DataReg, ah + out dx, ax + popf + } +} + +unsigned char +Draco9210ReadDataIn() +{ + unsigned char readdata; + + _asm { + pushf + ;Point to PCI address register + mov dx, 0CF8h + ;55 XX GPIO data register + mov eax, CX55x0_ID + 090h + out dx, eax + ;Point to PCI data register (CFCh) + mov dx, 0FCh + + in ax, dx + ;Preserve just Data IN bit + and ah, DATAIN9210 + mov al, ah + cmp al, 0 + ;Is it LOW ? + je readDataLow + ;must be HIGH + mov al, 1 + readDataLow: + mov readdata, al + popf + } + return (readdata); +} + +void +Draco9210ToggleClock() +{ + _asm { + pushf + ;Point to PCI address register + mov dx, 0CF8h + ;55 XX GPIO data register + mov eax, CX55x0_ID + 090h + ;Point to PCI data register (CFCh) + out dx, eax + mov dx, 0CFCh + ;SET CLOCK + in ax, dx + mov ah, c92DataReg + or ah, CLOCK9210 + mov c92DataReg, ah + out dx, ax + out 0EDh, al /* IOPAUSE */ + ;Point to PCI address register + mov dx, 0CF8h + ;55 XX GPIO data register + mov eax, CX55x0_ID + 090h + out dx, eax + ;Point to PCI data register (CFCh) + mov dx, 0CFCh; + ;CLEAR CLOCK + in ax, dx + mov ah, c92DataReg + and ah, NOT CLOCK9210 + mov c92DataReg, ah + out dx, ax + popf + } +} + +#elif defined(linux) /* Linux */ + +void +Draco9210GpioInit() +{ +} +void +Draco9210SetCS() +{ +} +void +Draco9210ClearCS() +{ +} +void +Draco9210SetDataOut() +{ +} +void +Draco9210ClearDataOut() +{ +} +unsigned char +Draco9210ReadDataIn() +{ +} +void +Draco9210ToggleClock() +{ +} + +#endif + +unsigned char +Draco9210ReadReg(unsigned char index) +{ + unsigned char data; + + Draco9210SetCS(); + Draco9210ToggleClock(); + Draco9210SetDataOut(); + Draco9210ToggleClock(); + Draco9210ClearDataOut(); + Draco9210ToggleClock(); + Draco9210ClearDataOut(); + Draco9210ToggleClock(); + Draco9210ClearDataOut(); + Draco9210ToggleClock(); + + DracoWriteData(index); + DracoReadData(&data); + + return (data); +} + +void +Draco9210WriteReg(unsigned char index, unsigned char data) +{ + + Draco9210SetCS(); + Draco9210ToggleClock(); + + Draco9210SetDataOut(); + Draco9210ToggleClock(); + + Draco9210ClearDataOut(); + Draco9210ToggleClock(); + + Draco9210ClearDataOut(); + Draco9210ToggleClock(); + + Draco9210SetDataOut(); + Draco9210ToggleClock(); + + DracoWriteData(index); + DracoWriteData(data); + + Draco9210ClearDataOut(); + Draco9210ToggleClock(); + + Draco9210ClearCS(); + Draco9210ToggleClock(); + Draco9210ToggleClock(); + +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/drac9210.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/drac9210.h new file mode 100644 index 000000000..1dd762484 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/drac9210.h @@ -0,0 +1,274 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/drac9210.h,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/* + * $Workfile: drac9210.h $ + * $Revision: 1.2 $ + * + * File Contents: This file contains the panel header file and definition + * for the platform with 9210 support. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Geode graphics driver for panel support + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "panel.h" + +#ifndef _DRAC9210_h +#define _DRAC9210_h +#define CX55x0_ID 0x80009000 +static unsigned char c92DataReg = 0; +#endif /* !_DRAC9210_h */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.c new file mode 100644 index 000000000..71909f8c4 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.c @@ -0,0 +1,382 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.c,v 1.3 2003/01/14 09:34:35 alanh Exp $ */ +/* + * $Workfile: gx2_9211.c $ + * + * This header file defines the pneumonics used when calling Durango routines. + * This file is automatically included by gfx_rtns.h + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "92xx.h" +#include "gx2_9211.h" +#include "pnl_defs.h" + +#if defined(_WIN32) /*windows */ +#include "gfx_defs.h" + +extern DEV_STATUS gfx_msr_read(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue); +extern DEV_STATUS gfx_msr_write(unsigned int device, unsigned int msrRegister, + Q_WORD * msrValue); +#endif + +static unsigned long FPBaseAddr; + +void +SetFPBaseAddr(unsigned long addr) +{ + + FPBaseAddr = addr; +} + +/**************************************************************************** + * protected_mode_access( unsigned long mode, unsigned long width, + * unsigned long addr, unsigned char* pdata ) + * This function provides access to physical memory at the requested address. + * mode is: + * GX2_READ or GX2_WRITE (accesses a single byte, word or double + * word depending on the value of "width". Only 1, 2 or 4 supported). + * READ_BYTES, WRITE_BYTES accesses "width" number of bytes (8 bits) + * READ_WORDS, WRITE_WORDS accesses "width" number of words (16 bits) + * READ_DWORDS, WRITE_DWORDS accesses "width" number of dwords (32 bits) + * width is: The size of the access. For READ or WRITE, only 1, 2 and 4 are + * supported. For other modes, width is not limited but will cause + * paging if the block traverses page boundaries. + * addr is: The physical address being accessed + * pdata is: A pointer to the data to be read or written into. + * NOTE! WORD or DWORD accesses can only be made on WORD or DWORD boundaries! + ****************************************************************************/ +void +protected_mode_access(unsigned long mode, + unsigned long width, unsigned long addr, char *pdata) +{ + void *ptr = (void *)(FPBaseAddr + addr); + + /* type specific buffer pointers */ + char *byte_data = (char *)pdata; + unsigned long *word_data = (unsigned long *)pdata; + unsigned long *dword_data = (unsigned long *)pdata; + + if (mode == GX2_READ) { + switch (width) { + case FOUR_BYTES: + *(dword_data) = (unsigned long)(*(unsigned long *)ptr); + break; + case TWO_BYTES: + *(word_data) = (unsigned long)(*(unsigned long *)ptr); + break; + default: + *(byte_data) = (char)(*(char *)ptr); + break; + } + } /* end GX2_READ */ + else if (mode == GX2_WRITE) { + switch (width) { + case FOUR_BYTES: + *(unsigned long *)ptr = *dword_data; + break; + case TWO_BYTES: + *(unsigned long *)ptr = *word_data; + break; + default: + *(char *)ptr = *byte_data; + break; + } /* end switch(mode) */ + } + /* end case GX2_WRITE */ + return; + +} /* End of protected_mode_access. */ + +/************************************************************************* + * void write_video_reg64_low( unsigned long offset, unsigned long value ) + * Writes value to the low 32 bits of the 64 bit memory mapped video + * register indicated by offset. + * This function uses Sys_info.video_reg_base as the base address, so + * the value of offset should be with respect to this base. + *************************************************************************/ +void +write_video_reg64_low(unsigned long offset, unsigned long value) +{ + protected_mode_access(GX2_WRITE, FOUR_BYTES, + FPBaseAddr + offset, (char *)&value); +} /*end write_video_reg64_low() */ + +/************************************************************************* + * unsigned long read_video_reg64_low( unsigned long offset ) + * Returns the contents of the low 32 bits of the 64 bit memory mapped + * video register indicated by offset. + * This function uses Sys_info.video_reg_base as the base address, so + * the value of offset should be with respect to this base. + *************************************************************************/ +unsigned long +read_video_reg64_low(unsigned long offset) +{ + unsigned long data; + + protected_mode_access(GX2_READ, FOUR_BYTES, + FPBaseAddr + offset, (char *)&data); + return (data); +} /*end read_video_reg64_low() */ + +/******************************************************************************* + * void Redcloud_fp_reg( int mode, unsigned long address, unsigned long *data ) + * + * Writes and reads dwords to the Redcloud flat panel registers in the Redcloud + * Display Filter. There's no clock control, chip select or timing to deal with. + * This routine expects the actual GX2 macro definitions for the address. + * + * Parameters: + * mode: An integer value for a GX2_READ or GX2_WRITE operation + * 0 = GX2_Read and 1 = GX2_Write + * address: A dword value representing the offset of the register. + * data: A pointer to a dword value that is to be written in to + * the required register. In case of a Read operation this + * will point to the result of the Read operation. + * + *******************************************************************************/ +void +Redcloud_fp_reg(int mode, unsigned long address, unsigned long *data) +{ + if (mode == GX2_READ) { + *data = read_video_reg64_low(address); + } else { + write_video_reg64_low(address, *data); + } + +} /* End of Redcloud_fp_reg() */ + +/*------------------------------------------------------------------- + * + * SET_92XX_MODE_PARAMS + * This routine sets the 9211 mode parameters. + * + *-------------------------------------------------------------------*/ + +void +set_Redcloud_92xx_mode_params(int mode) +{ + CS92xx_MODE *pMode = &FPModeParams[mode]; + unsigned long temp_data = 0; + unsigned long base_data; + Q_WORD msrValue; + + /* on a Redcloud, we need to set up the DF pad select MSR */ + if (gfx_msr_read(RC_ID_DF, GX2_VP_MSR_PAD_SELECT, &msrValue) == FOUND) { + msrValue.low &= ~GX2_VP_PAD_SELECT_MASK; + if (pMode->panel_type == PNL_TFT || pMode->panel_type == PNL_TWOP) { + msrValue.low = GX2_VP_PAD_SELECT_TFT; + } else { + msrValue.low = GX2_VP_PAD_SELECT_DSTN; + } + gfx_msr_write(RC_ID_DF, GX2_VP_MSR_PAD_SELECT, &msrValue); + } + + /* Turn the 92xx power off before setting any new parameters. */ + temp_data = pMode->power_management & ~GX2_FP_PM_PWR_ON; + Redcloud_fp_reg(GX2_WRITE, GX2_FP_PWR_MAN, (unsigned long *)&temp_data); + + /* Set 9211 registers using the desired panel settings */ + + Redcloud_fp_reg(GX2_WRITE, GX2_FP_PAN_TIMING1, + (unsigned long *)&pMode->panel_timing1); + + /* On Redcloud, bit 31 is now reserved. */ + temp_data = pMode->panel_timing2 & 0x7FFFFFFF; + Redcloud_fp_reg(GX2_WRITE, GX2_FP_PAN_TIMING2, + (unsigned long *)&temp_data); + + /* On Redcloud TFT parts, set this to 0x70 so all 8 bits per color run + * thru fp crc but only non-TFT parts. Otherwise, set it to be 0x50. + * (source: Larry G.). + */ + if (pMode->panel_type == PNL_TFT || pMode->panel_type == PNL_TWOP) { + temp_data = GX2_FP_CRC_PASS_THRU_MASK; + } else { + temp_data = pMode->rev_C_dither_frc; + } + Redcloud_fp_reg(GX2_WRITE, GX2_FP_DITH_FR_CNTRL, + (unsigned long *)&temp_data); + Redcloud_fp_reg(GX2_WRITE, GX2_FP_BLFSR, + (unsigned long *)&pMode->blue_lsfr_seed); + Redcloud_fp_reg(GX2_WRITE, GX2_FP_RLFSR, + (unsigned long *)&pMode->red_green_lsfr_seed); + + /* Set the memory information, then the power register last. + * This will turn the panel on at the 9211. + */ + + Redcloud_fp_reg(GX2_READ, GX2_FP_FBB, (unsigned long *)&base_data); + if (base_data != 0x41780000) { + base_data = 0x41780000; + Redcloud_fp_reg(GX2_WRITE, GX2_FP_FBB, (unsigned long *)&base_data); + } + + Redcloud_fp_reg(GX2_WRITE, GX2_FP_PWR_MAN, + (unsigned long *)&pMode->power_management); + +} /*end set_92xx_mode_params() */ + +/* ----------------------------------------------------------------------- + * + * SET_FLAT_PANEL_MODE + * + * This routine sets the specified flat panel moden parameters in + * the 9211. + * Returns PASS if successful, FAIL if the mode parameters could + * not be set. + * + *------------------------------------------------------------------------*/ + +unsigned char +set_Redcloud_92xx_mode(Pnl_PanelStat * pstat) +{ + int mode; + + /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ + + for (mode = 0; mode < NUM_92XX_MODES; mode++) { + if ((FPModeParams[mode].xres == pstat->XRes) && + (FPModeParams[mode].yres == pstat->YRes) && + (FPModeParams[mode].bpp == pstat->Depth) && + (FPModeParams[mode].panel_type == pstat->Type) && + (FPModeParams[mode].color_type == pstat->MonoColor)) { + + /* SET THE 92xx FOR THE SELECTED MODE */ + set_Redcloud_92xx_mode_params(mode); + return TRUE; + } /* end if() */ + } /* end for() */ + return FALSE; + +} /* end set_Centaurus_92xx_mode() */ + +void +Redcloud_9211init(Pnl_PanelStat * pstat) +{ + + set_Redcloud_92xx_mode(pstat); + +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.h new file mode 100644 index 000000000..a545cb12b --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.h @@ -0,0 +1,207 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.h,v 1.3 2003/01/14 09:34:35 alanh Exp $ */ +/* + * $Workfile: gx2_9211.h $ + * + * This header file defines the pneumonics used when calling Durango routines. + * This file is automatically included by gfx_rtns.h + * + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for Durango + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for Durango + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* ----------------------------------------------------------- + * GX2 FLAT PANEL CONTROLLER REGISTER DEFINITIONS + *----------------------------------------------------------- + */ + +#define GX2_VP_MSR_PAD_SELECT 0x2011 +#define GX2_VP_PAD_SELECT_MASK 0x3FFFFFFF +#define GX2_VP_PAD_SELECT_TFT 0x1FFFFFFF +#define GX2_VP_PAD_SELECT_DSTN 0x00000000 + +/* This is useful for generating addresses incrementally + * (ie, vidtest register display code). + */ + +#define GX2_FP_LCD_OFFSET 0x00000400 +#define CS9211_REDCLOUD 0x0400 /* Moved 9211 Rev C3 up to next major no. */ + +#define GX2_FP_PAN_TIMING1 0x0400 /* FP timings 1 */ +#define GX2_FP_PAN_TIMING2 0x0408 /* FP timings 2 */ +#define GX2_FP_PWR_MAN 0x0410 /* FP power management */ +#define GX2_FP_DITH_FR_CNTRL 0x0418 /* FP dither and frame rate */ +#define GX2_FP_BLFSR 0x0420 /* Blue LFSR seed */ +#define GX2_FP_RLFSR 0x0428 /* Red and Green LFSR seed */ +#define GX2_FP_FMI 0x0430 /* FRM Memory Index */ +#define GX2_FP_FMD 0x0438 /* FRM Memory Data */ +#define GX2_FP_DCA 0x0448 /* Dither ram control and address */ +#define GX2_FP_DMD 0x0450 /* Dither memory data */ +#define GX2_FP_PAN_CRC_SIG 0x0458 /* FP CRC signature */ +#define GX2_FP_FBB 0x0460 /* Frame Buffer Base Address */ + +/* GX2_FP_PAN_TIMING2 bits */ + +#define GX2_FP_TFT_PASS_THRU 0x40000000 /* TFT pass through enable */ +#define GX2_FP_PT2_PIX_OUT_MASK 0xFFF8FFFF /* panel output bit formats */ +#define GX2_FP_PT2_PIX_OUT_TFT 0x00000000 /* 8 BIT DSTN or TFT panel */ +#define GX2_FP_PT2_COLOR_MONO 0x00080000 /* color or monochrome */ +#define GX2_FP_PT2_DSTN_TFT_MASK 0xFFCFFFFF /* panel type bits */ +#define GX2_FP_PT2_DSTN_TFT_TFT 0x00100000 /* TFT panel */ +#define GX2_FP_PT2_PSH_CLK_CTL 0x08000000 /* shift clock retrace activity control */ + +/* GX2_FP_PWR_MAN bits */ + +#define GX2_FP_PM_SHFCLK_INVERT 0x00002000 /* Invert shfclk to panel */ +#define GX2_FP_PM_VSYNC_DELAY 0x0000C000 /* Vert Sync delay */ +#define GX2_FP_PM_HSYNC_DELAY 0x00030000 /* Horiz Sync delay */ +#define GX2_FP_PM_PWRDN_PHASE_BIT0 0x00040000 /* panel power down phase bit 0 */ +#define GX2_FP_PM_PWRDN_PHASE_BIT1 0x00080000 /* panel power down phase bit 1 */ +#define GX2_FP_PM_PWRDN_PHASE_BIT2 0x00100000 /* panel power down phase bit 2 */ +#define GX2_FP_PM_PWRUP_PHASE_BIT0 0x00200000 /* panel power up phase bit 0 */ +#define GX2_FP_PM_PWRUP_PHASE_BIT1 0x00400000 /* panel power up phase bit 1 */ +#define GX2_FP_PM_PWRUP_PHASE_BIT2 0x00800000 /* panel power up phase bit 2 */ +#define GX2_FP_PM_PWR_ON 0x01000000 /* panel power ON */ +#define GX2_FP_PM_DIS_OFF_CTL 0x02000000 /* disable the panel back light */ +#define GX2_FP_PM_EXT_PWR_SEQ 0x08000000 /* external power sequence */ + +/* GX2_FP_PAN_CRC_SIG bits */ + +#define GX2_FP_PAN_CRC_SIGE 0x00000001 /* CRC Sig Enable */ +#define GX2_FP_PAN_CRC_SFR 0x00000002 /* CRC Sig Free Run */ + +/* This define is used by the hardware CRC mechanism */ +#define GX2_FP_CRC_PASS_THRU_MASK 0x00000070 + +#define GX2_READ 0 +#define GX2_WRITE 1 + +void SetFPBaseAddr(unsigned long); +void Redcloud_9211init(Pnl_PanelStat *); +void protected_mode_access(unsigned long mode, + unsigned long width, + unsigned long addr, char *pdata); +void write_video_reg64_low(unsigned long offset, unsigned long value); +unsigned long read_video_reg64_low(unsigned long offset); +void Redcloud_fp_reg(int mode, unsigned long address, unsigned long *data); +void set_Redcloud_92xx_mode_params(int mode); +unsigned char set_Redcloud_92xx_mode(Pnl_PanelStat * pstat); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/panel.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/panel.c new file mode 100644 index 000000000..78c931f55 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/panel.c @@ -0,0 +1,179 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/panel.c,v 1.3 2003/01/14 09:34:35 alanh Exp $ */ +/* + * $Workfile: panel.c $ + * $Revision: 1.2 $ + * + * File Contents: This file contains the file inclusions, macro definitions + * for the panel. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#if defined(linux) /* Linux */ + +#ifdef __KERNEL__ + +#include <linux/string.h> +#include <asm/io.h> + +#elif !defined(XFree86Server) + +#include <linux/fs.h> +#include <asm/mman.h> + +#endif /* __KERNEL__ */ +#elif defined(_WIN32) /* windows */ + +#include <windows.h> + +#endif + +#include "panel.h" +#include "gfx_defs.h" + +extern unsigned char *gfx_virt_regptr; +extern unsigned char *gfx_virt_fbptr; +extern unsigned char *gfx_virt_vidptr; +extern unsigned char *gfx_virt_vipptr; +extern unsigned long gfx_detect_video(void); + +#define PLATFORM_DYNAMIC 1 /* runtime selection */ +#define PLATFORM_DRACO 1 /* Draco + 9210 */ +#define PLATFORM_CENTAURUS 1 /* Centaurus + 9211 RevA */ +#define PLATFORM_DORADO 1 /* Dorado + 9211 RevC */ +#define PLATFORM_REDCLOUD 1 /* GX2 */ + +unsigned char *XpressROMPtr; + +#include "pnl_init.c" +#include "pnl_bios.c" diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/panel.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/panel.h new file mode 100644 index 000000000..e16d71d55 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/panel.h @@ -0,0 +1,190 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/panel.h,v 1.3 2003/01/14 09:34:36 alanh Exp $ */ +/* + * $Workfile: panel.h $ + * $Revision: 1.2 $ + * + * File Contents: This file contains the Geode frame buffer panel + * functions prototypes and it includes panel + * definitions header file. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +/* COMPILER OPTION FOR C++ PROGRAMS */ + +#ifndef _panel_h +#define _panel_h + +#include "pnl_defs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* CLOSE BRACKET FOR C++ COMPLILATION */ + + void Pnl_SetPlatform(int platform); + int Pnl_GetPlatform(void); + int Pnl_IsPanelPresent(void); + void Pnl_SetPanelPresent(int present); + void Pnl_SetPanelChip(int panelChip); + int Pnl_GetPanelChip(void); + void Pnl_SetPanelParam(PPnl_PanelParams pParam); + void Pnl_GetPanelParam(PPnl_PanelParams pParam); + int Pnl_InitPanel(PPnl_PanelParams pParam); + int Detect_Platform(void); + void Pnl_SavePanelState(void); + void Pnl_RestorePanelState(void); + void Pnl_PowerUp(void); + void Pnl_PowerDown(void); + + int Pnl_IsPanelEnabledInBIOS(void); + void Pnl_GetPanelInfoFromBIOS(int *xres, int *yres, int *bpp, int *hz); +/* from durango */ + +#if defined(_WIN32) /* windows */ + extern void gfx_delay_milliseconds(unsigned long milliseconds); + extern unsigned long gfx_ind(unsigned short port); + extern void gfx_outd(unsigned short port, unsigned long data); + extern unsigned char gfx_inb(unsigned short port); + extern void gfx_outb(unsigned short port, unsigned char data); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !_panel_h */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/platform.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/platform.c new file mode 100644 index 000000000..f3166518b --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/platform.c @@ -0,0 +1,726 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/platform.c,v 1.3 2003/01/14 09:34:36 alanh Exp $ */ +/* + * $Workfile: platform.c $ + * $Revision: 1.2 $ + * + * File Contents: This file contains platform dependent functions + * which provide interface to that platform. + * + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#define LINUX_ROM_SEGMENT 0x000F +#define SEGMENT_LENGTH 0xFFFF +#define PAGE_LENGTH 0x1000 +#define SYS_BOARD_NAME_LEN 24 + +#define PLT_READ 0 +#define PLT_WRITE 1 +#define PLT_WRITE_BYTES 2 +#define PLT_READ_BYTES 3 +#define PLT_WRITE_WORDS 4 +#define PLT_READ_WORDS 5 +#define PLT_WRITE_DWORDS 6 +#define PLT_READ_DWORDS 7 +#define PLT_UNKNOWN 0xFFFF + +typedef struct +{ + char sys_board_name[SYS_BOARD_NAME_LEN]; + SYS_BOARD sys_board; +} +SYS_BOARD_INFO; + +static SYS_BOARD_INFO Sys_info; + +/* + * The names in the sys_board_name string must exactly match the names in the + * BIOS header. These names are used by FindStringInSeg() to find the names + * in the BIOS header space. The BIOS does not use OTHER; it is a dummy value + * for program useonly. + * + */ + +SYS_BOARD_INFO Sys_board_info_array[] = { + {"Marmot", MARMOT_PLATFORM}, + {"Unicorn", UNICORN_PLATFORM}, + {"Centaurus", CENTAURUS_PLATFORM}, + {"Aries", ARIES_PLATFORM}, + {"Carmel", CARMEL_PLATFORM}, + {"Hyrda", HYDRA_PLATFORM}, + {"Dorado", DORADO_PLATFORM}, + {"Redcloud", REDCLOUD_PLATFORM}, + {"Other", OTHER_PLATFORM} +}; + +#define NUM_SYS_BOARD_TYPES sizeof(Sys_board_info_array)/sizeof(SYS_BOARD_INFO) + +static int Num_sys_board_type = NUM_SYS_BOARD_TYPES; +SYS_BOARD_INFO *Sys_board_array_base = Sys_board_info_array; +int FindStringInSeg(unsigned int, char *); +static unsigned char get_sys_board_type(SYS_BOARD_INFO *, SYS_BOARD_INFO *); + +#if defined(linux) && !defined(__KERNEL__) +#if !defined(XFree86Server) +static void protected_mode_access(unsigned int, unsigned int, + unsigned long, unsigned char *); +static void setup_pma(); +static void close_pma(); +static int fd; +#endif /* IN_MODULE */ +#endif /* __KERNEL__ */ + +/* Detect the Platform */ +int +Detect_Platform(void) +{ +#if defined(linux) && !defined(__KERNEL__) +#if !defined(XFree86Server) + setup_pma(); +#endif /* IN_MODULE */ +#endif /* __KERNEL__ */ + + /* See if we can find the board name using Xpressrom */ + if (get_sys_board_type(&Sys_info, Sys_board_array_base) == TRUE) { +#if 0 + if (Sys_info.sys_board == CENTAURUS_PLATFORM) { + printk("CENTAURUS Platform Found\n"); + } else if (Sys_info.sys_board == DORADO_PLATFORM) { + printk("DORADO Platform Found \n"); + } else { + printk("UNKNOWN Platform Found \n"); + } +#endif + } +#if defined(linux) && !defined(__KERNEL__) +#if !defined(XFree86Server) + close_pma(); +#endif /* IN_MODULE */ +#endif /* __KERNEL__ */ + + return (Sys_info.sys_board); +} + +static int +Strncmp(char *str1, char *str2, int len) +{ + int i; + + if ((str1 == 0x0) || (str2 == 0x0) || (len == 0)) + return (1); + for (i = 0; i < len; i++) { + if (*(str1 + i) > *(str2 + i)) { + return 1; + } else if (*(str1 + i) < *(str2 + i)) { + return -1; + } + } + return 0; +} + +static char * +Strcpy(char *dst, char *src) +{ + int i; + + if ((dst == 0x0) || (src == 0x0)) + return (0); + for (i = 0; src[i] != 0x0; i++) { + dst[i] = src[i]; + } + dst[i] = 0x0; /* NULL termination */ + return dst; +} + +static int +Strlen(char *str) +{ + int i; + + if (str == 0x0) + return 0; + for (i = 0; str[i] != 0x0; i++) ; + return i; +} + +/***********************************************************************/ + +/* Platform Detection Code */ + +/***********************************************************************/ + +/************************************************************************ + * int FindStringInSeg( unsigned int segment_address, char *string_ptr ) + * Returns the offset where the NULL terminated string pointed to by + * string_ptr is located in the segment passed in segment_address. + * Segment_address must be of the form 0xXXXX (i.e 0xf000 for segment f). + * Returns NULL if the string is not found. + ************************************************************************ + */ +int +FindStringInSeg(unsigned int segment_address, char *string_ptr) +{ + int string_length = Strlen(string_ptr); + char *psegment_buf; + unsigned long mem_ptr = (unsigned long)segment_address << 16; + char segment_buffer[SEGMENT_LENGTH + 1]; + int i, cursor; + + /* silence compiler */ + (void)cursor; + (void)mem_ptr; + (void)segment_buffer; + +#if defined(linux) && !defined(XFree86Server) +#ifdef __KERNEL__ + XpressROMPtr = (unsigned char *)ioremap(mem_ptr, SEGMENT_LENGTH + 1); + psegment_buf = (char *)XpressROMPtr; +#else + /* Fill the segment_buffer with 16 page accesses */ + + for (cursor = 0; (cursor * PAGE_LENGTH) < SEGMENT_LENGTH; cursor++) { + protected_mode_access(PLT_READ_BYTES, PAGE_LENGTH, mem_ptr + + (cursor * PAGE_LENGTH), + &(segment_buffer[(cursor * PAGE_LENGTH)])); + } + psegment_buf = segment_buffer; +#endif /* __KERNEL__ */ +#elif defined (XFree86Server) + psegment_buf = (char *)XpressROMPtr; +#elif defined(_WIN32) /* Windows */ + psegment_buf = XpressROMPtr; +#endif + + /* Now search for the first character of the string_ptr */ + for (i = 0; i < SEGMENT_LENGTH + 1; i++) { + if (*(psegment_buf + i) == *string_ptr) { + + /* If we match the first character, do a + * string compare. + */ + + if (!Strncmp(string_ptr, (psegment_buf + i), string_length)) { + /* They match! */ + return (1); + } + } + } + /* if we got this far we didn't find anything. Return NULL. */ + return (0); + +} /* end FindStringInSeg() */ + +/********************************************************************** + + * TRUE_FALSE get_sys_board_type( SYS_BOARD_INFO *sys_info, + * SYS_BOARD_INFO *sys_board_array_base) Checks the system + * BIOS area for Xpressrom information. If found, searches the BIOS + * area for one of names in the array pointed to by sys_board_array_ptr. + * If a match is found, sets the SYS_INFO system_board_name string + * and the system_board variable to the board name and returns TRUE. + * If Xpressrom or a board is not found, sets the variables to + * their default values and returns FALSE. + * Uses the global string pointer *xpress_rom_string_ptr. + * + *********************************************************************** + */ + +static unsigned char +get_sys_board_type(SYS_BOARD_INFO * sys_info, + SYS_BOARD_INFO * sys_board_array_base) +{ + int index; + char *xpress_rom_string_ptr = "XpressStart"; + unsigned int segment = LINUX_ROM_SEGMENT; + + /* See if XpressStart is present in the BIOS area. + * If it is, search for a board string. If not, Xpressrom is + * not present, set system_board information to UNKNOWN and + * return FALSE. + */ + + if (!FindStringInSeg(segment, xpress_rom_string_ptr)) { + sys_info->sys_board = PLT_UNKNOWN; + Strcpy(sys_info->sys_board_name, "Unknown"); + return (FALSE); + } else { + + /* we have Xpressrom, so look for a board */ + for (index = 0; index < Num_sys_board_type; index++) { + if (!FindStringInSeg(segment, (sys_board_array_base + + index)->sys_board_name)) { + continue; + } else { + + /* a match!! */ + sys_info->sys_board = (sys_board_array_base + index)->sys_board; + Strcpy(sys_info->sys_board_name, + (sys_board_array_base + index)->sys_board_name); + return (TRUE); + } + } /* end for() */ + } /* end else */ + + /* if we are here we have failed */ + sys_info->sys_board = PLT_UNKNOWN; + Strcpy(sys_info->sys_board_name, "Unknown"); + return (FALSE); +} /* end get_sys_board_type() */ + +#if defined(linux) && !defined(__KERNEL__) +#if !defined(XFree86Server) + +/****************************************************************** + * + * protected_mode_access( unsigned int mode, unsigned int width, + * unsigned long addr, unsigned char* pdata ) + * This function provides access to physical memory + * at the requested address. + * mode is: PLT_READ or PLT_WRITE (accesses a single byte, word + * or double word depending on the value of "width". + * Only 1, 2 or 4 supported). + * PLT_READ_BYTES, PLT_WRITE_BYTES accesses "width" number + * of bytes (8 bits) + * PLT_READ_WORDS, PLT_WRITE_WORDS accesses "width" number + * of words (16 bits) PLT_READ_DWORDS, PLT_WRITE_DWORDS accesses + * "width" number of dwords (32 bits) + * width is: The size of the access. + * For PLT_READ or PLT_WRITE, only 1, 2 and 4 are + * supported. For other modes, width is not limited but + * will cause paging if the block traverses page boundaries. + * addr is: The physical address being accessed + * pdata is: A pointer to the data to be read or written into. + * NOTE! WORD or DWORD accesses can only be made on + * WORD or DWORD boundaries! + * + ****************************************************************** + */ + +static void +protected_mode_access(unsigned int mode, unsigned int width, + unsigned long addr, unsigned char *pdata) +{ + +#define PMTRASH 0x12345678L + + unsigned long base; /* The physical page address */ + int length = 0x1000; /* the page size is 4k */ + unsigned int offset = 0; /* The physical addr offset into page */ + unsigned int index = 0; /* Used to read/write from/to a block */ + unsigned int chunk = 0; /* The amount to read/wr from THIS block */ + unsigned int size = 0; /* Data size shift value (to avoid math) */ + static void *ptr; /* pointer to real memory location. */ + + static unsigned long lastbase = PMTRASH; + + /* temp storage of previous base used. */ + /* type specific buffer pointers */ + unsigned char *byte_data = (unsigned char *)pdata; + unsigned int *word_data = (unsigned int *)pdata; + unsigned long *dword_data = (unsigned long *)pdata; + + switch (mode) { + + case PLT_READ_WORDS: + case PLT_WRITE_WORDS: + + size = 1; + break; + + case PLT_READ_DWORDS: + case PLT_WRITE_DWORDS: + + size = 2; + } + + /* Check if we're in the user accessable range */ + if (addr < 0xFF000000L) { + + /* We get physical memory in "pages", defined by the + * following "base" address and the "offset" into it. + * "base" will be used with mmap to get "ptr", which + * points to the memory mapped actual physical memory at + * the address pointed-to by "base". + * "width" and "chunk" are in units of whatever data + * type we're reading. + * "length" and "offset" are in units of bytes. + * "width" and "chunk" must be adjusted with "<<size" + * to use with "length" or "offset". Similarly, the + * result must be adjusted with ">>size" to make into the + * proper type units when done. + */ + base = addr & 0xFFFFF000L; + offset = addr & 0x00000FFFL; + do { + if ((offset + (width << size)) > length) { + + /* Block being read extends beyond the + * page boundary. Adjust things. + */ + chunk = (length - offset) >> size; + + /* Figure the chunk size */ + width -= chunk; + + /* Reduce width by the current chunk */ + } else { + + /* Block being read is within the + * page boundary. + */ + chunk = width; + width = 0; + + /* set to zero so we'll exit at the end */ + + } + /* We keep the page around in case we need to + * access it again. + * This saves us some time if we have consecutive + * accesses. + */ + + if (base != lastbase) { + + /* we haven't mmap'd this address + * Have to get a new page. Free the + * previous page, if it's valid (ie, not + * PMTRASH). If not, unmap it and get the + * new page. + */ + if (lastbase != PMTRASH) + munmap(ptr, length); + ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, + base); + if ((int)ptr == -1) { + lastbase = PMTRASH; + return; /* error */ + } + } + + /* Now we're ready to get the data. + * It's pure memory access now, no funny + * function calls, however we do cast things to get + * the right size data. + */ + + /* Scale the offset for the data type size */ + index = offset >> size; + + /* Note that the above line and below lines, + * which shift "offset", discard address information + * if you happen to be trying to write, for example, + * dwords on non-dword boundaries. + */ + /* Note that cases PLT_READ and PLT_WRITE don't + * use "index". They shift "offset" on their own. + * This is because in PLT_READ and PLT_WRITE modes, + * the information on the size of the data + * transaction is in the "width" variable not "size". + * We also need separate cases to cast the values + * right. + */ + switch (mode) { + + case PLT_READ:{ + + switch (chunk) { + + case FOUR_BYTES: + + *(dword_data) = (unsigned long) + (*(((unsigned long *)ptr) + (offset >> 2))); + break; + + case TWO_BYTES: + + *(word_data) = (unsigned int) + (*(((unsigned int *)ptr) + (offset >> 1))); + break; + + default: + + *(byte_data) = (unsigned char) + (*(((unsigned char *)ptr) + (offset))); + break; + + } /* end switch() */ + break; + + } /* end case PLT_READ */ + + case PLT_WRITE:{ + + switch (chunk) { + + case FOUR_BYTES: + + *(((unsigned long *)ptr) + (offset >> 2)) = *dword_data; + break; + + case TWO_BYTES: + + *(((unsigned int *)ptr) + (offset >> 1)) = *word_data; + break; + + default: + + *(((unsigned char *)ptr) + (offset)) = *byte_data; + break; + } /* end switch() */ + break; + + } /* end case PLT_WRITE */ + + case PLT_READ_BYTES:{ + + for (; chunk > 0; chunk--) { + + *(byte_data++) = (unsigned char)(*(((unsigned char *)ptr) + + (index++))); + } + break; + } /* end case PLT_READ_BYTES */ + + case PLT_WRITE_BYTES:{ + + for (; chunk > 0; chunk--) { + *(((unsigned char *)ptr) + (index++)) = *(byte_data++); + } + break; + + } /* end case PLT_WRITE_BYTES */ + + case PLT_READ_WORDS:{ + + for (; chunk > 0; chunk--) { + + *(word_data++) = (unsigned int) + (*(((unsigned int *)ptr) + (index++))); + } + break; + + } /* end case PLT_READ_WORDS */ + + case PLT_WRITE_WORDS:{ + + for (; chunk > 0; chunk--) { + + *(((unsigned int *)ptr) + (index++)) = *(word_data++); + } + break; + + } /* end case PLT_WRITE_WORDS */ + + case PLT_READ_DWORDS:{ + + for (; chunk > 0; chunk--) { + + *(dword_data++) = (*(((unsigned long *)ptr) + (index++))); + } + break; + + } /* end case PLT_READ_DWORDS */ + + case PLT_WRITE_DWORDS:{ + + for (; chunk > 0; chunk--) { + + *(((unsigned long *)ptr) + (index++)) + = *(dword_data++); + } + break; + + } /* end case PLT_WRITE_DWORDS */ + + } /* end switch(mode) */ + + lastbase = base; + + /* Save the page we've just processed. */ + + if (width) { + + /* If there's still width left to get. */ + + base += length; + /* Increment to the next page. */ + + offset = 0; + /* Set the offset to zero. */ + } + + } while (width); /* While there's still data to get. */ + return; + + } /* end for if addr */ + else { + + printf("PMA error: Unable to read ROM address space\n"); + exit(1); + } + return; +} + +/************************************************************************ + * setup_pma() loads the ROM memory access module and initializes + * memory access file descriptor (access is handled through a file-like + * interface). + ************************************************************************ + */ +static void +setup_pma() +{ + fd = open("/dev/mem", 2); /* O_RDWR */ + if (fd == -1) { + + printf("Error: Unable to open /dev/mem !\a\n"); + exit(1); + } + return; +} + +/********************************************************************** + * close_pma() cleans up the open memory access devices and file + * descriptors. + ********************************************************************** + */ +static void +close_pma() +{ + close(fd); + return; +} +#endif /* IN_MODULE */ +#endif /* linux && !__KERNEL__ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_bios.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_bios.c new file mode 100644 index 000000000..97739638f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_bios.c @@ -0,0 +1,377 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_bios.c,v 1.3 2003/01/14 09:34:36 alanh Exp $ */ +/* + * $Workfile: pnl_bios.c $ + * $Revision: 1.2 $ + * + * File Contents: This file panel functions which query for the BIOS for current FP + * Paramters. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "panel.h" + +#if defined(_WIN32) /* windows */ +extern unsigned long gfx_cpu_version; +extern void gfx_outw(unsigned short port, unsigned short data); +extern unsigned short gfx_inw(unsigned short port); +#endif + +#define SOFTVGA_DISPLAY_ENABLE 0x50 +#define SOFTVGA_FPRESOLUTION 0x52 +#define SOFTVGA_FPCLOCKFREQUENCY 0x54 + +/* SOFTVG VIRTUAL REGISTER DEFINITIONS */ + +#define VR_INDEX 0xAC1C +#define VR_DATA 0xAC1E +#define VR_UNLOCK 0xFC53 +#define VRC_VG 0x0002 /* SoftVG Virtual Register Class */ +#define VG_MEM_SIZE 0x0000 /* MemSize Virtual Register */ +#define FP_DETECT_MASK 0x8000 + +#define VG_FP_TYPE 0x0002 /* Flat Panel Info Virtual Register */ + +#define FP_DEV_MASK 0x0003 /* Flat Panel type */ +#define FP_TYPE_SSTN 0x0000 /* SSTN panel type value */ +#define FP_TYPE_DSTN 0x0001 /* DSTN panel type value */ +#define FP_TYPE_TFT 0x0002 /* TFT panel type value */ +#define FP_TYPE_LVDS 0x0003 /* LVDS panel type value */ + +#define FP_RESOLUTION_MASK 0x0038 +#define FP_RES_6X4 0x0000 /* 640x480 resolution value */ +#define FP_RES_8X6 0x0008 /* 800x600 resolution value */ +#define FP_RES_10X7 0x0010 /* 1024x768 resolution value */ +#define FP_RES_12X10 0x0018 /* 1280x1024 resolution value */ +#define FP_RES_16X12 0x0020 /* 1600x1200 resolution value */ + +#define FP_WIDTH_MASK 0x01C0 +#define FP_WIDTH_8 0x0000 /* 8 bit data bus width */ +#define FP_WIDTH_9 0x0040 /* 9 bit data bus width */ +#define FP_WIDTH_12 0x0080 /* 12 bit data bus width */ +#define FP_WIDTH_18 0x00C0 /* 18 bit data bus width */ +#define FP_WIDTH_24 0x0100 /* 24 bit data bus width */ +#define FP_WIDTH_16 0x0140 /* 16 bit data bus width - 16 bit Mono DSTN only */ + +#define FP_COLOR_MASK 0x0200 +#define FP_COLOR_COLOR 0x0000 /* Color panel */ +#define FP_COLOR_MONO 0x0200 /* Mono Panel */ + +#define FP_PPC_MASK 0x0400 +#define FP_PPC_1PPC 0x0000 /* One pixel per clock */ +#define FP_PPC_2PPC 0x0400 /* Two pixels per clock */ + +#define FP_HPOL_MASK 0x0800 +#define FP_H_POL_LGH 0x0000 /* HSync at panel, normally low, active high */ +#define FP_H_POL_HGL 0x0800 /* HSync at panel, normally high, active low */ + +#define FP_VPOL_MASK 0x1000 +#define FP_V_POL_LGH 0x0000 /* VSync at panel, normally low, active high */ +#define FP_V_POL_HGL 0x1000 /* VSync at panel, normally high, active low */ + +#define FP_REF_MASK 0xD000 +#define FP_REF_60 0x0000 /* 60Hz refresh rate */ +#define FP_REF_65 0x2000 /* 65Hz refresh rate */ +#define FP_REF_70 0x4000 /* 70Hz refresh rate */ +#define FP_REF_72 0x6000 /* 72Hz refresh rate */ +#define FP_REF_75 0x8000 /* 75Hz refresh rate */ +#define FP_REF_85 0xA000 /* 85Hz refresh rate */ + +/*----------------------------------------------------------------- + * Pnl_IsPanelEnabledInBIOS + * + * Description: This function specifies whether the panel is enabled + * by the BIOS or not. + * parameters: none. + * return: 1 - Enabled, 0 - Disabled + *-----------------------------------------------------------------*/ +int +Pnl_IsPanelEnabledInBIOS(void) +{ + unsigned char ret = 0; + + if ((gfx_cpu_version & 0xFF) == GFX_CPU_REDCLOUD) { + unsigned short data; + + gfx_outw(VR_INDEX, VR_UNLOCK); + gfx_outw(VR_INDEX, (VRC_VG << 8) | VG_MEM_SIZE); + data = gfx_inw(VR_DATA); + if (data & FP_DETECT_MASK) + ret = 1; + } else { + unsigned short crtcindex, crtcdata; + + crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + /* CHECK DisplayEnable Reg in SoftVGA */ + + gfx_outb(crtcindex, (unsigned char)SOFTVGA_DISPLAY_ENABLE); + ret = gfx_inb(crtcdata); + } + + return (ret & 0x1); +} + +/*----------------------------------------------------------------- + * Pnl_GetPanelInfoFromBIOS + * + * Description: This function queries the panel information from + * the BIOS. + * parameters: + * xres: width of the panel configured + * yres: height of the panel configured + * bpp: depth of the panel configured + * hz: vertical frequency of the panel configured + * return: none + *-----------------------------------------------------------------*/ +void +Pnl_GetPanelInfoFromBIOS(int *xres, int *yres, int *bpp, int *hz) +{ + unsigned short crtcindex, crtcdata; + unsigned short ret; + + if ((gfx_cpu_version & 0xFF) == GFX_CPU_REDCLOUD) { + gfx_outw(VR_INDEX, VR_UNLOCK); + gfx_outw(VR_INDEX, (VRC_VG << 8) | VG_FP_TYPE); + ret = gfx_inw(VR_DATA); + switch (ret & FP_RESOLUTION_MASK) { + case FP_RES_6X4: + *xres = 640; + *yres = 480; + break; + case FP_RES_8X6: + *xres = 800; + *yres = 600; + break; + case FP_RES_10X7: + *xres = 1024; + *yres = 768; + break; + case FP_RES_12X10: + *xres = 1280; + *yres = 1024; + break; + case FP_RES_16X12: + *xres = 1600; + *yres = 1200; + break; + } + + switch (ret & FP_WIDTH_MASK) { + case FP_WIDTH_8: + *bpp = 8; + break; + case FP_WIDTH_9: + *bpp = 9; + break; + case FP_WIDTH_12: + *bpp = 12; + break; + case FP_WIDTH_18: + *bpp = 18; + break; + case FP_WIDTH_24: + *bpp = 24; + break; + case FP_WIDTH_16: + *bpp = 16; + break; + } + + switch (ret & FP_REF_MASK) { + case FP_REF_60: + *hz = 60; + break; + case FP_REF_65: + *hz = 65; + break; + case FP_REF_70: + *hz = 70; + break; + case FP_REF_72: + *hz = 72; + break; + case FP_REF_75: + *hz = 75; + break; + case FP_REF_85: + *hz = 85; + break; + } + + } else { + crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; + crtcdata = crtcindex + 1; + + /* CHECK FPResolution Reg in SoftVGA */ + + gfx_outb(crtcindex, (unsigned char)SOFTVGA_FPRESOLUTION); + ret = gfx_inb(crtcdata); + + switch (ret & 0x3) { + case 0: + *xres = 640; + *yres = 480; + break; + case 1: + *xres = 800; + *yres = 600; + break; + case 2: + *xres = 1024; + *yres = 768; + break; + } + + switch ((ret >> 4) & 0x3) { + case 0: + *bpp = 12; + break; + case 1: + *bpp = 18; + break; + case 2: + *bpp = 16; + break; + case 3: + *bpp = 8; + break; + } + + /* CHECK FPClockFrequency Reg in SoftVGA */ + + gfx_outb(crtcindex, (unsigned char)SOFTVGA_FPCLOCKFREQUENCY); + *hz = gfx_inb(crtcdata); + } +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_defs.h b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_defs.h new file mode 100644 index 000000000..37a37c712 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_defs.h @@ -0,0 +1,203 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_defs.h,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/* + * $Workfile: pnl_defs.h $ + * + * File Contents: This file contains definitions of the Geode + * frame buffer panel data structures. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#ifndef _pnl_defs_h +#define _pnl_defs_h + +typedef enum +{ + MARMOT_PLATFORM = 0, + UNICORN_PLATFORM, + CENTAURUS_PLATFORM, + ARIES_PLATFORM, + CARMEL_PLATFORM, + HYDRA_PLATFORM, + DORADO_PLATFORM, + DRACO_PLATFORM, + REDCLOUD_PLATFORM, + OTHER_PLATFORM +} +SYS_BOARD; + +#define PNL_9210 0x01 +#define PNL_9211_A 0x02 +#define PNL_9211_C 0x04 +#define PNL_UNKNOWN_CHIP 0x08 + +#define PNL_TFT 0x01 +#define PNL_SSTN 0x02 +#define PNL_DSTN 0x04 +#define PNL_TWOP 0x08 +#define PNL_UNKNOWN_PANEL 0x10 + +#define PNL_MONO_PANEL 0x01 +#define PNL_COLOR_PANEL 0x02 +#define PNL_UNKNOWN_COLOR 0x08 + +#define PNL_PANELPRESENT 0x01 +#define PNL_PLATFORM 0x02 +#define PNL_PANELCHIP 0x04 +#define PNL_PANELSTAT 0x08 +#define PNL_OVERRIDE_STAT 0x10 +#define PNL_OVERRIDE_ALL 0x1F + +typedef struct _Pnl_PanelStat_ +{ + int Type; + int XRes; + int YRes; + int Depth; + int MonoColor; +} +Pnl_PanelStat; + +typedef struct _Pnl_Params_ +{ + unsigned long Flags; + int PanelPresent; + int Platform; + int PanelChip; + Pnl_PanelStat PanelStat; +} +Pnl_PanelParams, *PPnl_PanelParams; + +#endif /* _pnl_defs_h */ + +/* END OF FILE */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_init.c b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_init.c new file mode 100644 index 000000000..9cd4e71d9 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_init.c @@ -0,0 +1,613 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/pnl_init.c,v 1.1 2002/12/10 15:12:28 alanh Exp $ */ +/* + * $Workfile: pnl_init.c $ + * $Revision: 1.2 $ + * + * File Contents: This file contains the Geode frame buffer panel + * intialization functions. + * + * SubModule: Geode FlatPanel library + * + */ + +/* + * NSC_LIC_ALTERNATIVE_PREAMBLE + * + * Revision 1.0 + * + * National Semiconductor Alternative GPL-BSD License + * + * National Semiconductor Corporation licenses this software + * ("Software"): + * + * Panel Library + * + * under one of the two following licenses, depending on how the + * Software is received by the Licensee. + * + * If this Software is received as part of the Linux Framebuffer or + * other GPL licensed software, then the GPL license designated + * NSC_LIC_GPL applies to this Software; in all other circumstances + * then the BSD-style license designated NSC_LIC_BSD shall apply. + * + * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ + +/* NSC_LIC_BSD + * + * National Semiconductor Corporation Open Source License for + * + * Panel Library + * + * (BSD License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the National Semiconductor Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * END_NSC_LIC_BSD */ + +/* NSC_LIC_GPL + * + * National Semiconductor Corporation Gnu General Public License for + * + * Panel Library + * + * (GPL License with Export Notice) + * + * Copyright (c) 1999-2001 + * National Semiconductor Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted under the terms of the GNU General + * Public License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version + * + * In addition to the terms of the GNU General Public License, neither + * the name of the National Semiconductor Corporation nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, + * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. See the GNU General Public License for more details. + * + * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF + * YOUR JURISDICTION. It is licensee's responsibility to comply with + * any export regulations applicable in licensee's jurisdiction. Under + * CURRENT (2001) U.S. export regulations this software + * is eligible for export from the U.S. and can be downloaded by or + * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed + * destinations which include Cuba, Iraq, Libya, North Korea, Iran, + * Syria, Sudan, Afghanistan and any other country to which the U.S. + * has embargoed goods and services. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * END_NSC_LIC_GPL */ + +#include "panel.h" +#include "gfx_regs.h" +#include "gfx_type.h" + +/* defaults +Panel : Enabled +Platform : Centaurus +92xx Chip : 9211 Rev. A +PanelType : DSTN +XResxYRes : 800x600 +Depth : 16 +Mono_Color : Color +*/ +static Pnl_PanelParams sPanelParam = { + 0, 1, CENTAURUS_PLATFORM, PNL_9211_A, + {PNL_DSTN, 800, 600, 16, PNL_COLOR_PANEL} +}; + +#if PLATFORM_DRACO +#include "drac9210.c" +#endif + +#if PLATFORM_CENTAURUS +#include "cen9211.c" +#endif + +#if PLATFORM_DORADO +#include "dora9211.c" +#endif + +#if PLATFORM_GX2BASED +#include "gx2_9211.c" +#endif +#include "platform.c" + +/* + * return -1 - UnKnown + * 0 - Draco has 9210 + * 1 - Centaurus has 9211 Rev. A + * 2 - Dorado has 9211 Rev. C + */ + +/*----------------------------------------------------------------- + * Pnl_SetPlatform + * + * Description: This function sets the panel with hardware platform. + * parameters: + * platform: It specify the platform. + * return: none. + *-----------------------------------------------------------------*/ +void +Pnl_SetPlatform(int platform) +{ + /* To Be Implemented */ + sPanelParam.Platform = platform; + +} + +/*----------------------------------------------------------------- + * Pnl_GetPlatform + * + * Description: This function returns the panel platform. + * parameters: none. + * return: On success it returns the panel platform. + *-----------------------------------------------------------------*/ +int +Pnl_GetPlatform(void) +{ + sPanelParam.Platform = Detect_Platform(); + + return sPanelParam.Platform; + +} + +/*----------------------------------------------------------------- + * Pnl_IsPanelPresent + * + * Description: This function specifies whether the panel is prsent + * or not. + * parameters: none. + * return: On success it returns an integer panel present value. + *-----------------------------------------------------------------*/ +int +Pnl_IsPanelPresent(void) +{ + /* To Be Implemented */ + return sPanelParam.PanelPresent; +} + +/*----------------------------------------------------------------- + * Pnl_SetPanelPresent + * + * Description: This function sets the panel_present parameter. + * parameters: + * present: It specifies the panel present value. + * return: none. + *-----------------------------------------------------------------*/ +void +Pnl_SetPanelPresent(int present) +{ + /* To Be Implemented */ + sPanelParam.PanelPresent = present; +} + +/*----------------------------------------------------------------- + * Pnl_SetPanelParam + * + * Description: This function sets the panel parameters + * parameters: + * pParam: It specifies the elements of the panel parameter + * structure. + * return: none. + *-----------------------------------------------------------------*/ +void +Pnl_SetPanelParam(PPnl_PanelParams pParam) +{ + if (pParam->Flags & PNL_PANELPRESENT) { + Pnl_SetPanelPresent(pParam->PanelPresent); + } + if (pParam->Flags & PNL_PLATFORM) { + Pnl_SetPlatform(pParam->Platform); + } + if (pParam->Flags & PNL_PANELCHIP) { + Pnl_SetPanelChip(pParam->PanelChip); + } + if (pParam->Flags & PNL_PANELSTAT) { + sPanelParam.PanelStat.XRes = pParam->PanelStat.XRes; + sPanelParam.PanelStat.YRes = pParam->PanelStat.YRes; + sPanelParam.PanelStat.Depth = pParam->PanelStat.Depth; + sPanelParam.PanelStat.MonoColor = pParam->PanelStat.MonoColor; + sPanelParam.PanelStat.Type = pParam->PanelStat.Type; + } +} + +/*----------------------------------------------------------------- + * Pnl_PowerUp + * + * Description: This function sets the power based on the + * hardware platforms dorado or centaraus. + * parameters: none. + * return: none. + *-----------------------------------------------------------------*/ +void +Pnl_PowerUp(void) +{ + int Platform; + unsigned long dcfg, hw_video; + + Platform = Pnl_GetPlatform(); + +#if PLATFORM_CENTAURUS + if (Platform == CENTAURUS_PLATFORM) { + Centaurus_Power_Up(); + return; + } +#endif + +#if PLATFORM_DORADO + if (Platform == DORADO_PLATFORM) { + Dorado_Power_Up(); + return; + } +#endif + +#if PLATFORM_GX2BASED + if (Platform == REDCLOUD_PLATFORM) { + } +#endif + + hw_video = gfx_detect_video(); + + if (hw_video == GFX_VID_CS5530) { + /* READ DISPLAY CONFIG FROM CX5530 */ + dcfg = READ_VID32(CS5530_DISPLAY_CONFIG); + + /* SET RELEVANT FIELDS */ + dcfg |= (CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN); + /* Enable the flatpanel power and data */ + WRITE_VID32(CS5530_DISPLAY_CONFIG, dcfg); + } else if (hw_video == GFX_VID_SC1200) { + /* READ DISPLAY CONFIG FROM SC1200 */ + dcfg = READ_VID32(SC1200_DISPLAY_CONFIG); + + /* SET RELEVANT FIELDS */ + dcfg |= (SC1200_DCFG_FP_PWR_EN | SC1200_DCFG_FP_DATA_EN); + /* Enable the flatpanel power and data */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg); + } else if (hw_video == GFX_VID_REDCLOUD) { + /* READ DISPLAY CONFIG FROM REDCLOUD */ + dcfg = READ_VID32(RCDF_DISPLAY_CONFIG); + + /* SET RELEVANT FIELDS */ + dcfg |= (RCDF_DCFG_FP_PWR_EN | RCDF_DCFG_FP_DATA_EN); + /* Enable the flatpanel power and data */ + WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg); + } + +} + +/*----------------------------------------------------------------- + * Pnl_PowerDown + * + * Description: This function make power down based on the + * hardware platforms dorado or centaraus. + * parameters: none. + * return: none. + *-----------------------------------------------------------------*/ +void +Pnl_PowerDown(void) +{ + int Platform; + unsigned long dcfg, hw_video; + + Platform = Pnl_GetPlatform(); + +#if PLATFORM_CENTAURUS + if (Platform == CENTAURUS_PLATFORM) { + Centaurus_Power_Down(); + return; + } +#endif +#if PLATFORM_DORADO + if (Platform == DORADO_PLATFORM) { + Dorado_Power_Down(); + return; + } +#endif + +#if PLATFORM_GX2BASED + if (Platform == REDCLOUD_PLATFORM) { + } +#endif + + hw_video = gfx_detect_video(); + + if (hw_video == GFX_VID_CS5530) { + /* READ DISPLAY CONFIG FROM CX5530 */ + dcfg = READ_VID32(CS5530_DISPLAY_CONFIG); + + /* CLEAR RELEVANT FIELDS */ + dcfg &= ~(CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN); + /* Disable the flatpanel power and data */ + WRITE_VID32(CS5530_DISPLAY_CONFIG, dcfg); + } else if (hw_video == GFX_VID_SC1200) { + /* READ DISPLAY CONFIG FROM SC1200 */ + dcfg = READ_VID32(SC1200_DISPLAY_CONFIG); + + /* CLEAR RELEVANT FIELDS */ + dcfg &= ~(SC1200_DCFG_FP_PWR_EN | SC1200_DCFG_FP_DATA_EN); + /* Disable the flatpanel power and data */ + WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg); + } else if (hw_video == GFX_VID_REDCLOUD) { + /* READ DISPLAY CONFIG FROM REDCLOUD */ + dcfg = READ_VID32(RCDF_DISPLAY_CONFIG); + + /* CLEAR RELEVANT FIELDS */ + dcfg &= ~(RCDF_DCFG_FP_PWR_EN | RCDF_DCFG_FP_DATA_EN); + /* Disable the flatpanel power and data */ + WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg); + } +} + +/*----------------------------------------------------------------- + * Pnl_SavePanelState + * + * Description: This function saves the panel state based on the + * hardware platforms dorado or centaraus. + * parameters: none. + * return: none. + *-----------------------------------------------------------------*/ +void +Pnl_SavePanelState(void) +{ + int Platform; + + Platform = Pnl_GetPlatform(); + +#if PLATFORM_CENTAURUS + if (Platform == CENTAURUS_PLATFORM) { + Centaurus_Save_Panel_State(); + return; + } +#endif + +#if PLATFORM_DORADO + if (Platform == DORADO_PLATFORM) { + Dorado_Save_Panel_State(); + return; + } +#endif + +#if PLATFORM_GX2BASED + if (Platform == REDCLOUD_PLATFORM) { + } +#endif +} + +/*----------------------------------------------------------------- + * Pnl_RestorePanelState + * + * Description: This function restore the panel state based on the + * hardware platforms dorado or centaraus. + * parameters: none. + * return: none. + *-----------------------------------------------------------------*/ +void +Pnl_RestorePanelState(void) +{ + int Platform; + + Platform = Pnl_GetPlatform(); +#if PLATFORM_CENTAURUS + if (Platform == CENTAURUS_PLATFORM) { + Centaurus_Restore_Panel_State(); + return; + } +#endif + +#if PLATFORM_DORADO + if (Platform == DORADO_PLATFORM) { + Dorado_Restore_Panel_State(); + return; + } +#endif + +#if PLATFORM_GX2BASED + if (Platform == REDCLOUD_PLATFORM) { + } +#endif +} + +/*----------------------------------------------------------------- + * Pnl_GetPanelParam + * + * Description: This function gets the panel parameters from the + * hardware platforms dorado or centaraus. + * parameters: + * pParam: It specifies the elements of the panel parameter + * structure. + * return: none. + *-----------------------------------------------------------------*/ +void +Pnl_GetPanelParam(PPnl_PanelParams pParam) +{ + if (pParam->Flags & PNL_PANELPRESENT) { + pParam->PanelPresent = Pnl_IsPanelPresent(); + } + if (pParam->Flags & PNL_PLATFORM) { + pParam->Platform = Pnl_GetPlatform(); + } + if ((pParam->Flags & PNL_PANELCHIP) || (pParam->Flags & PNL_PANELSTAT)) { +#if PLATFORM_CENTAURUS + if (pParam->Platform == CENTAURUS_PLATFORM) { + Centaurus_Get_9211_Details(pParam->Flags, pParam); + return; + } +#endif + +#if PLATFORM_DORADO + if (pParam->Platform == DORADO_PLATFORM) { + Dorado_Get_9211_Details(pParam->Flags, pParam); + return; + } +#endif + +#if PLATFORM_GX2BASED + if (pParam->Platform == REDCLOUD_PLATFORM) { + } +#endif + + /* if unknown platform put unknown */ + if (pParam->Flags & PNL_PANELCHIP) + pParam->PanelChip = PNL_UNKNOWN_CHIP; + + if (pParam->Flags & PNL_PANELSTAT) { + pParam->PanelStat.XRes = 0; + pParam->PanelStat.YRes = 0; + pParam->PanelStat.Depth = 0; + pParam->PanelStat.MonoColor = PNL_UNKNOWN_COLOR; + pParam->PanelStat.Type = PNL_UNKNOWN_PANEL; + } + } +} + +/*----------------------------------------------------------------- + * Pnl_SetPanelChip + * + * Description: This function sets the panelchip parameter of panel + * structure. + * parameters: + * panelChip: It specifies the panelChip value. + * return: none. + *-----------------------------------------------------------------*/ + +void +Pnl_SetPanelChip(int panelChip) +{ + /* To Be Implemented */ + sPanelParam.PanelChip = panelChip; + +} + +/*----------------------------------------------------------------- + * Pnl_GetPanelChip + * + * Description: This function gets the panelchip parameter of panel + * structure. + * parameters: + * return: On success it returns the panelchip. + *-----------------------------------------------------------------*/ +int +Pnl_GetPanelChip(void) +{ + /* To Be Implemented */ + return sPanelParam.PanelChip; +} + +/*----------------------------------------------------------------- + * Pnl_InitPanel + * + * Description: This function initializes the panel with + * hardware platforms dorado or centaraus. + * parameters: + * pParam: It specifies the elements of the panel parameter + * structure. + * return: none. + *-----------------------------------------------------------------*/ +int +Pnl_InitPanel(PPnl_PanelParams pParam) +{ + PPnl_PanelParams pPtr; + + if (pParam == 0x0) /* NULL use the static table */ + pPtr = &sPanelParam; + else + pPtr = pParam; + + if (!pPtr->PanelPresent) { + return -1; /* error */ + } else { + if ((pPtr->PanelChip < 0) || (pPtr->Platform < 0)) + return -1; /* error */ + +#if PLATFORM_DRACO + /* check we are init. the right one */ + if ((pPtr->Platform == DRACO_PLATFORM) && (pPtr->PanelChip == PNL_9210)) { + Draco9210Init(&(pPtr->PanelStat)); + } +#endif + +#if PLATFORM_CENTAURUS + /* check we are init. the right one */ + if (pPtr->Platform == CENTAURUS_PLATFORM) { + Centaurus_9211init(&(pPtr->PanelStat)); + } +#endif + +#if PLATFORM_DORADO + /* check we are init. the right one */ + if ((pPtr->Platform == DORADO_PLATFORM) && + (pPtr->PanelChip == PNL_9211_C)) { + Dorado9211Init(&(pPtr->PanelStat)); + } +#endif +#if PLATFORM_GX2BASED + if (pPtr->Platform == REDCLOUD_PLATFORM) { + Redcloud_9211init(&(pPtr->PanelStat)); + } +#endif + } /* else end */ + return 1; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/readme.txt b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/readme.txt new file mode 100644 index 000000000..bfe92f384 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/readme.txt @@ -0,0 +1,365 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/readme.txt,v 1.2 2002/12/10 15:41:27 alanh Exp $ */ +Panel Library +Release 1.3.2 +OS - Can be used in all OS's. +Dec 10, 2002 +Developer - Sarma Kolluru + +----------------------------------------------------------------------------- +PRODUCT INFORMATION +----------------------------------------------------------------------------- +Panel library is set of functions enabling the driver to give panel support. +The panel library is supported on Centaurus and Dorado. +The panel library can detect the panel support by the jumper settings +selected on the board. The platform can be detected too. + + \readme.txt This file + +----------------------------------------------------------------------------- +BUILD INSTRUCTIONS +----------------------------------------------------------------------------- +Panel library is a set of files which has support for flatpanel. The panel +subdirectory needs to be copied in the driver directory. +----------------------------------------------------------------------------- +INSTALLATION INSTRUCTIONS +----------------------------------------------------------------------------- +These is no instalation and to be treaded as a driver source code extension. +- Run "/root/crlf/crlf -a" in Linux OS. +----------------------------------------------------------------------------- +UNIT TEST +Panel library when compiled is a part of the driver and cannot be unit tested. +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +REVISION HISTORY +----------------------------------------------------------------------------- +Version changes v1.3.2 12/10/02 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1o +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +- Did code indentation for XFree release. +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None. +----------------------------------------------------------------------------- +FILE CHANGES + 92xx.h + cen9211.c + cen9211.h + dora9211.c + dora9211.h + drac9210.c + drac9210.h + gx2_9211.c + gx2_9211.h + panel.h + panel.c + platform.c + pnl_bios.c + pnl_defs.h + pnl_init.c +----------------------------------------------------------------------------- +Version changes v1.3.1 12/06/02 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1o +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +- Added function protoype. +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None. +----------------------------------------------------------------------------- +FILE CHANGES + cen9211.h + dora9211.h + gx2_9211.h +----------------------------------------------------------------------------- +Version changes v1.3.0 11/29/02 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1o +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +- None. +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- cursor variable not defined for XFree when not as a module. +----------------------------------------------------------------------------- +FILE CHANGES + platform.c +----------------------------------------------------------------------------- +Version changes v1.2.9 7/31/02 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1o +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Added FP setup from user input. +Added Redcloud Panel initialization. +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + pnl_init.c + panel.c + platform.c + gx2_9211.c + gx2_9211.h +----------------------------------------------------------------------------- +Version changes v1.2.8 5/16/02 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1o +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Added FP detection with BIOS for GX2. +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + pnl_bios.c +----------------------------------------------------------------------------- +Version changes v1.2.7 1/20/02 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1o +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Added the protoype for gfx_detect_video. +Durango dependency removed. +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + panel.c +----------------------------------------------------------------------------- +Version changes v1.2.6 12/1/01 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1o + - Durango 2.35.01 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Toggle 5530/scx200/RC FlatPanel Power and Data accordingly during +power up/down. + +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + pnl_init.c +----------------------------------------------------------------------------- +Version changes v1.2.5 11/1/01 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1o + - Durango 2.35.01 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Re-Enabled the Draco platform support. + +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + panel_defs.h + pnl_init.c +----------------------------------------------------------------------------- +Version changes v1.2.4 08/12/01 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1 + - Durango 2.33.01 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Added 2 functions to get the FP setting details from BIOS. + +int Pnl_IsPanelEnabledInBIOS(void); +void Pnl_GetPanelInfoFromBIOS(int *xres, int *yres, int *bpp, int *hz); + +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + panel.h + pnl_bios.c +----------------------------------------------------------------------------- +Version changes v1.2.3 06/05/01 +----------------------------------------------------------------------------- +Dependencies: + - crlf v1.0.1 + - Durango 2.31.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Code cleanup and documentation. + +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + panel.h + cen9211.c + cen9211.h + dora9211.c + dora9211.h + panel.h + pnl_init.c +----------------------------------------------------------------------------- +Version changes v1.2.2 04/11/01 +----------------------------------------------------------------------------- +Dependencies: + - Durango 2.27.00 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Added Pnl_PowerUp and Pnl_PowerDown Functions. + +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + panel.h + cen9211.c + cen9211.h + dora9211.c + dora9211.h + panel.h + pnl_init.c +----------------------------------------------------------------------------- +Version changes v1.2.1 03/29/01 +----------------------------------------------------------------------------- +Dependencies: + - Durango 2.25 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Added Pnl_SavePanelState and Pnl_RestorePanelState Functions. + +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + panel.h + 92xx.h + cen9211.c + cen9211.h + dora9211.c + dora9211.h + platform.c + pnl_init.c +----------------------------------------------------------------------------- +Version changes v1.2.0 03/04/01 +----------------------------------------------------------------------------- +Dependencies: + - Durango 2.23 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Use inb/out routines from durango directly. +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + panel.h -inb/outb deleted. +============================================================================= +Version changes v1.0.1 02/02/01 +----------------------------------------------------------------------------- +Dependencies: + - Durango 2.19 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Added 9211 Rev. C on Centaurus platform. + +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + 92xx.h -9211 Rev.C. + cen9211.c - centaurus 9211_C support file. + cen9211.h - centaurus 9211_C support file. + platform.c - Support for detection of platform in which driver runs. +============================================================================= +Version changes v1.0.0 01/21/01 +----------------------------------------------------------------------------- +Dependencies: + - Durango 2.16 + +----------------------------------------------------------------------------- +FUNCTIONAL CHANGES +----------------------------------------------------------------------------- +Detection of platform +Detection of 92x chip with version and the panel sected by jumper settings. +initialization of the h/w. +----------------------------------------------------------------------------- +DEFECTS CORRECTED +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- +FILE CHANGES + 92xx.h -common file with all 9211/9210 definitions. + cen9211.c - centaurus 9211_A support file. + cen9211.h - centaurus 9211_A support file. + dora9211.c - dorado 9211_A support file. + dora9211.h - dorado 9211_C support file. + drac9210.c - draco 9210 support file. + drac9210.h - draco 9210 support file. + panel.c - This is the confiuration file to enable support for platforms. + panel.h - centaurus 9211_A support file. + platform.c - Support for detection of platform in which driver runs. + pnl_defs.h - common definitions for panel. + pnl_init.c - configurationto call appropriate platform calls. + readme.txt - this file. +----------------------------------------------------------------------------- +----------------------------------------------------------------------------- +KNOWN ERRATA +----------------------------------------------------------------------------- +- None listed +----------------------------------------------------------------------------- + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_xv.c b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_xv.c index 1729ca81c..0e2995b82 100755 --- a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_xv.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_xv.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_xv.c,v 1.5 2001/11/21 22:43:00 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_xv.c,v 1.7 2003/02/04 02:20:50 dawes Exp $ */ /* Copyright (C) 2000 The XFree86 Project, Inc. All Rights Reserved. @@ -55,6 +55,7 @@ in this Software without prior written authorization from the XFree86 Project. #ifndef XvExtension void S3VInitVideo(ScreenPtr pScreen) {} +int S3VQueryXvCapable(ScrnInfoPtr) {return FALSE;} #else #if 0 @@ -93,6 +94,25 @@ static Atom xvBrightness, xvContrast, xvColorKey; #endif /* 0 */ +int S3VQueryXvCapable(ScrnInfoPtr pScrn) +{ + S3VPtr ps3v = S3VPTR(pScrn); + + if( + ((pScrn->bitsPerPixel == 24) || + (pScrn->bitsPerPixel == 16) + ) + && + ((ps3v->Chipset == S3_ViRGE_DXGX) || + S3_ViRGE_MX_SERIES(ps3v->Chipset) || + S3_ViRGE_GX2_SERIES(ps3v->Chipset) + )) + return TRUE; + else + return FALSE; +} + + void S3VInitVideo(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -115,7 +135,7 @@ void S3VInitVideo(ScreenPtr pScreen) && ps3v->XVideo ) { - #if 0 +#if 0 if((pMga->Overlay8Plus24 /* || dualhead */ || pMga->TexturedVideo) && (pScrn->bitsPerPixel != 24)) { @@ -123,12 +143,12 @@ void S3VInitVideo(ScreenPtr pScreen) newAdaptor = MGASetupImageVideoTexture(pScreen); pMga->TexturedVideo = TRUE; } else { - #endif +#endif xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using overlay video\n"); newAdaptor = S3VSetupImageVideoOverlay(pScreen); - #if 0 +#if 0 pMga->TexturedVideo = FALSE; }*/ @@ -136,7 +156,7 @@ void S3VInitVideo(ScreenPtr pScreen) S3VInitOffscreenImages(pScreen); pMga->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = MGABlockHandler; - #endif +#endif } @@ -762,6 +782,10 @@ S3VDisplayVideoOverlay( vgaCRIndex = vgaIOBase + 4; vgaCRReg = vgaIOBase + 5; + /* If streams aren't enabled, do nothing */ + if(!ps3v->NeedSTREAMS) + return; + #if 0 /* got 64 scanlines to do it in */ tmp = INREG(MGAREG_VCOUNT) + 64; @@ -962,6 +986,10 @@ S3VPutImage( static int once = 1; static int once2 = 1; + /* If streams aren't enabled, do nothing */ + if(!ps3v->NeedSTREAMS) + return Success; + /* Clip */ x1 = src_x; x2 = src_x + src_w; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c index c5b6ed187..0ffc8631b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.17 2002/10/02 20:39:54 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.18 2002/11/08 18:03:32 alanh Exp $ */ /* * @@ -417,7 +417,7 @@ SavageInitAccel(ScreenPtr pScreen) #if 1 xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy; xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy; - xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | ROP_NEEDS_SOURCE; + xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK | ROP_NEEDS_SOURCE; #endif @@ -438,6 +438,7 @@ SavageInitAccel(ScreenPtr pScreen) xaaptr->Mono8x8PatternFillFlags = 0 | HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN + | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST ; if( psav->Chipset == S3_SAVAGE4 ) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c index b84710694..cdfe256fb 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.28 2002/10/02 20:39:55 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.34 2003/02/25 04:08:21 dawes Exp $ */ /* * vim: sw=4 ts=8 ai ic: * @@ -193,7 +193,6 @@ typedef enum { ,OPTION_ROTATE ,OPTION_USEBIOS ,OPTION_SHADOW_STATUS - ,OPTION_VIDEORAM ,OPTION_CRT_ONLY ,OPTION_TV_ON ,OPTION_TV_PAL @@ -211,7 +210,6 @@ static const OptionInfoRec SavageOptions[] = { OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_LCDCLOCK, "LCDClock", OPTV_FREQ, {0}, FALSE }, { OPTION_SHADOW_STATUS, "ShadowStatus", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_VIDEORAM, "VideoRAM", OPTV_INTEGER, {0}, FALSE }, { OPTION_CRT_ONLY, "CrtOnly", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_TV_ON, "TvOn", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_TV_PAL, "PAL", OPTV_BOOLEAN, {0}, FALSE }, @@ -891,13 +889,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "%ssing video BIOS to set modes\n", psav->UseBIOS ? "U" : "Not u" ); - pScrn->videoRam = 0; - if( xf86GetOptValInteger(psav->Options, OPTION_VIDEORAM, &pScrn->videoRam ) ) - { - xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, - "Option: VideoRAM %dkB\n", pScrn->videoRam ); - } - psav->LCDClock = 0.0; if( xf86GetOptValFreq( psav->Options, OPTION_LCDCLOCK, OPTUNITS_MHZ, &psav->LCDClock ) ) xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, @@ -995,6 +986,9 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) } else psav->ChipRev = psav->PciInfo->chipRev; + if (pEnt->device->videoRam != 0) + pScrn->videoRam = pEnt->device->videoRam; + xfree(pEnt); /* maybe throw in some more sanity checks here */ @@ -1358,7 +1352,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) } } - clockRanges = xnfalloc(sizeof(ClockRange)); + clockRanges = xnfcalloc(sizeof(ClockRange),1); clockRanges->next = NULL; clockRanges->minClock = psav->minClock; clockRanges->maxClock = psav->maxClock; @@ -2839,15 +2833,16 @@ static Bool SavageSaveScreen(ScreenPtr pScreen, int mode) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; TRACE(("SavageSaveScreen(0x%x)\n", mode)); - if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor ) - { + if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor && SAVPTR(pScrn)->hwc_on) { + if( xf86IsUnblank(mode) ) SavageShowCursor( pScrn ); else SavageHideCursor( pScrn ); + SAVPTR(pScrn)->hwc_on = TRUE; } - return vgaHWSaveScreen(pScreen, mode); + return vgaHWSaveScreen(pScreen, mode); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h index b79d5d953..231139684 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v 1.14 2002/10/02 20:39:55 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v 1.16 2003/01/18 15:22:30 eich Exp $ */ #ifndef SAVAGE_VGAHWMMIO_H #define SAVAGE_VGAHWMMIO_H @@ -118,6 +118,7 @@ typedef struct _Savage { Bool fifo_moderate; Bool fifo_aggressive; Bool hwcursor; + Bool hwc_on; Bool NoAccel; Bool shadowFB; Bool UseBIOS; @@ -212,6 +213,15 @@ typedef struct _Savage { #define SAVPTR(p) ((SavagePtr)((p)->driverPrivate)) +/* Make the names of these externals driver-unique */ +#define gpScrn savagegpScrn +#define myOUTREG savageOUTREG +#define readdw savagereaddw +#define readfb savagereadfb +#define writedw savagewritedw +#define writefb savagewritefb +#define writescan savagewritescan + /* Prototypes. */ extern void SavageCommonCalcClock(long freq, int min_m, int min_n1, diff --git a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi.h b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi.h index 2a0c8ebda..6fb2ee09f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi.h @@ -26,7 +26,7 @@ Silicon Motion shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the XFree86 Project and Silicon Motion. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi.h,v 1.11 2002/09/16 18:05:59 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi.h,v 1.12 2003/01/12 03:55:49 tsi Exp $ */ #ifndef _SMI_H #define _SMI_H @@ -65,8 +65,8 @@ authorization from the XFree86 Project and Silicon Motion. #include "vbe.h" #ifdef XvExtension - #include "xf86xv.h" - #include "Xv.h" +# include "xf86xv.h" +# include "Xv.h" #endif /******************************************************************************/ @@ -74,7 +74,7 @@ authorization from the XFree86 Project and Silicon Motion. /******************************************************************************/ #ifndef SMI_DEBUG - #define SMI_DEBUG 0 +# define SMI_DEBUG 0 #endif #define SMI_USE_IMAGE_WRITES 0 @@ -263,20 +263,20 @@ typedef struct /******************************************************************************/ #if SMI_DEBUG - #define VERBLEV 1 - #define ENTER_PROC(PROCNAME) xf86ErrorFVerb(VERBLEV, "ENTER\t" PROCNAME \ +# define VERBLEV 1 +# define ENTER_PROC(PROCNAME) xf86ErrorFVerb(VERBLEV, "ENTER\t" PROCNAME \ "(%d)\n", __LINE__); xf86Break1() - #define DEBUG_PROC(PROCNAME) xf86ErrorFVerb(VERBLEV, "DEBUG\t" PROCNAME \ +# define DEBUG_PROC(PROCNAME) xf86ErrorFVerb(VERBLEV, "DEBUG\t" PROCNAME \ "(%d)\n", __LINE__); xf86Break2() - #define LEAVE_PROC(PROCNAME) xf86ErrorFVerb(VERBLEV, "LEAVE\t" PROCNAME \ +# define LEAVE_PROC(PROCNAME) xf86ErrorFVerb(VERBLEV, "LEAVE\t" PROCNAME \ "(%d)\n", __LINE__); xf86Break1() - #define DEBUG(arg) xf86ErrorFVerb arg +# define DEBUG(arg) xf86ErrorFVerb arg #else - #define VERBLEV 4 - #define ENTER_PROC(PROCNAME) - #define DEBUG_PROC(PROCNAME) - #define LEAVE_PROC(PROCNAME) - #define DEBUG(arg) +# define VERBLEV 4 +# define ENTER_PROC(PROCNAME) +# define DEBUG_PROC(PROCNAME) +# define LEAVE_PROC(PROCNAME) +# define DEBUG(arg) #endif /* Some Silicon Motion structs & registers */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c index 59097d610..1c53060e1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c @@ -26,7 +26,7 @@ Silicon Motion shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the XFree86 Project and silicon Motion. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c,v 1.6 2001/12/20 21:35:38 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c,v 1.7 2003/01/12 03:55:49 tsi Exp $ */ #include "smi.h" @@ -207,14 +207,14 @@ SMI_AccelInit(ScreenPtr pScreen) } else { - #if defined(XvExtension) && SMI_USE_VIDEO +#if defined(XvExtension) && SMI_USE_VIDEO numLines = ((pSmi->FBReserved - pSmi->width * pSmi->Bpp * pSmi->height) * 25 / 100 + pSmi->width * pSmi->Bpp - 1) / (pSmi->width * pSmi->Bpp); numLines += pSmi->height; - #else +#else numLines = maxLines; - #endif +#endif } AvailFBArea.x1 = 0; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c index 75c27e139..1a242c6dc 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c @@ -26,7 +26,7 @@ Silicon Motion shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The XFree86 Project or Silicon Motion. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c,v 1.26 2002/09/16 18:05:59 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c,v 1.28 2003/02/05 17:45:29 eich Exp $ */ #include "xf86Resources.h" #include "xf86RAC.h" @@ -764,9 +764,9 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) pSmi->shadowFB ? "enabled" : "disabled"); } - #if 1 /* PDR#932 */ +#if 1 /* PDR#932 */ if ((pScrn->depth == 8) || (pScrn->depth == 16)) - #endif /* PDR#932 */ +#endif /* PDR#932 */ if ((s = xf86GetOptValString(pSmi->Options, OPTION_ROTATE))) { if(!xf86NameCmp(s, "CW")) @@ -1134,15 +1134,14 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) * Setup the ClockRanges, which describe what clock ranges are available, * and what sort of modes they can be used for. */ - clockRanges = xnfalloc(sizeof(ClockRange)); + clockRanges = xnfcalloc(sizeof(ClockRange),1); clockRanges->next = NULL; clockRanges->minClock = pSmi->minClock; clockRanges->maxClock = pSmi->maxClock; clockRanges->clockIndex = -1; clockRanges->interlaceAllowed = FALSE; clockRanges->doubleScanAllowed = FALSE; - - + i = xf86ValidateModes( pScrn, /* Screen pointer */ pScrn->monitor->Modes, /* Available monitor modes */ @@ -2341,7 +2340,7 @@ SMI_ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) if (!pSmi->useBIOS || pSmi->lcd) { - #if 1 /* PDR#983 */ +#if 1 /* PDR#983 */ if (pSmi->zoomOnLCD) { if ( (mode->HDisplay > pSmi->lcdWidth) @@ -2353,7 +2352,7 @@ SMI_ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) } } else - #endif +#endif { if ( (mode->HDisplay != pSmi->lcdWidth) || (mode->VDisplay != pSmi->lcdHeight) @@ -2366,7 +2365,7 @@ SMI_ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) } - #if 1 /* PDR#944 */ +#if 1 /* PDR#944 */ if (pSmi->rotate) { if ( (mode->HDisplay != pSmi->lcdWidth) @@ -2377,7 +2376,7 @@ SMI_ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) return(MODE_PANEL); } } - #endif +#endif LEAVE_PROC("SMI_ValidMode"); return(MODE_OK); @@ -2859,22 +2858,22 @@ SMI_AdjustFrame(int scrnIndex, int x, int y, int flags) if (SMI_LYNX3D_SERIES(pSmi->Chipset)) { Base = (Base + 15) & ~15; - #if 1 /* PDR#1058 */ +#if 1 /* PDR#1058 */ while ((Base % pSmi->Bpp) > 0) { Base -= 16; } - #endif +#endif } else { Base = (Base + 7) & ~7; - #if 1 /* PDR#1058 */ +#if 1 /* PDR#1058 */ while ((Base % pSmi->Bpp) > 0) { Base -= 8; } - #endif +#endif } WRITE_VPR(pSmi, 0x0C, Base >> 3); @@ -3098,7 +3097,7 @@ SMI_DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, return; } - #if 1 /* PDR#735 */ +#if 1 /* PDR#735 */ if (pSmi->pInt10 != NULL) { pSmi->pInt10->ax = 0x4F10; @@ -3126,19 +3125,19 @@ SMI_DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, if (pSmi->pInt10->ax == 0x004F) { pSmi->CurrentDPMS = PowerManagementMode; - #if 1 /* PDR#835 */ +#if 1 /* PDR#835 */ if (PowerManagementMode == DPMSModeOn) { SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, SR01 & ~0x20); } - #endif +#endif LEAVE_PROC("SMI_DisplayPowerManagementSet"); return; } } - #endif +#endif /* Save the current SR registers */ if (pSmi->CurrentDPMS == DPMSModeOn) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c index a2ef0369e..31694d384 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c @@ -41,7 +41,7 @@ Author of changes: Corvin Zahn <zahn@zac.de> Date: 2.11.2001 */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c,v 1.8 2002/09/16 18:06:00 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c,v 1.9 2003/01/12 03:55:49 tsi Exp $ */ #include "smi.h" #include "smi_video.h" @@ -1354,11 +1354,11 @@ SMI_StopVideo( if (pPort->videoStatus & CLIENT_VIDEO_ON) { WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x01000008); - #if SMI_USE_CAPTURE +#if SMI_USE_CAPTURE WRITE_CPR(pSmi, 0x00, READ_CPR(pSmi, 0x00) & ~0x00000001); WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) & ~0x00F00000); /* #864 OUT_SEQ(pSmi, 0x21, IN_SEQ(pSmi, 0x21) | 0x04); */ - #endif +#endif } if (pPort->area != NULL) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h new file mode 100644 index 000000000..a6989da1c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h @@ -0,0 +1,3314 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/300vtbl.h,v 1.6 2003/02/10 01:14:16 tsi Exp $ */ + + +/* Register settings for SiS 300 series */ + + +typedef struct _SiS300_StStruct +{ + UCHAR St_ModeID; + USHORT St_ModeFlag; + UCHAR St_StTableIndex; + UCHAR St_CRT2CRTC; + UCHAR St_ResInfo; + UCHAR VB_StTVFlickerIndex; + UCHAR VB_StTVEdgeIndex; + UCHAR VB_StTVYFilterIndex; +} SiS300_StStruct; + +static const SiS300_StStruct SiS300_SModeIDTable[] = +{ + {0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00}, + {0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00}, + {0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00}, + {0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00}, + {0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00}, + {0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00}, + {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00}, + {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00}, + {0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00}, + {0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00}, + {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00}, + {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00}, + {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00}, + {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00}, + {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00}, + {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00}, + {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00}, + {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00}, + {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00}, + {0xff, 0, 0, 0, 0, 0, 0, 0} +}; + +typedef struct _SiS300_StandTableStruct +{ + UCHAR CRT_COLS; + UCHAR ROWS; + UCHAR CHAR_HEIGHT; + USHORT CRT_LEN; + UCHAR SR[4]; + UCHAR MISC; + UCHAR CRTC[0x19]; + UCHAR ATTR[0x14]; + UCHAR GRC[9]; +} SiS300_StandTableStruct; + +static const SiS300_StandTableStruct SiS300_StandTable[] = +{ + {0x28,0x18,0x08,0x0800, /* 0x00 */ + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x28,0x18,0x08,0x0800, /* 0x01 */ + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x50,0x18,0x08,0x1000, /* 0x02 */ + {0x01,0x03,0x00,0x02}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x50,0x18,0x08,0x1000, /* 0x03 */ + {0x01,0x03,0x00,0x02}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x28,0x18,0x08,0x4000, /* 0x04 */ + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f, + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, + 0xff}, + {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x03,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, + 0xff} }, + {0x28,0x18,0x08,0x4000, /* 0x05 */ + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f, + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, + 0xff}, + {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x03,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, + 0xff} }, + {0x50,0x18,0x08,0x4000, /* 0x06 */ + {0x01,0x01,0x00,0x06}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2, + 0xff}, + {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17, + 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, + 0x01,0x00,0x01,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00, + 0xff} }, + {0x50,0x18,0x0e,0x1000, /* 0x07 */ + {0x00,0x03,0x00,0x03}, + 0xa6, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3, + 0xff}, + {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x0e,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, + 0xff} }, +/* MDA_DAC*/ + {0x00,0x00,0x00,0x0000, /* 0x08 */ + {0x00,0x00,0x00,0x15}, + 0x15, + {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00, + 0x00}, + {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15}, + {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x3f} }, +/* CGA_DAC*/ + {0x00,0x10,0x04,0x0114, /* 0x09 */ + {0x11,0x09,0x15,0x00}, + 0x10, + {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a, + 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a, + 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10, + 0x04}, + {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04, + 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e, + 0x3e,0x2b,0x3b,0x2f}, + {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, + 0x3f} }, +/* EGA_DAC*/ + {0x00,0x10,0x04,0x0114, /* 0x0a */ + {0x11,0x05,0x15,0x20}, + 0x30, + {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18, + 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38, + 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12, + 0x06}, + {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26, + 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e, + 0x1e,0x0b,0x1b,0x0f}, + {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, + 0x3f} }, +/* VGA_DAC*/ + {0x00,0x10,0x04,0x0114, /* 0x0b */ + {0x11,0x09,0x15,0x2a}, + 0x3a, + {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05, + 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20, + 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10, + 0x1f}, + {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d, + 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15, + 0x1c,0x0e,0x11,0x15}, + {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00, + 0x04} }, + {0x08,0x0c,0x10,0x0a08, /* 0x0c */ + {0x0c,0x0e,0x10,0x0b}, + 0x0c, + {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00, + 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00, + 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00, + 0x06}, + {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08, + 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00, + 0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00} }, + {0x28,0x18,0x08,0x2000, /* 0x0d */ + {0x09,0x0f,0x00,0x06}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f, + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} }, + {0x50,0x18,0x08,0x4000, /* 0x0e */ + {0x01,0x0f,0x00,0x06}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} }, + {0x00,0x00,0x00,0x0000, /* 0x0f */ /* TW: Standtable for VGA modes */ + {0x01,0x0f,0x00,0x0e}, + 0x23, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x01,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, + 0xff} }, + {0x4a,0x36,0x00,0x00c0, /* 0x10 */ + {0x00,0x00,0x00,0x00}, + 0x00, + {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a, + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0, + 0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00} }, + {0x50,0x18,0x0e,0x8000, /* 0x11 */ + {0x01,0x0f,0x00,0x06}, + 0xa2, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3, + 0xff}, + {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00, + 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00, + 0x0b,0x00,0x05,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05, + 0xff} }, + {0x50,0x18,0x0e,0x8000, /* 0x12 */ + {0x01,0x0f,0x00,0x06}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} }, + {0x28,0x18,0x0e,0x0800, /* 0x13 */ + {0x09,0x03,0x00,0x02}, + 0xa3, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x28,0x18,0x0e,0x0800, /* 0x14 */ + {0x09,0x03,0x00,0x02}, + 0xa3, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x50,0x18,0x0e,0x1000, /* 0x15 */ + {0x01,0x03,0x00,0x02}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x50,0x18,0x0e,0x1000, /* 0x16 */ + {0x01,0x03,0x00,0x02}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x28,0x18,0x10,0x0800, /* 0x17 */ + {0x08,0x03,0x00,0x02}, + 0x67, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x0c,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x50,0x18,0x10,0x1000, /* 0x18 */ + {0x00,0x03,0x00,0x02}, + 0x67, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x0c,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} }, + {0x50,0x18,0x10,0x1000, /* 0x19 */ + {0x00,0x03,0x00,0x02}, + 0x66, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x0e,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, + 0xff} }, + {0x50,0x1d,0x10,0xa000, /* 0x1a */ + {0x01,0x0f,0x00,0x06}, + 0xe3, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3, + 0xff}, + {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01, + 0xff} }, + {0x50,0x1d,0x10,0xa000, /* 0x1b */ + {0x01,0x0f,0x00,0x06}, + 0xe3, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} }, + {0x28,0x18,0x08,0x2000, /* 0x1c */ + {0x01,0x0f,0x00,0x0e}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f, + 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x41,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, + 0xff} } +}; + +typedef struct _SiS300_ExtStruct +{ + UCHAR Ext_ModeID; + USHORT Ext_ModeFlag; + USHORT Ext_ModeInfo; + USHORT Ext_Point; + USHORT Ext_VESAID; + UCHAR Ext_VESAMEMSize; + UCHAR Ext_RESINFO; + UCHAR VB_ExtTVFlickerIndex; + UCHAR VB_ExtTVEdgeIndex; + UCHAR VB_ExtTVYFilterIndex; + UCHAR REFindex; +} SiS300_ExtStruct; + +static const SiS300_ExtStruct SiS300_EModeIDTable[] = +{ + {0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600x? */ + {0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08}, + {0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10}, /* 640x400x8 */ + {0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00}, + {0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x8 */ + {0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x8 */ + {0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x16 */ + {0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x16 */ + {0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11}, /* 720x480x32 */ + {0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12}, /* 720x576x32 */ + {0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13}, /* 1024x768x? */ + {0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13}, /* 1024x768x8 */ + {0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */ + {0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, + {0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e}, + {0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23}, + {0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23}, + {0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08}, + {0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08}, + {0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */ + {0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */ + {0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13}, + {0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13}, + {0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a}, + {0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a}, + {0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24}, + {0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25}, /* 400x300 */ + {0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26}, + {0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24}, + {0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25}, /* 400x300 */ + {0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26}, + {0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23}, + {0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26}, /* TW: inserted 512x384x32 */ + {0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10}, /* 640x400x16 */ + {0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10}, /* TW: inserted 640x400x32 */ + {0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08}, + {0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00}, /* 800x600 */ + {0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13}, + {0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a}, + {0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e}, + {0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27}, + {0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27}, + {0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27}, + {0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28}, /* TW: 2048x1536x8 - not in BIOS! */ + {0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28}, /* TW: 2048x1536x16 - not in BIOS! */ + {0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x8 */ + {0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x16 */ + /* TW: 16:9 modes copied from 310/325 series - not in ANY BIOS */ + {0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x8 */ + {0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x8 */ + {0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x16 */ + {0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x16 */ + {0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x32 */ + {0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30}, /* 1024x576x32 */ + {0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x32 */ + {0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33}, /* 1280x720x8 */ + {0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d}, /* 800x480x16 */ + /* TW: End of new 16:9 modes */ + {0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29}, /* 1280x960x32 */ + {0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b}, /* 1024x600 */ + {0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b}, + {0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b}, + {0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c}, /* 1152x768 */ + {0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c}, + {0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c}, + {0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36}, /* TW: NEW 1152x864 - not in BIOS */ + {0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36}, + {0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36}, + {0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38}, /* TW: NEW 848x480 - not in BIOS */ + {0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38}, + {0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38}, + {0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a}, /* TW: NEW 856x480 - not in BIOS */ + {0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a}, + {0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a}, + {0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c}, /* TW: NEW 1360x768 - not in BIOS */ + {0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c}, + {0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c}, + {0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +typedef struct _SiS300_Ext2Struct +{ + USHORT Ext_InfoFlag; + UCHAR Ext_CRT1CRTC; /* TW: Index in SiS300_CRT1Table */ + UCHAR Ext_CRTVCLK; /* TW: Index in VCLK array */ + UCHAR Ext_CRT2CRTC; /* TW: Index in LCD Paneltype arrays (&3f) */ + UCHAR ModeID; + USHORT XRes; + USHORT YRes; + USHORT ROM_OFFSET; +} SiS300_Ext2Struct; + +static const SiS300_Ext2Struct SiS300_RefIndex[] = +{ /* TW: Don't ever insert anything here, table is indexed */ + {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */ + {0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */ + {0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */ + {0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */ + {0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */ + {0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */ + {0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */ + {0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */ + {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */ + {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */ + {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543}, /* 0a */ + {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548}, /* 0b */ + {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d}, /* 0c */ + {0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552}, /* 0d */ + {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557}, /* 0e */ + {0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c}, /* 0f */ + {0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532}, /* 10 */ + {0xc00f,0x31,0x01,0x06,0x31, 720, 480,0x3630}, /* 11 */ + {0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */ + {0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */ + {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */ + {0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */ + {0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */ + {0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */ + {0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */ + {0x0047,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */ + {0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */ + {0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */ + {0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */ + {0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */ + {0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */ + {0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */ + {0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */ + {0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */ + {0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */ + {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */ + {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */ + {0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */ + {0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */ /* was c077 */ + {0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */ + {0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */ + {0x0027,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */ + {0x0047,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */ + {0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */ + {0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */ /* VCLK 0x09 */ + {0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */ + {0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */ + {0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */ + {0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */ + {0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */ + {0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */ + {0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */ + {0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */ + {0x0047,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */ + {0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */ + {0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */ + {0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */ + {0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz - Non-BIOS, new */ + {0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */ + {0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz - Non-BIOS, new */ + {0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */ + {0xffff,0,0,0,0,0,0,0} +}; + +/*add for 300 oem util*/ +typedef struct _SiS_VBModeIDTableStruct +{ + UCHAR ModeID; + UCHAR VB_TVDelayIndex; + UCHAR VB_TVFlickerIndex; + UCHAR VB_TVPhaseIndex; + UCHAR VB_TVYFilterIndex; + UCHAR VB_LCDDelayIndex; + UCHAR _VB_LCDHIndex; + UCHAR _VB_LCDVIndex; +}SiS_VBModeIDTableStruct; + +static const SiS_VBModeIDTableStruct SiS300_VBModeIDTable[] = +{ + {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, + {0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x02}, + {0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x00}, + {0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x01}, + {0x03,0x00,0x00,0x00,0x03,0x00,0x03,0x02}, + {0x05,0x00,0x00,0x01,0x04,0x00,0x00,0x00}, + {0x06,0x00,0x00,0x01,0x05,0x00,0x02,0x00}, + {0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x01}, + {0x07,0x00,0x00,0x00,0x03,0x00,0x03,0x02}, + {0x0d,0x00,0x00,0x01,0x04,0x00,0x00,0x00}, + {0x0e,0x00,0x00,0x01,0x05,0x00,0x02,0x00}, + {0x0f,0x00,0x00,0x01,0x05,0x00,0x02,0x01}, + {0x10,0x00,0x00,0x01,0x05,0x00,0x02,0x01}, + {0x11,0x00,0x00,0x01,0x05,0x00,0x02,0x03}, + {0x12,0x00,0x00,0x01,0x05,0x00,0x02,0x03}, + {0x13,0x00,0x00,0x01,0x04,0x00,0x04,0x00}, + {0x6a,0x00,0x00,0x01,0x07,0x00,0x08,0x0a}, + {0x2e,0x00,0x00,0x01,0x05,0x00,0x06,0x08}, + {0x2f,0x00,0x00,0x01,0x05,0x00,0x06,0x06}, + {0x30,0x00,0x00,0x01,0x07,0x00,0x08,0x0a}, + {0x31,0x00,0x00,0x01,0x06,0x00,0x00,0x00}, + {0x32,0x00,0x00,0x01,0x06,0x00,0x00,0x00}, + {0x37,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c}, + {0x38,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c}, + {0x3a,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, + {0x40,0x00,0x00,0x01,0x04,0x00,0x05,0x05}, + {0x41,0x00,0x00,0x01,0x04,0x00,0x05,0x05}, + {0x43,0x00,0x00,0x01,0x05,0x00,0x06,0x08}, + {0x44,0x00,0x00,0x01,0x05,0x00,0x06,0x08}, + {0x46,0x00,0x00,0x01,0x07,0x00,0x08,0x0a}, + {0x47,0x00,0x00,0x01,0x07,0x00,0x08,0x0a}, + {0x49,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c}, + {0x4a,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c}, + {0x4c,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, + {0x4d,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, + {0x50,0x00,0x00,0x01,0x04,0x00,0x05,0x07}, + {0x51,0x00,0x00,0x01,0x07,0x00,0x07,0x09}, + {0x52,0x00,0x00,0x01,0x00,0x00,0x09,0x0b}, + {0x56,0x00,0x00,0x01,0x04,0x00,0x05,0x07}, + {0x57,0x00,0x00,0x01,0x07,0x00,0x07,0x09}, + {0x58,0x00,0x00,0x01,0x00,0x00,0x09,0x0b}, + {0x59,0x00,0x00,0x01,0x04,0x00,0x05,0x05}, + {0x5d,0x00,0x00,0x01,0x07,0x00,0x06,0x06}, + {0x62,0x00,0x00,0x01,0x05,0x00,0x06,0x08}, + {0x63,0x00,0x00,0x01,0x07,0x00,0x08,0x0a}, + {0x64,0x00,0x00,0x01,0x00,0x00,0x0a,0x0c}, + {0x65,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, + {0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, + {0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, + {0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d}, + {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00} /* TW: added! */ +}; +/*end*/ + +typedef struct _SiS300_CRT1TableStruct +{ + UCHAR CR[17]; +} SiS300_CRT1TableStruct; + +static const SiS300_CRT1TableStruct SiS300_CRT1Table[] = +{ + {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 */ + 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, + 0x00}}, + {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, + 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05, + 0x01}}, + {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, + 0x01}}, + {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, +#if 0 + {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 0x05 */ + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, + 0x00}}, +#endif + {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */ + 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05, + 0x00}}, +#if 0 + {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e, /* 0x06 */ + 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01, + 0x00}}, +#endif + {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */ + 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f, + 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01, + 0x00}}, + {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f, + 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, + 0x00}}, +#if 0 + {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e, /* 0x09 */ + 0xe4,0x87,0xdf,0xdf,0x04,0x00,0x00,0x01, + 0x00}}, +#endif + {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x09 - corrected 640x480-100 */ + 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05, + 0x00}}, +#if 0 + {{0x6c,0x4f,0x4f,0x83,0x59,0x9e,0x00,0x3e, /* 0x0a */ + 0xe5,0x8d,0xdf,0xdf,0x01,0x00,0x00,0x01, + 0x00}}, +#endif + {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x0a - corrected 640x480-120 */ + 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05, + 0x00}}, + {{0x63,0x4f,0x4f,0x87,0x56,0x9d,0xfb,0x1f, + 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01, + 0x00}}, + {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f, + 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* TW: Corrected VDE, VBE */ + 0x00}}, + {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0, + 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05, + 0x01}}, + {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06, + 0x01}}, + {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0, + 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06, + 0x01}}, + {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0, + 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06, + 0x01}}, + {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0, + 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06, + 0x01}}, + {{0x8c,0x63,0x63,0x87,0x72,0x16,0x7e,0xf0, + 0x59,0x8d,0x57,0x57,0x7f,0x00,0x00,0x06, + 0x01}}, + {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0, + 0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06, + 0x01}}, + {{0x7e,0x63,0x63,0x82,0x6c,0x14,0x75,0xe0, /* 0x14 */ + 0x58,0x0b,0x57,0x57,0x76,0x20,0x00,0x06, + 0x01}}, + {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f, + 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02, + 0x00}}, + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}}, + {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}}, + {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5, + 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02, + 0x01}}, + {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5, + 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02, + 0x01}}, + {{0x9f,0x7f,0x7f,0x83,0x83,0x93,0x1e,0xf5, /* 0x1a */ + 0x00,0x84,0xff,0xff,0x1f,0x10,0x00,0x02, + 0x01}}, + {{0xa2,0x7f,0x7f,0x86,0x84,0x94,0x37,0xf5, + 0x0b,0x82,0xff,0xff,0x38,0x10,0x00,0x02, + 0x01}}, + {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba, + 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03, + 0x00}}, + {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a, + 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, + 0x01}}, + {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a, /* 0x1e */ + 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, + 0x01}}, + {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a, + 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07, + 0x01}}, + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, /* 36: 1600x1200x85Hz */ + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, + {{0x3f,0xef,0xef,0x83,0xfd,0x1a,0xda,0x1f, /* 37: 1920x1440x60Hz */ + 0xa0,0x84,0x9f,0x9f,0xdb,0x1f,0x01,0x01, + 0x00}}, + {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba, + 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05, + 0x00}}, +#if 0 + {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef, /* 0x27: 1280x960-70 - invalid! */ + 0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07, + 0x01}}, +#endif + {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 0x27: 1280x960-60 - correct */ + 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07, + 0x01}}, + {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x28 */ + 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06, + 0x01}}, + {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba, + 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06, + 0x01}}, + {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba, + 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06, + 0x01}}, + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1, + 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02, + 0x01}}, + {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1, + 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02, + 0x01}}, + {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1, + 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02, + 0x01}}, + {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4, + 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, + 0x01}}, + {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4, + 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, + 0x01}}, + {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4, + 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07, + 0x01}}, + {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e, + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, + 0x00}}, + {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 0x32 */ + 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05, + 0x01}}, + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */ + 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02, + 0x01}}, +#if 0 + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, /* 0x34 - 1152x768 */ + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}}, +#endif + {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5, /* 0x34 - 1152x768 - TW: corrected */ + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}}, + {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, /* 0x35 - NEW 16:9 modes, not in BIOS ------ */ + 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06, + 0x01}}, /* 0x35 */ + {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba, + 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06, + 0x01}}, /* 0x36 */ + {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba, + 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06, + 0x01}}, /* 0x37 */ + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1, + 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02, + 0x01}}, /* 0x38 */ + {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1, + 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02, + 0x01}}, /* 0x39 */ + {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* TW: 95 was 15 - illegal HBE! */ + 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02, + 0x01}}, /* 0x3a */ + {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4, + 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, + 0x01}}, /* 0x3b */ + {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4, + 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, + 0x01}}, /* 0x3c */ + {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4, + 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07, + 0x01}}, /* 0x3d */ /* TW: End of 16:9 modes --------------- */ + {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* TW: New, 1152x864-75 (not in any BIOS) */ + 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07, + 0x01}}, /* 0x3e */ + {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */ + 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, + 0x00}}, /* 0x3f */ +#if 0 + {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */ + 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, + 0x00}}, /* 0x40 */ +#endif + {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */ + 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06, + 0x00}}, /* 0x40 */ + {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 856x480-38i, not in BIOS */ + 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, + 0x00}}, /* 0x41 */ + {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 856x480-60, not in BIOS */ + 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, + 0x00}}, /* 0x42 */ + {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* TW: New, 1360x768-60, not in BIOS */ + 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03, + 0x01}}, /* 0x43 */ + {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* TW: New, 1152x864-84 (not in any BIOS) */ + 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03, + 0x01}}, /* 0x44 */ + {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85 (not in any BIOS) */ + 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07, + 0x01}} /* 0x45 */ +}; + +typedef struct _SiS300_MCLKDataStruct +{ + UCHAR SR28,SR29,SR2A; + USHORT CLOCK; +} SiS300_MCLKDataStruct; + +static const SiS300_MCLKDataStruct SiS300_MCLKData_630[] = /* 630 */ +{ /* TW: at 0x54 in BIOS */ + { 0x5a,0x64,0x80, 66}, + { 0xb3,0x45,0x80, 83}, + { 0x37,0x61,0x80,100}, + { 0x37,0x22,0x80,133}, + { 0x37,0x61,0x80,100}, + { 0x37,0x61,0x80,100}, + { 0x37,0x61,0x80,100}, + { 0x37,0x61,0x80,100} +}; + +static const SiS300_MCLKDataStruct SiS300_MCLKData_300[] = /* 300 */ +{ /* TW: at 0x54 in BIOS */ + { 0x68,0x43,0x80,125}, + { 0x68,0x43,0x80,125}, + { 0x68,0x43,0x80,125}, + { 0x37,0x61,0x80,100}, + { 0x37,0x61,0x80,100}, + { 0x37,0x61,0x80,100}, + { 0x37,0x61,0x80,100}, + { 0x37,0x61,0x80,100} +}; + +typedef struct _SiS300_ECLKDataStruct +{ + UCHAR SR2E,SR2F,SR30; + USHORT CLOCK; +} SiS300_ECLKDataStruct; + +static const SiS300_ECLKDataStruct SiS300_ECLKData[] = +{ + { 0x54,0x43,0x80,100}, + { 0x53,0x43,0x80,100}, + { 0x55,0x43,0x80,100}, + { 0x52,0x43,0x80,100}, + { 0x3f,0x42,0x80,100}, + { 0x54,0x43,0x80,100}, + { 0x54,0x43,0x80,100}, + { 0x54,0x43,0x80,100} +}; + +typedef struct _SiS300_VCLKDataStruct +{ + UCHAR SR2B,SR2C; + USHORT CLOCK; +} SiS300_VCLKDataStruct; + +static const SiS300_VCLKDataStruct SiS300_VCLKData[] = +{ + { 0x1b,0xe1, 25}, /* 0x00 */ + { 0x4e,0xe4, 28}, + { 0x57,0xe4, 32}, /* 0x02 */ + { 0xc3,0xc8, 36}, + { 0x42,0xc3, 40}, /* 0x04 */ + { 0x5d,0xc4, 45}, + { 0x52,0x65, 50}, /* 0x06 */ + { 0x53,0x65, 50}, + { 0x6d,0x66, 56}, /* 0x08 */ + { 0x5a,0x64, 65}, + { 0x46,0x44, 68}, /* 0x0a */ + { 0x3e,0x43, 75}, + { 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH); - 730, A901(301B): 0xb1,0x46, 76 */ + { 0x41,0x43, 79}, + { 0x31,0x42, 79}, /* 0x0e */ + { 0x46,0x25, 85}, + { 0x78,0x29, 87}, /* 0x10 */ + { 0x62,0x44, 95}, + { 0x2b,0x22,105}, /* 0x12 */ + { 0x49,0x24,106}, + { 0xc3,0x28,108}, /* 0x14 */ + { 0x3c,0x23,109}, + { 0xf7,0x2c,132}, /* 0x16 */ + { 0xd4,0x28,136}, + { 0x41,0x05,158}, /* 0x18 */ + { 0x43,0x05,162}, + { 0xe1,0x0f,175}, /* 0x1a */ + { 0xfc,0x12,189}, /* 0x1b */ + { 0xde,0x26,194}, /* 0x1c */ + { 0x54,0x05,203}, + { 0x3f,0x03,230}, /* 0x1e */ + { 0x30,0x02,234}, + { 0x24,0x01,266}, /* 0x20 */ + { 0x52,0x2a, 54}, /* 301 TV */ + { 0x52,0x6a, 27}, /* 301 TV */ + { 0x62,0x24, 70}, /* 301 TV */ + { 0x62,0x64, 70}, /* 301 TV */ + { 0xa8,0x4c, 30}, /* 301 TV */ + { 0x20,0x26, 33}, /* 301 TV */ + { 0x31,0xc2, 39}, + { 0xbf,0xc8, 35}, /* 0x28 - 856x480 */ + { 0x60,0x36, 30}, /* 0x29 CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */ + { 0x40,0x4a, 28}, + { 0x9f,0x46, 44}, + { 0x97,0x2c, 26}, + { 0x44,0xe4, 25}, + { 0x7e,0x32, 47}, + { 0x8a,0x24, 31}, /* 0x2f CH/PAL TEXT | LVDS_2(CH), Mitac(CH) - 730, A901(301B): 0x57, 0xe4, 31 */ + { 0x97,0x2c, 26}, + { 0xce,0x3c, 39}, + { 0x52,0x4a, 36}, /* 0x32 CH/PAL 800x600 5/6 */ + { 0x34,0x61, 95}, + { 0x78,0x27,108}, + { 0xce,0x25,189}, /* 0x35 */ + { 0x45,0x6b, 21}, /* 0x36 */ /* TW: Added from Mitac */ + { 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */ + { 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */ + { 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */ + { 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */ + { 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */ + { 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/ + { 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */ + { 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/ + { 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/ + { 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */ + { 0x15,0x21, 79}, /* 0x41 - test for SiS730 */ + { 0xff,0x00, 0} +}; + +#if 0 /* TW: This table is in all BIOSes, but not used */ +static const SiS300_VCLKDataStruct SiS300_VBVCLKData[] = +{ + { 0x1b,0xe1, 25}, + { 0x4e,0xe4, 28}, + { 0x57,0xe4, 31}, + { 0xc3,0xc8, 36}, + { 0x42,0x47, 40}, + { 0x5d,0xc4, 44}, + { 0x52,0x47, 49}, + { 0x53,0x47, 50}, + { 0x6d,0x66, 56}, + { 0x5a,0x64, 65}, + { 0x46,0x44, 67}, + { 0x29,0x61, 75}, + { 0x6d,0x46, 75}, + { 0x41,0x43, 78}, + { 0x31,0x42, 79}, + { 0x46,0x25, 84}, + { 0x78,0x29, 86}, /* 0x10 */ + { 0x62,0x44, 94}, + { 0x2b,0x22,104}, + { 0x49,0x24,105}, + { 0x43,0x42,108}, + { 0x3c,0x23,109}, + { 0xe0,0x46,132}, + { 0x70,0x25,135}, + { 0x41,0x22,157}, + { 0x43,0x22,162}, + { 0x30,0x21,175}, + { 0xc1,0x24,189}, + { 0xde,0x26,194}, + { 0x70,0x07,202}, + { 0x3f,0x03,229}, + { 0x30,0x02,234}, /* 0x1f */ + { 0x24,0x01,265}, /* 0x20 */ + { 0x52,0x2a, 54}, + { 0x52,0x6a, 27}, + { 0x62,0x24, 70}, + { 0x62,0x64, 70}, + { 0xa8,0x4c, 30}, + { 0x20,0x26, 33}, + { 0x31,0xc2, 39}, + { 0x2e,0x48, 25}, /* 0x28 */ + { 0x24,0x46, 25}, /* 0x29 */ + { 0x26,0x64, 28}, + { 0x37,0x64, 40}, + { 0xa1,0x42,108}, + { 0x37,0x61,100}, + { 0x78,0x27,108}, + { 0xff,0x00, 0} +}; +#endif + +static const UCHAR SiS300_ScreenOffset[] = +{ + 0x14,0x19,0x20,0x28,0x32,0x40,0x50, + 0x64,0x78,0x80,0x2d,0x35,0x48,0x35, /* 0x35 for 848 and 856 */ + 0x55,0xff /* 0x55 for 1360 */ +}; + +typedef struct _SiS300_StResInfoStruct +{ + USHORT HTotal; + USHORT VTotal; +} SiS300_StResInfoStruct; + +static const SiS300_StResInfoStruct SiS300_StResInfo[] = +{ + { 640,400}, + { 640,350}, + { 720,400}, + { 720,350}, + { 640,480} +}; + +typedef struct _SiS300_ModeResInfoStruct +{ + USHORT HTotal; + USHORT VTotal; + UCHAR XChar; + UCHAR YChar; +} SiS300_ModeResInfoStruct; + +static const SiS300_ModeResInfoStruct SiS300_ModeResInfo[] = +{ + { 320, 200, 8, 8}, /* 0x00 */ + { 320, 240, 8, 8}, /* 0x01 */ + { 320, 400, 8, 8}, /* 0x02 */ + { 400, 300, 8, 8}, /* 0x03 */ + { 512, 384, 8, 8}, /* 0x04 */ + { 640, 400, 8,16}, /* 0x05 */ + { 640, 480, 8,16}, /* 0x06 */ + { 800, 600, 8,16}, /* 0x07 */ + { 1024, 768, 8,16}, /* 0x08 */ + { 1280,1024, 8,16}, /* 0x09 */ + { 1600,1200, 8,16}, /* 0x0a */ + { 1920,1440, 8,16}, /* 0x0b */ + { 720, 480, 8,16}, /* 0x0c */ + { 720, 576, 8,16}, /* 0x0d */ + { 1280, 960, 8,16}, /* 0x0e */ + { 1024, 600, 8,16}, /* 0x0f */ + { 1152, 768, 8,16}, /* 0x10 */ + { 2048,1536, 8,16}, /* 0x11 - TW: Not in BIOS! */ + { 800, 480, 8,16}, /* 0x12 - TW: New, not in any BIOS */ + { 1024, 576, 8,16}, /* 0x13 - TW: New, not in any BIOS */ + { 1280, 720, 8,16}, /* 0x14 - TW: New, not in any BIOS */ + { 1152, 864, 8,16}, /* 0x15 - TW: New, not in any BIOS */ + { 848, 480, 8,16}, /* 0x16 - TW: New, not in any BIOS */ + { 856, 480, 8,16}, /* 0x17 - TW: New, not in any BIOS */ + { 1360, 768, 8,16} /* 0x18 - TW: New, not in any BIOS */ +}; + +static const UCHAR SiS300_OutputSelect = 0x40; + +static const UCHAR SiS300_SoftSetting = 0x30; + +#ifndef LINUX_XF86 +static UCHAR SiS300_SR07 = 0x10; +#endif + +static const UCHAR SiS300_SR15[8][4] = +{ + {0x01,0x09,0xa3,0x00}, + {0x43,0x43,0x43,0x00}, + {0x1e,0x1e,0x1e,0x00}, + {0x2a,0x2a,0x2a,0x00}, + {0x06,0x06,0x06,0x00}, + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00} +}; + +#ifndef LINUX_XF86 +static UCHAR SiS300_SR1F = 0x00; +static UCHAR SiS300_SR21 = 0x16; +static UCHAR SiS300_SR22 = 0xb2; +static UCHAR SiS300_SR23 = 0xf6; +static UCHAR SiS300_SR24 = 0x0d; +static UCHAR SiS300_SR25[] = {0x0,0x0}; +static UCHAR SiS300_SR31 = 0x00; +static UCHAR SiS300_SR32 = 0x11; +static UCHAR SiS300_SR33 = 0x00; +static UCHAR SiS300_CRT2Data_1_2 = 0x40; +static UCHAR SiS300_CRT2Data_4_D = 0x00; +static UCHAR SiS300_CRT2Data_4_E = 0x00; +static UCHAR SiS300_CRT2Data_4_10 = 0x80; + +static const USHORT SiS300_RGBSenseData = 0xd1; +static const USHORT SiS300_VideoSenseData = 0xb3; +static const USHORT SiS300_YCSenseData = 0xb9; +static const USHORT SiS300_RGBSenseData2 = 0x0190; /*301b*/ +static const USHORT SiS300_VideoSenseData2 = 0x0174; +static const USHORT SiS300_YCSenseData2 = 0x016b; + +static const UCHAR SiS300_CR40[5][4]; + +static UCHAR SiS300_CR49[2]; +#endif + +static const UCHAR SiS300_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* TW: Was {0x21,0xed,0x8a,0x08}; */ +static const UCHAR SiS300_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* TW: Was {0x2a,0x05,0xd3,0x00}; */ +static const UCHAR SiS300_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /* palmn */ +static const UCHAR SiS300_PALNPhase[] = {0x21,0xF4,0x3E,0xBA}; +static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6}; /* 301b */ +static const UCHAR SiS300_PALPhase2[] = {0x2a,0x09,0x86,0xe9}; /* 301b */ +static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/ +static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/ + +typedef struct _SiS300_PanelDelayTblStruct +{ + UCHAR timer[2]; +} SiS300_PanelDelayTblStruct; + +static const SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] = +{ + {{0x05,0xaa}}, /* TW: From 2.04.5a */ + {{0x05,0x14}}, + {{0x05,0x36}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x05,0x90}}, + {{0x05,0x90}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x20,0x80}}, + {{0x05,0x14}}, + {{0x05,0x40}}, + {{0x05,0x60}} +}; + +static const SiS300_PanelDelayTblStruct SiS300_PanelDelayTblLVDS[] = +{ + {{0x05,0xaa}}, + {{0x05,0x14}}, + {{0x05,0x36}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x05,0x90}}, + {{0x05,0x90}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x05,0x14}}, + {{0x05,0x14}}, /* 2.07a (JVC): 14,96 */ + {{0x05,0x28}}, /* 2.04.5c: 20, 80 - Clevo (2.04.2c): 05, 28 */ + {{0x05,0x14}}, + {{0x05,0x14}}, /* Some BIOSes: 05, 40 */ + {{0x05,0x60}} +}; + +typedef struct _SiS300_LCDDataStruct +{ + USHORT RVBHCMAX; + USHORT RVBHCFACT; + USHORT VGAHT; + USHORT VGAVT; + USHORT LCDHT; + USHORT LCDVT; +} SiS300_LCDDataStruct; + +static const SiS300_LCDDataStruct SiS300_StLCD1024x768Data[] = +{ + { 66, 31, 992, 510,1320, 816}, + { 66, 31, 992, 510,1320, 816}, + { 176, 75, 900, 510,1320, 816}, + { 176, 75, 900, 510,1320, 816}, + { 66, 31, 992, 510,1320, 816}, + { 27, 16,1024, 650,1350, 832}, + { 1, 1,1344, 806,1344, 806} +}; + +static const SiS300_LCDDataStruct SiS300_ExtLCD1024x768Data[] = +{ + { 12, 5, 896, 512,1344, 806}, + { 12, 5, 896, 510,1344, 806}, + { 32, 15,1008, 505,1344, 806}, + { 32, 15,1008, 514,1344, 806}, + { 12, 5, 896, 500,1344, 806}, + { 42, 25,1024, 625,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 12, 5, 896, 500,1344, 806}, + { 42, 25,1024, 625,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 12, 5, 896, 500,1344, 806}, + { 42, 25,1024, 625,1344, 806}, + { 1, 1,1344, 806,1344, 806} +}; + +static const SiS300_LCDDataStruct SiS300_St2LCD1024x768Data[] = +{ + { 62, 25, 800, 546,1344, 806}, + { 32, 15, 930, 546,1344, 806}, + { 32, 15, 930, 546,1344, 806}, + { 104, 45, 945, 496,1344, 806}, + { 62, 25, 800, 546,1344, 806}, + { 31, 18,1008, 624,1344, 806}, + { 1, 1,1344, 806,1344, 806} +}; + +static const SiS300_LCDDataStruct SiS300_StLCD1280x1024Data[] = +{ + { 4, 1, 880, 510,1650,1088}, + { 4, 1, 880, 510,1650,1088}, + { 176, 45, 900, 510,1650,1088}, + { 176, 45, 900, 510,1650,1088}, + { 4, 1, 880, 510,1650,1088}, + { 13, 5,1024, 675,1560,1152}, + { 16, 9,1266, 804,1688,1072}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS300_LCDDataStruct SiS300_ExtLCD1280x1024Data[] = +{ + { 211, 60,1024, 501,1688,1066}, + { 211, 60,1024, 508,1688,1066}, + { 211, 60,1024, 501,1688,1066}, + { 211, 60,1024, 508,1688,1066}, + { 211, 60,1024, 500,1688,1066}, + { 211, 75,1024, 625,1688,1066}, + { 211, 120,1280, 798,1688,1066}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS300_LCDDataStruct SiS300_St2LCD1280x1024Data[] = +{ + { 22, 5, 800, 510,1650,1088}, + { 22, 5, 800, 510,1650,1088}, + { 176, 45, 900, 510,1650,1088}, + { 176, 45, 900, 510,1650,1088}, + { 22, 5, 800, 510,1650,1088}, + { 13, 5,1024, 675,1560,1152}, + { 16, 9,1266, 804,1688,1072}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS300_LCDDataStruct SiS300_NoScaleData1024x768[] = +{ + { 1, 1, 800, 449, 800, 449}, + { 1, 1, 800, 449, 800, 449}, + { 1, 1, 900, 449, 900, 449}, + { 1, 1, 900, 449, 900, 449}, + { 1, 1, 800, 525, 800, 525}, + { 1, 1,1056, 628,1056, 628}, + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS300_LCDDataStruct SiS300_NoScaleData1280x1024[] = /* TW: Fake */ +{ + { 1, 1, 800, 449, 800, 449}, + { 1, 1, 800, 449, 800, 449}, + { 1, 1, 900, 449, 900, 449}, + { 1, 1, 900, 449, 900, 449}, + { 1, 1, 800, 525, 800, 525}, + { 1, 1,1056, 628,1056, 628}, + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS300_LCDDataStruct SiS300_LCD1280x960Data[] = +{ + { 9, 2, 800, 500,1800,1000}, + { 9, 2, 800, 500,1800,1000}, + { 4, 1, 900, 500,1800,1000}, + { 4, 1, 900, 500,1800,1000}, + { 9, 2, 800, 500,1800,1000}, + { 30, 11,1056, 625,1800,1000}, + { 5, 3,1350, 800,1800,1000}, + { 1, 1,1576,1050,1576,1050}, + { 1, 1,1800,1000,1800,1000} +}; + +static const SiS300_LCDDataStruct SiS300_ExtLCD1400x1050Data[] = /* TW: New */ +{ + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 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 const SiS300_LCDDataStruct SiS300_ExtLCD1600x1200Data[] = /* TW: New */ +{ + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 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 const SiS300_LCDDataStruct SiS300_StLCD1400x1050Data[] = /* TW: New */ +{ + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 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 const SiS300_LCDDataStruct SiS300_StLCD1600x1200Data[] = /* TW: New */ +{ + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 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 const SiS300_LCDDataStruct SiS300_NoScaleData1400x1050[] = /* TW: New */ +{ + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 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 const SiS300_LCDDataStruct SiS300_NoScaleData1600x1200[] = /* TW: New */ +{ + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0} +}; + + +typedef struct _SiS300_TVDataStruct +{ + USHORT RVBHCMAX; + USHORT RVBHCFACT; + USHORT VGAHT; + USHORT VGAVT; + USHORT TVHDE; + USHORT TVVDE; + USHORT RVBHRS; + UCHAR FlickerMode; + USHORT HALFRVBHRS; + UCHAR RY1COE; + UCHAR RY2COE; + UCHAR RY3COE; + UCHAR RY4COE; +} SiS300_TVDataStruct; + +static const SiS300_TVDataStruct SiS300_StPALData[] = +{ + { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, + { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, + { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22} +}; + +static const SiS300_TVDataStruct SiS300_ExtPALData[] = +{ + { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, + { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, + { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18}, + { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a}, + { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, + { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, + { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, + { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} + +}; + +static const SiS300_TVDataStruct SiS300_StNTSCData[] = +{ + { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, + { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18} +}; + +static const SiS300_TVDataStruct SiS300_ExtNTSCData[] = +{ + { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, + { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, + { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18}, + { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a}, + { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, + { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, + { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, + { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xf1,0x04,0x1f,0x18} +}; + +static const SiS_TVDataStruct SiS300_St1HiTVData[] = +{ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +static const SiS_TVDataStruct SiS300_St2HiTVData[] = +{ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +static const SiS_TVDataStruct SiS300_ExtHiTVData[] = +{ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +static const UCHAR SiS300_NTSCTiming[] = +{ + 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c, + 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a, + 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b, + 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17, /* (in 2.06.50) */ +/* 0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17, (in 2.04.5a) */ + 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02, /* (in 2.06.50) */ +/* 0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02, (in 2.04.5a) */ + 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50, + 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00 +}; + +static const UCHAR SiS300_PALTiming[] = +{ + 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70, + 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b, + 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17, /* (in 2.06.50) */ +/* 0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17, (in 2.04.5a) */ + 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02, /* (in 2.06.50) */ +/* 0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02, (in 2.04.5a) */ + 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63, + 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00 +}; + +#ifdef oldHV +static const UCHAR SiS300_HiTVExtTiming[] = /* TW: New */ +{ + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, + 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, + 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, + 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 +}; + +static const UCHAR SiS300_HiTVSt1Timing[] = /* TW: New */ +{ + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03, + 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10, + 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86, + 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00 +}; + +static const UCHAR SiS300_HiTVSt2Timing[] = /* TW: New */ +{ + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, + 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, + 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, + 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 +}; + +static const UCHAR SiS300_HiTVTextTiming[] = /* TW: New */ +{ + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03, + 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20, + 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96, + 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00 +}; + +static const UCHAR SiS300_HiTVGroup3Data[] = /* TW: New */ +{ + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f, + 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9, + 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; + +static const UCHAR SiS300_HiTVGroup3Simu[] = /* TW: New */ +{ + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95, + 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4, + 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; + +static const UCHAR SiS300_HiTVGroup3Text[] = /* TW: New */ +{ + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7, + 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca, + 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; +#endif + +typedef struct _SiS300_LVDSDataStruct +{ + USHORT VGAHT; + USHORT VGAVT; + USHORT LCDHT; + USHORT LCDVT; +} SiS300_LVDSDataStruct; + +static const SiS300_LVDSDataStruct SiS300_LVDS320x480Data_1[] = +{ + {848, 433,400, 525}, + {848, 389,400, 525}, + {848, 433,400, 525}, + {848, 389,400, 525}, + {848, 518,400, 525}, + {1056,628,400, 525}, + {400, 525,400, 525}, + {800, 449,1000, 644}, + {800, 525,1000, 635} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS800x600Data_1[] = +{ + {848, 433,1060, 629}, + {848, 389,1060, 629}, + {848, 433,1060, 629}, + {848, 389,1060, 629}, + {848, 518,1060, 629}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {800, 449,1000, 644}, + {800, 525,1000, 635} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS800x600Data_2[] = +{ + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {800, 449,1000, 644}, + {800, 525,1000, 635} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_1[] = +{ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1024x768Data_2[] = +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_1[] = +{ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1280x1024Data_2[] = +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1400x1050Data_1[] = /* TW: New */ +{ + {928, 416, 1688, 1066}, + {928, 366, 1688, 1066}, + {928, 416, 1688, 1066}, + {928, 366, 1688, 1066}, + {928, 496, 1688, 1066}, + {1088, 616, 1688, 1066}, + {1312, 784, 1688, 1066}, + {1568, 1040, 1688, 1066}, + {1688, 1066, 1688, 1066} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1400x1050Data_2[] = /* TW: New */ +{ + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1280x768Data_1[]= /* TW: New - TODO */ +{ /* TW: Temp data, invalid (is identical to 1024x768) */ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1280x768Data_2[]= /* TW: New - TODO */ +{ /* TW: Temp data, invalid (is identical to 1024x768) */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New: */ +static const SiS300_LVDSDataStruct SiS300_LVDS1024x600Data_1[] = +{ + {840, 604,1344, 800}, + {840, 560,1344, 800}, + {840, 604,1344, 800}, + {840, 560,1344, 800}, + {840, 689,1344, 800}, + {1050, 800,1344, 800}, + {1344, 800,1344, 800}, + {800, 449,1280, 789}, + {800, 525,1280, 785} +}; + +/* TW: New: */ +static const SiS300_LVDSDataStruct SiS300_LVDS1024x600Data_2[] = +{ + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New: */ +static const SiS300_LVDSDataStruct SiS300_LVDS1152x768Data_1[] = +{ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New: */ +static const SiS300_LVDSDataStruct SiS300_LVDS1152x768Data_2[] = +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New in 650/LVDS BIOS - 1:1 */ +static const SiS300_LVDSDataStruct SiS300_LVDSXXXxXXXData_1[] = /* TW: New */ +{ + { 800, 449, 800, 449}, + { 800, 449, 800, 449}, + { 900, 449, 900, 449}, + { 900, 449, 900, 449}, + { 800, 525, 800, 525}, + {1056, 628,1056, 628}, + {1344, 806,1344, 806}, + {1688, 806,1688, 806} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS640x480Data_1[] = +{ + {800, 449, 800, 449}, + {800, 449, 800, 449}, + {800, 449, 800, 449}, + {800, 449, 800, 449}, + {800, 525, 800, 525}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1280x960Data_1[] = /* TW: New */ +{ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LVDS1280x960Data_2[] = /* TW: New */ +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LCDA1400x1050Data_1[] = /* TW: New */ +{ /* TW: Might be temporary (invalid) data */ + {928, 416, 1688, 1066}, + {928, 366, 1688, 1066}, + {1008, 416, 1688, 1066}, + {1008, 366, 1688, 1066}, + {1200, 530, 1688, 1066}, + {1088, 616, 1688, 1066}, + {1312, 784, 1688, 1066}, + {1568, 1040, 1688, 1066}, + {1688, 1066, 1688, 1066} +}; + +static const SiS300_LVDSDataStruct SiS300_LCDA1400x1050Data_2[] = /* TW: New */ +{ /* TW: Temporary data. Not valid */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LCDA1600x1200Data_1[] = /* TW: New */ +{ /* TW: Temporary data. Not valid */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS300_LVDSDataStruct SiS300_LCDA1600x1200Data_2[] = /* TW: New */ +{ /* TW: Temporary data. Not valid */ + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; + + +/* TW: New: */ +static const SiS300_LVDSDataStruct SiS300_CHTVUNTSCData[] = +{ + {840, 600, 840, 600}, + {840, 600, 840, 600}, + {840, 600, 840, 600}, + {840, 600, 840, 600}, + {784, 600, 784, 600}, + {1064, 750,1064, 750} +}; + +static const SiS300_LVDSDataStruct SiS300_CHTVONTSCData[] = +{ + {840, 525, 840, 525}, + {840, 525, 840, 525}, + {840, 525, 840, 525}, + {840, 525, 840, 525}, + {784, 525, 784, 525}, + {1040, 700,1040, 700} +}; + +static const SiS300_LVDSDataStruct SiS300_CHTVUPALData[] = +{ + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {840, 750, 840, 750}, + {936, 836, 936, 836} +}; + +static const SiS300_LVDSDataStruct SiS300_CHTVOPALData[] = +{ + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {840, 625, 840, 625}, + {960, 750, 960, 750} +}; + +static const SiS300_LVDSDataStruct SiS300_CHTVSOPALData[] = +{ + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {840, 500, 840, 500}, + {944, 625, 944, 625} +}; + +/* TW: new end */ + +typedef struct _SiS300_LVDSDesStruct +{ + USHORT LCDHDES; + USHORT LCDVDES; +} SiS300_LVDSDesStruct; + +static const SiS300_LVDSDesStruct SiS300_PanelType00_1[] = +{ + {0, 626}, + {0, 624}, + {0, 626}, + {0, 624}, + {0, 624}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType01_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType02_1[] = +{ + {0, 626}, + {0, 624}, + {0, 626}, + {0, 624}, + {0, 624}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType03_1[] = +{ + { 8, 436}, + { 8, 440}, + { 8, 436}, + { 8, 440}, + { 8, 512}, + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType04_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType05_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType06_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType07_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType08_1[] = +{ + {1059, 626}, + {1059, 624}, + {1059, 626}, + {1059, 624}, + {1059, 624}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType09_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0a_1[] = +{ + {1059, 626}, + {1059, 624}, + {1059, 626}, + {1059, 624}, + {1059, 624}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0b_1[] = +{ + {1343, 0}, + {1343, 0}, + {1343, 0}, + {1343, 0}, + {1343, 0}, /* 640x480 - BIOS 1343, 0 */ + {1343, 0}, + { 0, 799}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0c_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0d_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0e_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, /* 640x480 */ + {1343, 0}, /* 800x600 */ + { 0, 805}, /* 1024x768 */ + { 0, 794}, /* 1280x1024 */ + { 0, 0} /* 1280x960 - not applicable */ +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0f_1[] = +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType00_2[] = +{ + {976, 527}, + {976, 502}, + {976, 527}, + {976, 502}, + {976, 567}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType01_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType02_2[] = +{ + {976, 527}, + {976, 502}, + {976, 527}, + {976, 502}, + {976, 567}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType03_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + {1152, 622}, + {1152, 597} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType04_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType05_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType06_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType07_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType08_2[] = +{ + {976, 527}, + {976, 502}, + {976, 527}, + {976, 502}, + {976, 567}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType09_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0a_2[] = +{ + {976, 527}, + {976, 502}, + {976, 527}, + {976, 502}, + {976, 567}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0b_2[] = +{ + { 1152, 700}, + { 1152, 675}, + { 1152, 700}, + { 1152, 675}, + { 1152, 740}, + { 1232, 799}, + { 0, 799}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0c_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0d_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0e_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType0f_2[] = +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] = /* TW: New */ +{ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] = /* TW: New */ +{ + { 1152, 622 }, + { 1152, 597 }, + { 1152, 622 }, + { 1152, 597 }, + { 1152, 622 }, + { 1232, 722 }, + { 0, 0 }, + { 0, 794 }, + { 0, 0 } +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] = /* TW: New */ +{ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] = /* TW: New */ +{ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] = /* TW: New */ +{ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] = /* TW: New */ +{ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + + +/* TW: New */ +static const SiS300_LVDSDesStruct SiS300_CHTVUNTSCDesData[] = +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_CHTVONTSCDesData[] = +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_CHTVUPALDesData[] = +{ + {256, 0}, + {256, 0}, + {256, 0}, + {256, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS300_LVDSDesStruct SiS300_CHTVOPALDesData[] = +{ + {256, 0}, + {256, 0}, + {256, 0}, + {256, 0}, + { 0, 0}, + { 0, 0} +}; +/* TW: New end */ + +/* TW: New for SiS300+301LV */ +typedef struct _SiS300_Part2PortTblStruct +{ + UCHAR CR[12]; +} SiS300_Part2PortTblStruct; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] = +{ /* VESA Timing */ + {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}}, + {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}}, + {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}, + {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}, + {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] = +{ /* TW: Temporary data, invalid */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_1[] = +{ /* TW: Temporary data, invalid */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_1[] = +{ /* TW: Temporary data, invalid */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] = +{ /* Non-VESA */ + {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, + {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, + {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, + {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, + {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, + {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, + {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] = +{ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_2[] = +{ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_2[] = +{ /* TW: Temporary data, invalid */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] = +{ /* TW: Temporary data, invalid */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] = +{ /* TW: Temporary data, invalid */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_3[] = +{ /* TW: Temporary data, invalid */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_3[] = +{ /* TW: Temporary data, invalid */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +typedef struct _SiS300_LVDSCRT1DataStruct +{ +UCHAR CR[15]; +} SiS300_LVDSCRT1DataStruct; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] = +{ + {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, + 0x00 }}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] = +{ + {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, + 0x00}}, + {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] = +{ + {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, + 0x00 }}, + {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, + 0x01 }}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] = +{ + {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x04, + 0x00 }}, + {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04, + 0x00 }}, + {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x04, + 0x00 }}, + {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04, + 0x00 }}, + {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04, + 0x00 }}, + {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x05, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] = +{ + {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00 }}, + {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f, + 0x60,0x87,0x5D,0x83,0x01,0x00,0x44, + 0x00}}, + {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f, + 0x60,0x87,0x5D,0x83,0x01,0x00,0x44, + 0x00}}, + {{0x37,0x27,0x9B,0x2b,0x94,0x04,0x3e, + 0xE2,0x89,0xDf,0x05,0x00,0x00,0x44, + 0x00}}, + {{0x41,0x31,0x85,0x35,0x1d,0x7c,0xf0, + 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55, + 0x01}}, + {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5, + 0x02,0x88,0xFf,0x25,0x10,0x00,0x01, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] = +{ + {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x04, + 0x00 }}, + {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x04, + 0x00 }}, + {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x04, + 0x00 }}, + {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x04, + 0x00 }}, + {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x04, + 0x00 }}, + {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, + 0x01 }}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] = +{ + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, + 0xf4,0x88,0x8f,0x73,0x20,0x00,0x06, + 0x00 }}, + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, + 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06, + 0x00 }}, + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, + 0xf4,0x88,0x8f,0x73,0x20,0x00,0x06, + 0x00 }}, + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, + 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06, + 0x00 }}, + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba, + 0x1c,0x80,0xdf,0x73,0x00,0x00,0x06, + 0x00 }}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01 }}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01 }}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] = +{ + {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, + 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05, + 0x00 }}, + {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, + 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05, + 0x00 }}, + {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e, + 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05, + 0x00 }}, + {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e, + 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05, + 0x00 }}, + {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba, + 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05, + 0x00 }}, + {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x05, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] = +{ + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x01, + 0x01 }}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] = +{ + {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x01, + 0x01 }}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_1[] = +{ + {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, + 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, + 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, + 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, + 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba, + 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01, + 0x00}}, + {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1, + 0xae,0x85,0x57,0x1f,0x30,0x00,0x26, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1, + 0xae,0x85,0x57,0x1f,0x30,0x00,0x02, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_1_H[] = +{ + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, + 0x00}}, + {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x600_2_H[] = +{ + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x01, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_1[] = +{ + {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, + 0x00}}, + {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_1_H[] = +{ + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, + 0x00}}, + {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11152x768_2_H[] = +{ + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x01, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +/* TW: New */ +static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] = +{ + {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, + 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, + 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, + 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, + 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01, + 0x00 }}, + {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba, + 0x18,0x84,0xdf,0x57,0x00,0x00,0x01, + 0x00 }}, + {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0, + 0x90,0x8c,0x57,0xed,0x20,0x00,0x06, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] = +{ + {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e, + 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e, + 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e, + 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e, + 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01, + 0x00 }}, + {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e, + 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01, + 0x00 }}, + {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0, + 0x7f,0x86,0x57,0xbb,0x00,0x00,0x06, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] = +{ + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba, + 0x50,0x84,0xdf,0xed,0x00,0x00,0x05, + 0x00 }}, + {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1, + 0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] = +{ + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba, + 0x20,0x83,0xdf,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0, + 0x90,0x8c,0x57,0xed,0x20,0x00,0x05, + 0x01 }} +}; + +static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] = +{ + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba, /* TODO */ + 0x20,0x83,0xdf,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0, /* TODO */ + 0x90,0x8c,0x57,0xed,0x20,0x00,0x05, + 0x01 }} +}; +/* TW: New end */ + +/* TW: New */ +typedef struct _SiS300_CHTVRegDataStruct +{ + UCHAR Reg[16]; +} SiS300_CHTVRegDataStruct; + +static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] = +{ + {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x6a,0x6a,0x00,0x2d,0xfa,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 17: 640x480 NTSC 7/8 */ + {{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 24: 800x600 NTSC 7/10 */ +}; + +static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] = +{ + {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x69,0x6a,0x00,0x1e,0xfd,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 16: 640x480 NTSC 1/1 */ + {{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 23: 800x600 NTSC 3/4 */ +}; + +static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] = +{ + {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x63,0x94,0x01,0x50,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 15: 640x480 PAL 5/6 */ + {{0x84,0x64,0x01,0x4e,0x2f,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 21: 800x600 PAL 3/4 */ + +}; + +static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] = +{ + {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */ + {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x61,0x94,0x01,0x36,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 14: 640x480 PAL 1/1 */ + {{0x83,0x76,0x01,0x40,0x31,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 20: 800x600 PAL 5/6 */ + +}; + +static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] = +{ + {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 5/4 */ + {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, + {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */ + {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* TW: Mode 19: 800x600 PAL 1/1 */ +}; +/* TW: New end */ + +/* TW: New */ +static const UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e}; + +static const UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b}; + +static const UCHAR SiS300_CHTVVCLKSONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b}; + +static const UCHAR SiS300_CHTVVCLKUPAL[] = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31}; + +static const UCHAR SiS300_CHTVVCLKOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x30,0x32}; + +static const UCHAR SiS300_CHTVVCLKSOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x36,0x29}; +/* TW: New end */ + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h new file mode 100644 index 000000000..5bb9d772a --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h @@ -0,0 +1,4673 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/310vtbl.h,v 1.5 2003/02/10 01:14:16 tsi Exp $ */ + + +/* Register settings for SiS 310/325 series */ + + +typedef struct _SiS310_StStruct +{ + UCHAR St_ModeID; + USHORT St_ModeFlag; + UCHAR St_StTableIndex; + UCHAR St_CRT2CRTC; + UCHAR St_ResInfo; + UCHAR VB_StTVFlickerIndex; + UCHAR VB_StTVEdgeIndex; + UCHAR VB_StTVYFilterIndex; +} SiS310_StStruct; + +static const SiS310_StStruct SiS310_SModeIDTable[]= +{ + {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00}, + {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00}, + {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01}, + {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02}, + {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02}, + {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03}, + {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04}, + {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05}, + {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03}, + {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03}, + {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04}, + {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05}, + {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05}, + {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05}, + {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05}, + {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05}, + {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04}, + {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05}, + {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05}, + {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +typedef struct _SiS310_StandTableStruct +{ + UCHAR CRT_COLS; + UCHAR ROWS; + UCHAR CHAR_HEIGHT; + USHORT CRT_LEN; + UCHAR SR[4]; + UCHAR MISC; + UCHAR CRTC[0x19]; + UCHAR ATTR[0x14]; + UCHAR GRC[9]; +} SiS310_StandTableStruct; + +static const SiS310_StandTableStruct SiS310_StandTable[]= +{ +/* MD_0_200 */ + { + 0x28,0x18,0x08,0x0800, + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_1_200 */ + { + 0x28,0x18,0x08,0x0800, + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_2_200 */ + { + 0x50,0x18,0x08,0x1000, + {0x01,0x03,0x00,0x02}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_3_200 */ + { + 0x50,0x18,0x08,0x1000, + {0x01,0x03,0x00,0x02}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_4 */ + { + 0x28,0x18,0x08,0x4000, + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, + 0xff}, + {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x03,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, + 0xff} + }, +/* MD_5 */ + { + 0x28,0x18,0x08,0x4000, + {0x09,0x03,0x00,0x02}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2, + 0xff}, + {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x03,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00, + 0xff} + }, +/* MD_6 */ + { + 0x50,0x18,0x08,0x4000, + {0x01,0x01,0x00,0x06}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2, + 0xff}, + {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17, + 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, + 0x01,0x00,0x01,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00, + 0xff} + }, +/* MD_7 */ + { + 0x50,0x18,0x0e,0x1000, + {0x00,0x03,0x00,0x03}, + 0xa6, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3, + 0xff}, + {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x0e,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, + 0xff} + }, +/* MDA_DAC */ + { + 0x00,0x00,0x00,0x0000, + {0x00,0x00,0x00,0x15}, + 0x15, + {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00, + 0x00}, + {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15}, + {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x3f} + }, +/* CGA_DAC */ + { + 0x00,0x10,0x04,0x0114, + {0x11,0x09,0x15,0x00}, + 0x10, + {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a, + 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a, + 0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10, + 0x04}, + {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04, + 0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e, + 0x3e,0x2b,0x3b,0x2f}, + {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, + 0x3f} + }, +/* EGA_DAC */ + { + 0x00,0x10,0x04,0x0114, + {0x11,0x05,0x15,0x20}, + 0x30, + {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18, + 0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38, + 0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12, + 0x06}, + {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26, + 0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e, + 0x1e,0x0b,0x1b,0x0f}, + {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f, + 0x3f} + }, +/* VGA_DAC */ + { + 0x00,0x10,0x04,0x0114, + {0x11,0x09,0x15,0x2a}, + 0x3a, + {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05, + 0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20, + 0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10, + 0x1f}, + {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d, + 0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15, + 0x1c,0x0e,0x11,0x15}, + {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00, + 0x04} + }, + { + 0x08,0x0c,0x10,0x0a08, + {0x0c,0x0e,0x10,0x0b}, + 0x0c, + {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00, + 0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00, + 0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00, + 0x06}, + {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08, + 0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00, + 0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00} + }, +/* MD_D */ + { + 0x28,0x18,0x08,0x2000, + {0x09,0x0f,0x00,0x06}, + 0x63, + {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} + }, +/* MD_E */ + { + 0x50,0x18,0x08,0x4000, + {0x01,0x0f,0x00,0x06}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} + }, +/* ExtVGATable */ + { + 0x00,0x00,0x00,0x0000, + {0x01,0x0f,0x00,0x0e}, + 0x23, + {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x01,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, + 0xff} + }, +/* ROM_SAVEPTR */ + { + 0x9f,0x3b,0x00,0x00c0, + {0x00,0x00,0x00,0x00}, + 0x00, + {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f, + 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0, + 0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00} + }, +/* MD_F */ + { + 0x50,0x18,0x0e,0x8000, + {0x01,0x0f,0x00,0x06}, + 0xa2, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, + 0xff}, + {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00, + 0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00, + 0x0b,0x00,0x05,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05, + 0xff} + }, +/* MD_10 */ + { + 0x50,0x18,0x0e,0x8000, + {0x01,0x0f,0x00,0x06}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} + }, +/* MD_0_350 */ + { + 0x28,0x18,0x0e,0x0800, + {0x09,0x03,0x00,0x02}, + 0xa3, + {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_1_350 */ + { + 0x28,0x18,0x0e,0x0800, + {0x09,0x03,0x00,0x02}, + 0xa3, + {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_2_350 */ + { + 0x50,0x18,0x0e,0x1000, + {0x01,0x03,0x00,0x02}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_3_350 */ + { + 0x50,0x18,0x0e,0x1000, + {0x01,0x03,0x00,0x02}, + 0xa3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00, + 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x08,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_0_1_400 */ + { + 0x28,0x18,0x10,0x0800, + {0x08,0x03,0x00,0x02}, + 0x67, + {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f, + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x0c,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_2_3_400 */ + { + 0x50,0x18,0x10,0x1000, + {0x00,0x03,0x00,0x02}, + 0x67, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x0c,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, + 0xff} + }, +/* MD_7_400 */ + { + 0x50,0x18,0x10,0x1000, + {0x00,0x03,0x00,0x02}, + 0x66, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x0e,0x00,0x0f,0x08}, + {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00, + 0xff} + }, +/* MD_11 */ + { + 0x50,0x1d,0x10,0xa000, + {0x01,0x0f,0x00,0x06}, + 0xe3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3, + 0xff}, + {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01, + 0xff} + }, +/* ExtEGATable */ + { + 0x50,0x1d,0x10,0xa000, + {0x01,0x0f,0x00,0x06}, + 0xe3, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x01,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, + 0xff} + }, +/* MD_13 */ + { + 0x28,0x18,0x08,0x2000, + {0x01,0x0f,0x00,0x0e}, + 0x63, + {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00, + 0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3, + 0xff}, + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x41,0x00,0x0f,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, + 0xff} + } +}; + +typedef struct _SiS310_ExtStruct +{ + UCHAR Ext_ModeID; + USHORT Ext_ModeFlag; + USHORT Ext_ModeInfo; + USHORT Ext_Point; /* TW: Address of table entry in (older) BIOS image */ + USHORT Ext_VESAID; + UCHAR Ext_VESAMEMSize; + UCHAR Ext_RESINFO; + UCHAR VB_ExtTVFlickerIndex; + UCHAR VB_ExtTVEdgeIndex; + UCHAR VB_ExtTVYFilterIndex; + UCHAR REFindex; +} SiS310_ExtStruct; + +/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */ +static const SiS310_ExtStruct SiS310_EModeIDTable[]= +{ + {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x? */ + {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x8 */ +/* {0x2e,0x021b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08}, */ /* 640x480x8 - 650/LVDS BIOS (no CRt2Mode) */ + {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10}, /* 640x400x8 */ +/* {0x2f,0x021b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10}, */ /* 640x400x8 - 650/LVDS BIOS (no CRt2Mode) */ + {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x8 */ +/* {0x30,0x221b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00}, */ /* 800x600x8 - 650/LVDS BIOS (no CRt2Mode) */ +/* {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, */ /* 720x480x8 */ + {0x31,0x0a1b,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x8 BIOS (301/LVDS) */ + {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x8 */ + {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x16 */ + {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x16 */ + {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11}, /* 720x480x32 */ + {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12}, /* 720x576x32 */ + {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x? */ + {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x8 */ +/* {0x38,0x021b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13}, */ /* 1024x768x8 - 650/LVDS BIOS (no CRt2Mode) */ + {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */ +/* {0x3a,0x063b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a}, */ /* 1280x1024x8 - 650/LVDS BIOS*/ + {0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */ +/* {0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e}, */ /* 1600x1200x8 - 650/LVDS BIOS */ + {0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */ + {0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25}, + {0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25}, + {0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08}, + {0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x16 */ + {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00}, + {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x16 */ + {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13}, + {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x16 */ + {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a}, + {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */ + {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26}, +/* {0x50,0x921b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26}, */ /* 650/LVDS BIOS */ + {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27}, +/* {0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, */ + {0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, /* 650/301 BIOS */ +/* {0x52,0xb21b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28}, */ /* 650/LVDS BIOS (no CRT2Mode) */ + {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26}, + {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27}, +/* {0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28}, */ + {0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28}, /* BIOS (301+LVDS) */ + {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25}, +/* {0x59,0x921b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25}, */ /* 650/LVDS BIOS (no CRT2Mode) */ + {0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f}, /* 320x480x8 fstn add new mode*/ + {0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f}, /* 320x480x16 fstn add new mode*/ + {0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28}, /* TW: inserted 512x384x32 */ + {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10}, + {0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10}, /* TW: Inserted 640x400x32 */ + {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08}, /* 640x480x32 */ + {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00}, /* 800x600x32 */ + {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13}, /* 1024x768x32 */ + {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */ + {0x66,0x06ff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */ + {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */ + {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */ + {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */ + {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */ + {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */ + {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */ + {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x8 */ + {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x8 */ + {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x16 */ + {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x16 */ + {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x32 */ + {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37}, /* 1024x576x32 */ + {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x32 */ + {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a}, /* 1280x720x8 */ + {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34}, /* 800x480x16 */ + {0x7c,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x8 - TW */ + {0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x16 - TW */ + {0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d}, /* 1280x960x32 - TW */ + /* TW: 650/LVDS BIOS new modes */ +/* {0x23,0x063b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, */ /* 1280x768x8 - 650/LVDS BIOS */ + {0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x8 */ + {0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x16 */ + {0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40}, /* 1280x768x32 */ + {0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */ +/* {0x26,0x063b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, */ /* 1400x1050x8 - 650/LVDS BIOS */ + {0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */ + {0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/ + {0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43}, /* TW: NEW 1152x864 - not in BIOS */ + {0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43}, + {0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43}, + {0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45}, /* TW: NEW 848x480 - not in BIOS */ + {0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45}, + {0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45}, + {0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47}, /* TW: NEW 856x480 - not in BIOS */ + {0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47}, + {0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47}, + {0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49}, /* TW: NEW 1360x768 - not in BIOS */ + {0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49}, + {0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49}, + {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +typedef struct _SiS310_Ext2Struct +{ + USHORT Ext_InfoFlag; + UCHAR Ext_CRT1CRTC; + UCHAR Ext_CRTVCLK; + UCHAR Ext_CRT2CRTC; + UCHAR ModeID; + USHORT XRes; + USHORT YRes; + USHORT ROM_OFFSET; +} SiS310_Ext2Struct; + +static const SiS310_Ext2Struct SiS310_RefIndex[]= +{ +/* {0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, 0x0 - TW: Patch for Chrontel 7019 */ + {0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */ + {0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */ + {0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */ + {0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */ + {0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */ + {0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */ + {0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */ + {0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */ +/* {0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, 0x8 - TW: Patch for Chrontel 7019 */ + {0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */ + {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */ + {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */ + {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */ + {0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */ + {0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */ + {0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */ + {0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */ + {0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */ + {0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */ + {0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */ + {0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */ + {0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 301b TV1024x768*/ + {0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */ + {0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */ + {0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */ + {0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */ + {0x0047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */ + {0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */ + {0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */ + {0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */ + {0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */ + {0x0007,0x20,0x21,0x00,0x3c,1600,1200,0x3af2}, /* 0x1e */ + {0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */ + {0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */ + {0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */ + {0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */ + {0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */ + {0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */ + {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */ + {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */ + {0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */ + {0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */ + {0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */ + {0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */ + {0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */ + {0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */ + {0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */ + {0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */ + {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */ + {0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */ + {0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */ + {0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */ + {0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */ + {0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */ + {0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */ + {0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */ + {0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */ + {0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */ + {0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */ + {0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */ + {0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */ + {0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */ + {0x0027,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */ + {0x0047,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */ + {0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */ /* FSTN mode */ + {0x0077,0x42,0x12,0x07,0x23,1280, 768,0x0000}, /* 0x40 */ /* TW: 650/LVDS/301LVx new mode */ + {0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */ /* TW: 650/LVDS/301LVx new mode */ + {0x0067,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */ /* TW: new, not in any BIOS */ + {0x0047,0x44,0x19,0x06,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */ + {0x0047,0x4a,0x1e,0x06,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */ + {0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */ + {0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz - Non-BIOS, new */ + {0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */ + {0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz - Non-BIOS, new */ + {0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */ + {0xffff,0x00,0x00,0x00,0x00, 0, 0,0x0000} +}; + +typedef struct _SiS310_CRT1TableStruct +{ + UCHAR CR[17]; +} SiS310_CRT1TableStruct; + +static const SiS310_CRT1TableStruct SiS310_CRT1Table[]= +{ + {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, /* 0x0 */ + {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, + 0x00}}, /* 0x1 */ + {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, + 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05, + 0x01}}, /* 0x2 */ + {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, + 0x01}}, /* 0x3 */ + {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, /* 0x4 */ +#if 0 + {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, + 0x00}}, /* 0x5 */ +#endif + {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */ + 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05, + 0x00}}, +#if 0 + {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e, + 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01, + 0x00}}, /* 0x6 */ +#endif + {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */ + 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f, + 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01, + 0x00}}, /* 0x7 */ + {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f, + 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, + 0x00}}, /* 0x8 */ + {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f, + 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* TW: Corrected VBE */ + 0x61}}, /* 0x9 */ + {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e, + 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05, + 0x61}}, /* 0xa */ + {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e, + 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* TW: Corrected VBE */ + 0x61}}, /* 0xb */ + {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f, + 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* TW: Corrected VDE, VBE */ + 0x00}}, /* 0xc */ + {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0, + 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05, + 0x01}}, /* 0xd */ + {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06, + 0x01}}, /* 0xe */ + {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0, + 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06, + 0x01}}, /* 0xf */ + {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0, + 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06, + 0x01}}, /* 0x10 */ + {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0, + 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06, + 0x01}}, /* 0x11 */ + {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0, + 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06, + 0x61}}, /* 0x12 */ + {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0, + 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06, + 0x61}}, /* 0x13 */ + {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0, + 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06, + 0x61}}, /* 0x14 */ + {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f, + 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02, + 0x00}}, /* 0x15 */ + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}}, /* 0x16 */ + {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}}, /* 0x17 */ + {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5, + 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02, + 0x01}}, /* 0x18 */ + {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5, + 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02, + 0x01}}, /* 0x19 */ + {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5, + 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02, + 0x62}}, /* 0x1a */ + {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5, + 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02, + 0x62}}, /* 0x1b */ + {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba, + 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03, + 0x00}}, /* 0x1c */ + {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a, + 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, + 0x01}}, /* 0x1d */ + {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a, + 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, + 0x01}}, /* 0x1e */ + {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a, + 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07, + 0x01}}, /* 0x1f */ + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, /* 0x20 */ + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, /* 0x21 @ 4084 */ + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, /* 0x22 */ + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, /* 0x23 */ + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, /* 0x24 */ + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, /* 0x25 */ + {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, + 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, + 0x00}}, /* 0x26 */ + {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, + 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, + 0x00}}, /* 0x27 */ + {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f, + 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05, + 0x63}}, /* 0x28 */ + {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f, + 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05, + 0x63}}, /* 0x29 */ + {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, + 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, + 0x00}}, /* 0x2a */ + {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, + 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, + 0x00}}, /* 0x2b */ + {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, + 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, + 0x00}}, /* 0x2c */ + {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba, + 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05, + 0x44}}, /* 0x2d */ + {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba, + 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05, + 0x44}}, /* 0x2e */ + {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba, + 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05, + 0x44}}, /* 0x2f */ + {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba, + 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05, + 0x44}}, /* 0x30 */ + {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba, + 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05, + 0x00}}, /* 0x31 */ + {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, + 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06, + 0x01}}, /* 0x32 */ + {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba, + 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06, + 0x01}}, /* 0x33 */ + {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba, + 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06, + 0x01}}, /* 0x34 */ + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1, + 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02, + 0x01}}, /* 0x35 */ + {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1, + 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02, + 0x01}}, /* 0x36 */ + {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* TW: 95 was 15 - illegal HBE! */ + 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02, + 0x01}}, /* 0x37 */ + {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4, + 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, + 0x01}}, /* 0x38 */ + {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4, + 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, + 0x01}}, /* 0x39 */ + {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4, + 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07, + 0x01}}, /* 0x3a */ +#if 0 + {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef, /* 1280x960 - invalid */ + 0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07, + 0x01}}, /* 0x3b */ +#endif + {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 1280x960-60 - corrected */ + 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07, + 0x01}}, /* 0x3b */ + {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e, + 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, + 0x00}}, /* 0x3c */ + {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0, + 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05, + 0x01}}, /* 0x3d */ + {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15, + 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02, + 0x00}}, /* 0x3e */ + {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e, + 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02, + 0x00}}, /* 0x3f */ + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* TW: The following from 650/LVDS BIOS */ + 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02, + 0x01}}, /* 0x40 */ + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}}, /* 0x41 */ + {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, + 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07, + 0x01}}, /* 0x42 */ + {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10, + 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03, + 0x00}}, /* 0x43 */ + {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* TW: New, 1152x864-75, not in any BIOS */ + 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07, + 0x01}}, /* 0x44 */ + {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */ + 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, + 0x00}}, /* 0x45 */ +#if 0 + {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */ + 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, + 0x00}}, /* 0x46 */ +#endif + {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */ + 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06, + 0x00}}, /* 0x46 */ + {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 856x480-38i, not in BIOS */ + 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, + 0x00}}, /* 0x47 */ + {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 856x480-60, not in BIOS */ + 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, + 0x00}}, /* 0x48 */ + {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* TW: New, 1360x768-60, not in BIOS */ + 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03, + 0x01}}, /* 0x49 */ + {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* TW: New, 1152x864-84, not in any BIOS */ + 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03, + 0x01}}, /* 0x4a */ + {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* TW: New, 1400x1050-75, not in any BIOS */ + 0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03, + 0x00}}, /* 0x4b */ + {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */ + 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07, + 0x01}} /* 0x4c */ +}; + + +typedef struct _SiS310_MCLKDataStruct +{ + UCHAR SR28,SR29,SR2A; + USHORT CLOCK; +} SiS310_MCLKDataStruct; + +static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] = +{ + { 0x3b,0x22,0x01,143}, /* TW: Was { 0x5c,0x23,0x01,166}, */ + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166} +}; + +static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] = /* @ 0x54 */ +{ + { 0x5a,0x64,0x82, 66}, + { 0xb3,0x45,0x82, 83}, + { 0x37,0x61,0x82,100}, + { 0x37,0x22,0x82,133}, + { 0x37,0x61,0x82,100}, + { 0x37,0x22,0x82,133}, + { 0x37,0x22,0x82,133}, + { 0x37,0x22,0x82,133} +}; + +static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] = /* @ 0x54 */ +{ + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x7c,0x08,0x01,200}, + { 0x79,0x06,0x01,250}, + { 0x7c,0x08,0x01,200}, + { 0x7c,0x08,0x01,200}, + { 0x7c,0x08,0x01,200}, + { 0x79,0x06,0x01,250} +}; + +static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] = /* @ 0x155 */ +{ + { 0x29,0x21,0x82,150}, + { 0x5c,0x23,0x82,166}, + { 0x65,0x23,0x82,183}, + { 0x37,0x21,0x82,200}, + { 0x37,0x22,0x82,133}, + { 0x37,0x22,0x82,133}, + { 0x37,0x22,0x82,133}, + { 0x37,0x22,0x82,133} +}; + +typedef struct _SiS310_ECLKDataStruct +{ + UCHAR SR2E,SR2F,SR30; + USHORT CLOCK; +} SiS310_ECLKDataStruct; + +static const SiS310_ECLKDataStruct SiS310_ECLKData[]= +{ + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166}, + { 0x5c,0x23,0x01,166} +}; + +typedef struct _SiS310_VCLKDataStruct +{ + UCHAR SR2B,SR2C; + USHORT CLOCK; +} SiS310_VCLKDataStruct; + +static const SiS310_VCLKDataStruct SiS310_VCLKData[]= +{ + { 0x1b,0xe1, 25}, /* 0x0 */ /* 650/LVDS BIOS: @ 0x5647 */ + { 0x4e,0xe4, 28}, /* 0x1 */ + { 0x57,0xe4, 31}, /* 0x2 */ + { 0xc3,0xc8, 36}, /* 0x3 */ + { 0x42,0xe2, 40}, /* 0x4 */ + { 0xfe,0xcd, 43}, /* 0x5 */ + { 0x5d,0xc4, 44}, /* 0x6 */ + { 0x52,0xe2, 49}, /* 0x7 */ + { 0x53,0xe2, 50}, /* 0x8 */ + { 0x74,0x67, 52}, /* 0x9 */ + { 0x6d,0x66, 56}, /* 0xa */ + { 0x5a,0x64, 65}, /* 0xb */ /* TW: was 6c c3 - WRONG */ + { 0x46,0x44, 67}, /* 0xc */ + { 0xb1,0x46, 68}, /* 0xd */ + { 0xd3,0x4a, 72}, /* 0xe */ + { 0x29,0x61, 75}, /* 0xf */ + { 0x6e,0x46, 76}, /* 0x10 */ + { 0x2b,0x61, 78}, /* 0x11 */ + { 0x31,0x42, 79}, /* 0x12 */ + { 0xab,0x44, 83}, /* 0x13 */ + { 0x46,0x25, 84}, /* 0x14 */ + { 0x78,0x29, 86}, /* 0x15 */ + { 0x62,0x44, 94}, /* 0x16 */ + { 0x2b,0x41,104}, /* 0x17 */ + { 0x3a,0x23,105}, /* 0x18 */ + { 0x70,0x44,108}, /* 0x19 */ + { 0x3c,0x23,109}, /* 0x1a */ + { 0x5e,0x43,113}, /* 0x1b */ + { 0xbc,0x44,116}, /* 0x1c */ + { 0xe0,0x46,132}, /* 0x1d */ + { 0x54,0x42,135}, /* 0x1e */ + { 0xea,0x2a,139}, /* 0x1f */ + { 0x41,0x22,157}, /* 0x20 */ + { 0x70,0x24,162}, /* 0x21 */ + { 0x30,0x21,175}, /* 0x22 */ + { 0x4e,0x22,189}, /* 0x23 */ + { 0xde,0x26,194}, /* 0x24 */ + { 0x62,0x06,202}, /* 0x25 */ + { 0x3f,0x03,229}, /* 0x26 */ + { 0xb8,0x06,234}, /* 0x27 */ + { 0x34,0x02,253}, /* 0x28 */ + { 0x58,0x04,255}, /* 0x29 */ + { 0x24,0x01,265}, /* 0x2a */ + { 0x9b,0x02,267}, /* 0x2b */ + { 0x70,0x05,270}, /* 0x2c */ + { 0x25,0x01,272}, /* 0x2d */ + { 0x9c,0x02,277}, /* 0x2e */ + { 0x27,0x01,286}, /* 0x2f */ + { 0x3c,0x02,291}, /* 0x30 */ + { 0xef,0x0a,292}, /* 0x31 */ + { 0xf6,0x0a,310}, /* 0x32 */ + { 0x95,0x01,315}, /* 0x33 */ + { 0xf0,0x09,324}, /* 0x34 */ + { 0xfe,0x0a,331}, /* 0x35 */ + { 0xf3,0x09,332}, /* 0x36 */ + { 0xea,0x08,340}, /* 0x37 */ + { 0xe8,0x07,376}, /* 0x38 */ + { 0xde,0x06,389}, /* 0x39 */ + { 0x52,0x2a, 54}, /* 0x3a */ + { 0x52,0x6a, 27}, /* 0x3b */ + { 0x62,0x24, 70}, /* 0x3c */ + { 0x62,0x64, 70}, /* 0x3d */ + { 0xa8,0x4c, 30}, /* 0x3e */ + { 0x20,0x26, 33}, /* 0x3f */ + { 0x31,0xc2, 39}, /* 0x40 */ + /* TW: 650/LVDS BIOS @ 0x574b new: */ + { 0x60,0x36, 30}, /* 0x41 */ /* Chrontel */ + { 0x40,0x4a, 28}, /* 0x42 */ /* Chrontel */ + { 0x9f,0x46, 44}, /* 0x43 */ /* Chrontel */ + { 0x97,0x2c, 26}, /* 0x44 */ + { 0x44,0xe4, 25}, /* 0x45 */ /* Chrontel */ + { 0x7e,0x32, 47}, /* 0x46 */ /* Chrontel */ + { 0x8a,0x24, 31}, /* 0x47 */ /* Chrontel */ + { 0x97,0x2c, 26}, /* 0x48 */ /* Chrontel */ + { 0xce,0x3c, 39}, /* 0x49 */ + { 0x52,0x4a, 36}, /* 0x4a */ /* Chrontel */ + { 0x34,0x61, 95}, /* 0x4b */ + { 0x78,0x27,108}, /* 0x4c - was 102 */ /* TW: Last entry in 650/301 BIOS */ + { 0x66,0x43,123}, /* 0x4d */ /* Modes 0x26-0x28 (1400x1050) */ + { 0x41,0x4e, 21}, /* 0x4e */ + { 0xa1,0x4a, 29}, /* 0x4f */ /* Chrontel */ + { 0x19,0x42, 42}, /* 0x50 */ + { 0x54,0x46, 58}, /* 0x51 */ /* Chrontel */ + { 0x25,0x42, 61}, /* 0x52 */ + { 0x44,0x44, 66}, /* 0x53 */ /* Chrontel */ + { 0x3a,0x62, 70}, /* 0x54 */ /* Chrontel */ + { 0x62,0xc6, 34}, /* 0x55 - added for 848x480-60 (not in any BIOS) */ + { 0x6a,0xc6, 37}, /* 0x56 - added for 848x480-75 (not in any BIOS) - TEMP */ + { 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */ + { 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) - TEMP */ + { 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */ + { 0x56,0x07,156} /* 0x5a - added for 1400x1050-75 */ +}; + +typedef struct _SiS310_VBVCLKDataStruct +{ + UCHAR Part4_A,Part4_B; + USHORT CLOCK; +} SiS310_VBVCLKDataStruct; + +static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]= +{ + { 0x1b,0xe1, 25}, /* 0x0 */ /* 650/LVDS BIOS: @ 0x579c */ + { 0x4e,0xe4, 28}, /* 0x1 */ + { 0x57,0xe4, 31}, /* 0x2 */ + { 0xc3,0xc8, 36}, /* 0x3 */ + { 0x42,0x47, 40}, /* 0x4 */ + { 0xfe,0xcd, 43}, /* 0x5 */ + { 0x5d,0xc4, 44}, /* 0x6 */ + { 0x52,0x47, 49}, /* 0x7 */ + { 0x53,0x47, 50}, /* 0x8 */ + { 0x74,0x67, 52}, /* 0x9 */ + { 0x6d,0x66, 56}, /* 0xa */ + { 0x35,0x62, 65}, /* 0xb */ /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62 */ + { 0x46,0x44, 67}, /* 0xc */ + { 0xb1,0x46, 68}, /* 0xd */ + { 0xd3,0x4a, 72}, /* 0xe */ + { 0x29,0x61, 75}, /* 0xf */ + { 0x6d,0x46, 75}, /* 0x10 */ + { 0x41,0x43, 78}, /* 0x11 */ + { 0x31,0x42, 79}, /* 0x12 */ + { 0xab,0x44, 83}, /* 0x13 */ + { 0x46,0x25, 84}, /* 0x14 */ + { 0x78,0x29, 86}, /* 0x15 */ + { 0x62,0x44, 94}, /* 0x16 */ + { 0x2b,0x22,104}, /* 0x17 */ + { 0x49,0x24,105}, /* 0x18 */ + { 0xf8,0x2f,108}, /* 0x19 */ + { 0x3c,0x23,109}, /* 0x1a */ + { 0x5e,0x43,113}, /* 0x1b */ + { 0xbc,0x44,116}, /* 0x1c */ + { 0xe0,0x46,132}, /* 0x1d */ + { 0xd4,0x28,135}, /* 0x1e */ + { 0xea,0x2a,139}, /* 0x1f */ + { 0x41,0x22,157}, /* 0x20 */ + { 0x70,0x24,162}, /* 0x21 */ + { 0x30,0x21,175}, /* 0x22 */ + { 0x4e,0x22,189}, /* 0x23 */ + { 0xde,0x26,194}, /* 0x24 */ + { 0x70,0x07,202}, /* 0x25 */ + { 0x3f,0x03,229}, /* 0x26 */ + { 0xb8,0x06,234}, /* 0x27 */ + { 0x34,0x02,253}, /* 0x28 */ + { 0x58,0x04,255}, /* 0x29 */ + { 0x24,0x01,265}, /* 0x2a */ + { 0x9b,0x02,267}, /* 0x2b */ + { 0x70,0x05,270}, /* 0x2c */ + { 0x25,0x01,272}, /* 0x2d */ + { 0x9c,0x02,277}, /* 0x2e */ + { 0x27,0x01,286}, /* 0x2f */ + { 0x3c,0x02,291}, /* 0x30 */ + { 0xef,0x0a,292}, /* 0x31 */ + { 0xf6,0x0a,310}, /* 0x32 */ + { 0x95,0x01,315}, /* 0x33 */ + { 0xf0,0x09,324}, /* 0x34 */ + { 0xfe,0x0a,331}, /* 0x35 */ + { 0xf3,0x09,332}, /* 0x36 */ + { 0xea,0x08,340}, /* 0x37 */ + { 0xe8,0x07,376}, /* 0x38 */ + { 0xde,0x06,389}, /* 0x39 */ + { 0x52,0x2a, 54}, /* 0x3a */ + { 0x52,0x6a, 27}, /* 0x3b */ + { 0x62,0x24, 70}, /* 0x3c */ + { 0x62,0x64, 70}, /* 0x3d */ + { 0xa8,0x4c, 30}, /* 0x3e */ + { 0x20,0x26, 33}, /* 0x3f */ + { 0x31,0xc2, 39}, /* 0x40 */ + /* TW: 650/LVDS+301 BIOS (@ 0x58a0 in LVDS) new: */ + { 0x2e,0x48, 25}, /* 0x41 */ + { 0x24,0x46, 25}, /* 0x42 */ + { 0x26,0x64, 28}, /* 0x43 */ + { 0x37,0x64, 40}, /* 0x44 */ + { 0xa1,0x42,108}, /* 0x45 */ + { 0x37,0x61,100}, /* 0x46 */ + { 0x78,0x27,108} /* 0x47 */ + /* --- 0x58bc --- */ +}; + +static const UCHAR SiS310_ScreenOffset[] = +{ + 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64, + 0x78,0x80,0x2d,0x35,0x57,0x48,0x55, + 0xff +}; /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */ + +typedef struct _SiS310_StResInfoStruct +{ + USHORT HTotal; + USHORT VTotal; +} SiS310_StResInfoStruct; + +static const SiS310_StResInfoStruct SiS310_StResInfo[]= +{ + { 640,400}, + { 640,350}, + { 720,400}, + { 720,350}, + { 640,480} +}; + +typedef struct _SiS310_ModeResInfoStruct +{ + USHORT HTotal; + USHORT VTotal; + UCHAR XChar; + UCHAR YChar; +} SiS310_ModeResInfoStruct; + +static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] = +{ + { 320, 200, 8, 8}, /* 0x00 */ + { 320, 240, 8, 8}, /* 0x01 */ + { 320, 400, 8, 8}, /* 0x02 */ + { 400, 300, 8, 8}, /* 0x03 */ + { 512, 384, 8, 8}, /* 0x04 */ + { 640, 400, 8,16}, /* 0x05 */ + { 640, 480, 8,16}, /* 0x06 */ + { 800, 600, 8,16}, /* 0x07 */ + { 1024, 768, 8,16}, /* 0x08 */ + { 1280,1024, 8,16}, /* 0x09 */ + { 1600,1200, 8,16}, /* 0x0a */ + { 1920,1440, 8,16}, /* 0x0b */ + { 2048,1536, 8,16}, /* 0x0c */ + { 720, 480, 8,16}, /* 0x0d */ + { 720, 576, 8,16}, /* 0x0e */ + { 1280, 960, 8,16}, /* 0x0f */ + { 800, 480, 8,16}, /* 0x10 */ + { 1024, 576, 8,16}, /* 0x11 */ + { 1280, 720, 8,16}, /* 0x12 */ + { 856, 480, 8,16}, /* 0x13 - TW: New, not in any BIOS */ + { 1280, 768, 8,16}, /* 0x14 20; TW: New */ + { 1400,1050, 8,16}, /* 0x15 21; TW: New */ + { 1152, 864, 8,16}, /* 0x16 - TW: New, not in any BIOS */ + { 848, 480, 8,16}, /* 0x17 - TW: New, not in any BIOS */ + { 1360, 768, 8,16} /* 0x18 - TW: New, not in any BIOS */ +}; + +static const UCHAR SiS310_OutputSelect = 0x40; + +static const UCHAR SiS310_SoftSetting = 0x30; /* TW: RAM setting */ + +static const UCHAR SiS310_SR15[8][4]={ + {0x00,0x04,0x60,0x60}, + {0x0f,0x0f,0x0f,0x0f}, + {0xba,0xba,0xba,0xba}, + {0xa9,0xa9,0xac,0xac}, + {0xa0,0xa0,0xa0,0xa8}, + {0x00,0x00,0x02,0x02}, + {0x30,0x30,0x40,0x40}, + {0x00,0xa5,0xfb,0xf6} +}; + +#ifndef LINUX_XF86 + +static UCHAR SiS310_SR07 = 0x18; + +static const UCHAR SiS310_CR40[5][4]={ + {0x77,0x77,0x33,0x33}, + {0x77,0x77,0x33,0x33}, + {0x00,0x00,0x00,0x00}, + {0x5b,0x5b,0x03,0x03}, + {0x00,0x00,0xf0,0xf8} +}; + +static UCHAR SiS310_CR49[] = {0xaa,0x88}; +static UCHAR SiS310_SR1F = 0x00; +static UCHAR SiS310_SR21 = 0xa5; +static UCHAR SiS310_SR22 = 0xfb; +static UCHAR SiS310_SR23 = 0xf6; +static UCHAR SiS310_SR24 = 0x0d; +static UCHAR SiS310_SR25[] = {0x33,0x3}; +static UCHAR SiS310_SR31 = 0x00; +static UCHAR SiS310_SR32 = 0x11; +static UCHAR SiS310_SR33 = 0x00; +static UCHAR SiS310_CRT2Data_1_2 = 0x00; +static UCHAR SiS310_CRT2Data_4_D = 0x00; +static UCHAR SiS310_CRT2Data_4_E = 0x00; +static UCHAR SiS310_CRT2Data_4_10 = 0x80; +static const USHORT SiS310_RGBSenseData = 0xd1; +static const USHORT SiS310_VideoSenseData = 0xb9; +static const USHORT SiS310_YCSenseData = 0xb3; +static const USHORT SiS310_RGBSenseData2 = 0x0190; /*301b*/ +static const USHORT SiS310_VideoSenseData2 = 0x0174; +static const USHORT SiS310_YCSenseData2 = 0x016b; +#endif + +static const UCHAR SiS310_NTSCPhase[] = {0x21,0xed,0xba,0x08}; /* TW: Was {0x21,0xed,0x8a,0x08}; */ +static const UCHAR SiS310_PALPhase[] = {0x2a,0x05,0xe3,0x00}; /* TW: Was {0x2a,0x05,0xd3,0x00}; */ +static const UCHAR SiS310_PALMPhase[] = {0x21,0xE4,0x2E,0x9B}; /* TW: palm*/ +static const UCHAR SiS310_PALNPhase[] = {0x21,0xF4,0x3E,0xBA}; /* TW: paln*/ +static const UCHAR SiS310_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6}; +static const UCHAR SiS310_PALPhase2[] = {0x2a,0x09,0x86,0xe9}; +static const UCHAR SiS310_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/ +static const UCHAR SiS310_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/ +static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a}; + +typedef struct _SiS310_LCDDataStruct +{ + USHORT RVBHCMAX; + USHORT RVBHCFACT; + USHORT VGAHT; + USHORT VGAVT; + USHORT LCDHT; + USHORT LCDVT; +} SiS310_LCDDataStruct; + +static const SiS310_LCDDataStruct SiS310_StLCD1024x768Data[]= +{ + { 62, 25, 800, 546,1344, 806}, + { 32, 15, 930, 546,1344, 806}, + { 32, 15, 930, 546,1344, 806}, + { 104, 45, 945, 496,1344, 806}, + { 62, 25, 800, 546,1344, 806}, + { 31, 18,1008, 624,1344, 806}, + { 1, 1,1344, 806,1344, 806} +}; + +static const SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] = /* TW: Checked */ +{ + { 12, 5, 896, 512,1344, 806}, + { 12, 5, 896, 510,1344, 806}, + { 32, 15,1008, 505,1344, 806}, + { 32, 15,1008, 514,1344, 806}, + { 12, 5, 896, 500,1344, 806}, + { 42, 25,1024, 625,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 12, 5, 896, 500,1344, 806}, + { 42, 25,1024, 625,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 12, 5, 896, 500,1344, 806}, + { 42, 25,1024, 625,1344, 806}, + { 1, 1,1344, 806,1344, 806} +}; + +static const SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] = /* TW: Checked */ +{ + { 62, 25, 800, 546,1344, 806}, + { 32, 15, 930, 546,1344, 806}, +/* { 32, 15, 930, 546,1344, 806}, */ + { 62, 25, 800, 546,1344, 806}, /* TW: Different in 650/301LV BIOS */ + { 104, 45, 945, 496,1344, 806}, + { 62, 25, 800, 546,1344, 806}, + { 31, 18,1008, 624,1344, 806}, + { 1, 1,1344, 806,1344, 806} +}; + +static const SiS310_LCDDataStruct SiS310_StLCD1280x1024Data[] = +{ + { 22, 5, 800, 510,1650,1088}, + { 22, 5, 800, 510,1650,1088}, + { 176, 45, 900, 510,1650,1088}, + { 176, 45, 900, 510,1650,1088}, + { 22, 5, 800, 510,1650,1088}, + { 13, 5,1024, 675,1560,1152}, + { 16, 9,1266, 804,1688,1072}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = /* TW: Checked */ +{ + { 211, 60,1024, 501,1688,1066}, + { 211, 60,1024, 508,1688,1066}, + { 211, 60,1024, 501,1688,1066}, + { 211, 60,1024, 508,1688,1066}, + { 211, 60,1024, 500,1688,1066}, + { 211, 75,1024, 625,1688,1066}, + { 211, 120,1280, 798,1688,1066}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] = +{ + { 22, 5, 800, 510,1650,1088}, + { 22, 5, 800, 510,1650,1088}, + { 176, 45, 900, 510,1650,1088}, + { 176, 45, 900, 510,1650,1088}, + { 22, 5, 800, 510,1650,1088}, + { 13, 5,1024, 675,1560,1152}, + { 16, 9,1266, 804,1688,1072}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS310_LCDDataStruct SiS310_NoScaleData1024x768[] = /* TW: Checked */ +{ + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1344, 806,1344, 806}, + { 1, 1,1344, 806,1344, 806} +}; + +static const SiS310_LCDDataStruct SiS310_NoScaleData1280x1024[] = /* TW: New; Checked */ +{ + { 1, 1,1688,1066,1688,1066}, + { 1, 1,1688,1066,1688,1066}, + { 1, 1,1688,1066,1688,1066}, + { 1, 1,1688,1066,1688,1066}, + { 1, 1,1688,1066,1688,1066}, + { 1, 1,1688,1066,1688,1066}, + { 1, 1,1688,1066,1688,1066}, + { 1, 1,1688,1066,1688,1066} +}; + +static const SiS310_LCDDataStruct SiS310_LCD1280x960Data[] = +{ + { 9, 2, 800, 500,1800,1000}, + { 9, 2, 800, 500,1800,1000}, + { 4, 1, 900, 500,1800,1000}, + { 4, 1, 900, 500,1800,1000}, + { 9, 2, 800, 500,1800,1000}, + { 30, 11,1056, 625,1800,1000}, + { 5, 3,1350, 800,1800,1000}, + { 1, 1,1576,1050,1576,1050}, + { 1, 1,1800,1000,1800,1000} +}; + +static const SiS310_LCDDataStruct SiS310_StLCD1400x1050Data[] = /* TW: New */ +{ /* TW: New from 1.11.6s */ + { 211, 100, 2100, 408, 1688, 1066 }, + { 211, 64, 1536, 358, 1688, 1066 }, + { 211, 100, 2100, 408, 1688, 1066 }, + { 211, 64, 1536, 358, 1688, 1066 }, + { 211, 48, 840, 488, 1688, 1066 }, + { 211, 72, 1008, 609, 1688, 1066 }, + { 211, 128, 1400, 776, 1688, 1066 }, + { 211, 205, 1680, 1041, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 } +}; + +static const SiS310_LCDDataStruct SiS310_ExtLCD1400x1050Data[] = /* TW: New */ +{ /* TW: New from 1.11.6s */ + { 211, 100, 2100, 408, 1688, 1066 }, + { 211, 64, 1536, 358, 1688, 1066 }, + { 211, 100, 2100, 408, 1688, 1066 }, + { 211, 64, 1536, 358, 1688, 1066 }, + { 211, 48, 840, 488, 1688, 1066 }, + { 211, 72, 1008, 609, 1688, 1066 }, + { 211, 128, 1400, 776, 1688, 1066 }, + { 211, 205, 1680, 1041, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 } +}; + +static const SiS310_LCDDataStruct SiS310_NoScaleData1400x1050[] = /* TW: New */ +{ /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */ + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 }, + { 1, 1, 1688, 1066, 1688, 1066 } +}; + +static const SiS310_LCDDataStruct SiS310_StLCD1600x1200Data[] = /* TW: New */ +{ /* TODO */ + { 0, 0, 0, 0, 0, 0} +}; + +static const SiS310_LCDDataStruct SiS310_ExtLCD1600x1200Data[] = /* TW: New */ +{ /* TODO */ + { 0, 0, 0, 0, 0, 0} +}; + +static const SiS310_LCDDataStruct SiS310_NoScaleData1600x1200[] = /* TW: New */ +{ /* TODO */ + { 0, 0, 0, 0, 0, 0} +}; + +typedef struct _SiS310_TVDataStruct +{ + USHORT RVBHCMAX; + USHORT RVBHCFACT; + USHORT VGAHT; + USHORT VGAVT; + USHORT TVHDE; + USHORT TVVDE; + USHORT RVBHRS; + UCHAR FlickerMode; + USHORT HALFRVBHRS; + UCHAR RY1COE; + UCHAR RY2COE; + UCHAR RY3COE; + UCHAR RY4COE; +} SiS310_TVDataStruct; + +static const SiS310_TVDataStruct SiS310_StPALData[]= +{ + { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, + { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, + { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22}, + { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22} +}; + +static const SiS310_TVDataStruct SiS310_ExtPALData[] = /* TW: Verfied (1.10.7w) */ +{ + { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, + { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, + { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18}, + { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a}, + { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480 */ + { 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600 */ + { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x480/576 */ + { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} /* 1024x768 */ +}; + +static const SiS310_TVDataStruct SiS310_StNTSCData[]= +{ + { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, + { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, + { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18} +}; + +static const SiS310_TVDataStruct SiS310_ExtNTSCData[]= +{ + { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, + { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, + { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18}, + { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a}, + { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480 */ + { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600 */ + { 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480/576 */ + { 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} /* 1024x768 */ +}; + +/* TW: These tables will need data ! */ +static const SiS310_TVDataStruct SiS310_St1HiTVData[]= +{ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +static const SiS310_TVDataStruct SiS310_St2HiTVData[]= +{ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +static const SiS310_TVDataStruct SiS310_ExtHiTVData[]= +{ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} +}; + +static const UCHAR SiS310_NTSCTiming[] = { /* TW: New (checked 1.09, 1.10.6s) */ + 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c, + 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a, + 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b, + 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17, + 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02, + 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50, + 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00 +}; + +static const UCHAR SiS310_PALTiming[] = { /* TW: New (checked 1.09, 1.10.6s) */ + 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70, + 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b, + 0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17, + 0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02, + 0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63, + 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00 +}; + +#ifdef oldHV +static const UCHAR SiS310_HiTVExtTiming[] = { /* TW: New */ + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, + 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, + 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, + 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 +}; + +static const UCHAR SiS310_HiTVSt1Timing[] = { /* TW: New */ + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03, + 0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10, + 0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86, + 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00 +}; + +static const UCHAR SiS310_HiTVSt2Timing[] = { /* TW: New */ + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, + 0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40, + 0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d, + 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 +}; + +static const UCHAR SiS310_HiTVTextTiming[] = { /* TW: New */ + 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, + 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, + 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, + 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03, + 0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20, + 0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40, + 0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96, + 0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00 +}; + +static const UCHAR SiS310_HiTVGroup3Data[] = { /* TW: New */ + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f, + 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9, + 0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; + +static const UCHAR SiS310_HiTVGroup3Simu[] = { /* TW: New */ + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95, + 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4, + 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; + +static const UCHAR SiS310_HiTVGroup3Text[] = { /* TW: New */ + 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7, + 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6, + 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, + 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22, + 0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80, + 0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca, + 0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75, + 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 +}; +#endif + +typedef struct _SiS310_PanelDelayTblStruct +{ + UCHAR timer[2]; +} SiS310_PanelDelayTblStruct; + +static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]= /* TW: New */ +{ + {{0x10,0x40}}, /* TW: from 650/301LVx 1.10.6s BIOS */ + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}}, + {{0x10,0x40}} +#if 0 + {{0x28,0xc8}}, /* TW: from 650/301LV BIOS */ + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}} +#endif +}; + +static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]= +{ + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}}, + {{0x28,0xc8}} +}; + +typedef struct _SiS310_LVDSDataStruct +{ + USHORT VGAHT; + USHORT VGAVT; + USHORT LCDHT; + USHORT LCDVT; +} SiS310_LVDSDataStruct; + +static const SiS310_LVDSDataStruct SiS310_LVDS320x480Data_1[]= +{ + {848, 433,400, 525}, + {848, 389,400, 525}, + {848, 433,400, 525}, + {848, 389,400, 525}, + {848, 518,400, 525}, + {1056,628,400, 525}, + {400, 525,400, 525}, + {800, 449,1000, 644}, + {800, 525,1000, 635} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS800x600Data_1[]= /* TW: New */ +{ + {848, 433,1060, 629}, + {848, 389,1060, 629}, + {848, 433,1060, 629}, + {848, 389,1060, 629}, + {848, 518,1060, 629}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {800, 449,1000, 644}, + {800, 525,1000, 635} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS800x600Data_2[]= /* TW: New */ +{ + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {800, 449,1000, 644}, + {800, 525,1000, 635} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_1[]= /* TW: New */ +{ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, /* 640x480 */ + {1050, 638,1344, 806}, /* 800x600 */ + {1344, 806,1344, 806}, /* 1024x768 */ + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1024x768Data_2[]= /* TW: New */ +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_1[]= /* TW: New - TODO */ +{ /* TW: Temp data, invalid (is identical to 1024x768) */ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1280x1024Data_2[]= /* TW: New - TODO */ +{ /* TW: Temp data, invalid (is identical to 1024x768) */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1400x1050Data_1[]= /* TW: New */ +{ + {928, 416, 1688, 1066}, + {928, 366, 1688, 1066}, + {928, 416, 1688, 1066}, + {928, 366, 1688, 1066}, + {928, 496, 1688, 1066}, + {1088, 616, 1688, 1066}, + {1312, 784, 1688, 1066}, + {1568, 1040, 1688, 1066}, + {1688, 1066, 1688, 1066} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1400x1050Data_2[]= /* TW: New */ +{ + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, + {1688,1066, 1688,1066}, +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1280x768Data_1[]= /* TW: New - TODO */ +{ /* TW: Temp data, invalid (is identical to 1024x768) */ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1280x768Data_2[]= /* TW: New - TODO */ +{ /* TW: Temp data, invalid (is identical to 1024x768) */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New: - from 300 series */ +static const SiS310_LVDSDataStruct SiS310_LVDS1024x600Data_1[]= +{ + {840, 604,1344, 800}, + {840, 560,1344, 800}, + {840, 604,1344, 800}, + {840, 560,1344, 800}, + {840, 689,1344, 800}, + {1050, 800,1344, 800}, + {1344, 800,1344, 800}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New: - from 300 series */ +static const SiS310_LVDSDataStruct SiS310_LVDS1024x600Data_2[]= +{ + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {1344, 800,1344, 800}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New: - from 300 series */ +static const SiS310_LVDSDataStruct SiS310_LVDS1152x768Data_1[]= +{ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New: - from 300 series */ +static const SiS310_LVDSDataStruct SiS310_LVDS1152x768Data_2[]= +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +/* TW: New in 650/LVDS BIOS - pass 1:1 data */ +static const SiS310_LVDSDataStruct SiS310_LVDSXXXxXXXData_1[]= /* TW: New */ +{ + { 800, 449, 800, 449}, + { 800, 449, 800, 449}, + { 900, 449, 900, 449}, + { 900, 449, 900, 449}, + { 800, 525, 800, 525}, + {1056, 628,1056, 628}, + {1344, 806,1344, 806}, + {1688, 806,1688, 806} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS640x480Data_1[]= /* TW: New */ +{ + {800, 449, 800, 449}, + {800, 449, 800, 449}, + {800, 449, 800, 449}, + {800, 449, 800, 449}, + {800, 525, 800, 525}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628}, + {1056, 628,1056, 628} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1280x960Data_1[]= /* TW: New */ +{ + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 438,1344, 806}, + {840, 409,1344, 806}, + {840, 518,1344, 806}, + {1050, 638,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LVDS1280x960Data_2[]= /* TW: New */ +{ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LCDA1400x1050Data_1[]= /* TW: New */ +{ /* TW: Might be temporary (invalid) data */ + {928, 416, 1688, 1066}, + {928, 366, 1688, 1066}, + {1008, 416, 1688, 1066}, + {1008, 366, 1688, 1066}, + {1200, 530, 1688, 1066}, + {1088, 616, 1688, 1066}, + {1312, 784, 1688, 1066}, + {1568, 1040, 1688, 1066}, + {1688, 1066, 1688, 1066} +}; + +static const SiS310_LVDSDataStruct SiS310_LCDA1400x1050Data_2[]= /* TW: New */ +{ /* TW: Temporary data. Not valid */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LCDA1600x1200Data_1[]= /* TW: New */ +{ /* TW: Temporary data. Not valid */ + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {1344, 806,1344, 806}, + {800, 449,1280, 801}, + {800, 525,1280, 813} +}; + +static const SiS310_LVDSDataStruct SiS310_LCDA1600x1200Data_2[]= /* TW: New */ +{ /* TW: Temporary data. Not valid */ + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {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 const SiS310_LVDSDataStruct SiS310_CHTVUNTSCData[]= /* TW: New */ +{ + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 784, 600, 784, 600}, + {1064, 750,1064, 750}, + {1160, 945,1160, 945} /* TW: For Ch7019 1024 */ +}; + +static const SiS310_LVDSDataStruct SiS310_CHTVONTSCData[]= /* TW: New */ +{ + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 784, 525, 784, 525}, + {1040, 700,1040, 700}, + {1160, 840,1160, 840} /* TW: For Ch7019 1024 */ +}; + +static const SiS310_LVDSDataStruct SiS310_CHTVUPALData[]= /* TW: New */ +{ + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + { 840, 625, 840, 625}, + { 960, 750, 960, 750}, + {1400,1000,1400,1000} /* TW: For Ch7019 1024 */ +}; + +static const SiS310_LVDSDataStruct SiS310_CHTVOPALData[]= /* TW: New */ +{ + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + { 840, 625, 840, 625}, + { 944, 625, 944, 625}, + {1400, 875,1400, 875} /* TW: For Ch7019 1024 */ +}; + +static const SiS310_LVDSDataStruct SiS310_CHTVUPALMData[]= /* TW: New */ +{ + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 840, 600, 840, 600}, + { 784, 600, 784, 600}, + {1064, 750,1064, 750}, + {1160, 945,1160, 945} /* TW: For Ch7019 1024 */ +}; + +static const SiS310_LVDSDataStruct SiS310_CHTVOPALMData[]= /* TW: New */ +{ + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 840, 525, 840, 525}, + { 784, 525, 784, 525}, + {1040, 700,1040, 700}, + {1160, 840,1160, 840} /* TW: For Ch7019 1024 */ +}; + +static const SiS310_LVDSDataStruct SiS310_CHTVUPALNData[]= /* TW: New */ +{ + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + { 840, 625, 840, 625}, + { 960, 750, 960, 750}, + {1400,1000,1400,1000} /* TW: For Ch7019 1024 */ +}; + +static const SiS310_LVDSDataStruct SiS310_CHTVOPALNData[]= /* TW: New */ +{ + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + { 840, 625, 840, 625}, + { 944, 625, 944, 625}, + {1400, 875,1400, 875} /* TW: For Ch7019 1024 */ +}; + +static const SiS310_LVDSDataStruct SiS310_CHTVSOPALData[]= /* TW: New (super overscan - no effect on 7019) */ +{ + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + {1008, 625,1008, 625}, + { 840, 625, 840, 625}, + { 944, 625, 944, 625}, + {1400, 875,1400, 875} +}; + +typedef struct _SiS310_LVDSDesStruct +{ + USHORT LCDHDES; + USHORT LCDVDES; +} SiS310_LVDSDesStruct; + +/* TW: PanelType arrays taken from 650/LVDS BIOS 1.10.0 */ + +static const SiS310_LVDSDesStruct SiS310_PanelType00_1[]= /* TW: New */ +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType01_1[]= /* TW: New */ +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 805}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType02_1[]= /* TW: New */ +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 1065}, + { 0, 0}, + { 0, 0} +}; + + +static const SiS310_LVDSDesStruct SiS310_PanelType03_1[]= /* TW: New */ +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType04_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType05_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType06_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType07_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType08_1[]= /* TW: New */ +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType09_1[]= /* TW: New - to check (1280x768) */ +{ + { 0, 448}, + { 0, 448}, + { 0, 448}, + { 0, 448}, + { 0, 524}, + { 0, 627}, + { 0, 805}, + { 0, 805}, +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0a_1[]= /* TW: New */ +{ + {1059, 626}, + {1059, 624}, + {1059, 626}, + {1059, 624}, + {1059, 624}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0b_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0c_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0d_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0e_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0f_1[]= /* TW: New */ +{ + {1343, 798}, + {1343, 794}, + {1343, 798}, + {1343, 794}, + {1343, 0}, + {1343, 0}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType00_2[]= /* TW: New */ +{ + {980, 528}, + {980, 503}, + {980, 528}, + {980, 503}, + {980, 568}, + { 0, 628}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType01_2[]= /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 806}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType02_2[]= /* TW: New */ +{ + {1368, 754}, + {1368, 729}, + {1368, 754}, + {1368, 729}, + {1368, 794}, + {1448, 854}, + {1560, 938}, + { 0,1066}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType03_2[]= /* TW: New */ +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType04_2[]= /* TW: New */ +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType05_2[]= /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType06_2[]= /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType07_2[]= /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType08_2[]= /* TW: New */ +{ + {976, 527}, + {976, 502}, + {976, 527}, + {976, 502}, + {976, 567}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType09_2[]= /* TW: New - to check (1280x768) */ +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0a_2[]= /* TW: New */ +{ + {976, 527}, + {976, 502}, + {976, 527}, + {976, 502}, + {976, 567}, + { 0, 627}, + { 0, 627}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0b_2[]= /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0c_2[]= /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0d_2[]= /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0e_2[]= /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType0f_2[] = /* TW: New */ +{ + {1152, 622}, + {1152, 597}, + {1152, 622}, + {1152, 597}, + {1152, 662}, + {1232, 722}, + { 0, 805}, + { 0, 794}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]= /* TW: New */ +{ /* 1024x768 - Checked (1.10.6s) */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]= /* TW: New */ +{ /* 1024x768 - Checked (1.10.6s) */ + { 1184, 622 }, + { 1184, 597 }, + { 1184, 622 }, + { 1184, 597 }, + { 1152, 622 }, + { 1232, 722 }, + { 0, 0 }, + { 0, 794 }, + { 0, 0 } +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]= /* TW: New */ +{ /* 1280x1024 - Checked (1.10.6s) */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]= /* TW: New */ +{ /* 1280x1024 - Checked (1.10.6s) */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]= /* TW: New */ +{ /* 1400x1050 - Checked (1.10.6s) */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]= /* TW: New */ +{ /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */ + { 808 , 740}, + { 0 , 715}, + { 632 , 740}, + { 632 , 715}, + { 1307, 780}, + { 1387,1157}, + { 1499, 924}, + { 1627,1052}, + { 0 , 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]= /* TW: New */ +{ /* 1600x1200 - Checked (1.10.6s) */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]= /* TW: New */ +{ /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid */ + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0}, + { 0 , 0} +}; + +static const SiS310_LVDSDesStruct SiS310_CHTVUNTSCDesData[]= +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_CHTVONTSCDesData[]= +{ + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_CHTVUPALDesData[]= +{ + {256, 0}, + {256, 0}, + {256, 0}, + {256, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +static const SiS310_LVDSDesStruct SiS310_CHTVOPALDesData[]= +{ + {256, 0}, + {256, 0}, + {256, 0}, + {256, 0}, + { 0, 0}, + { 0, 0}, + { 0, 0} +}; + +typedef struct _SiS310_Part2PortTblStruct +{ + UCHAR CR[12]; +} SiS310_Part2PortTblStruct; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] = +{ + {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] = +{ /* TW: Temporary data, invalid */ + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] = +{ /* TW: Temporary data, invalid */ + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] = +{ /* TW: Temporary data, invalid */ + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] = +{ + {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}}, + {{0x2c,0x12,0x38,0x55,0x2f,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}}, + {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}}, + {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}}, + {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}}, + {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}}, + {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] = +{ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] = +{ + {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}}, + {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}}, + {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] = +{ /* TW: Temporary data, invalid */ + {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}}, + {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}}, + {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}}, + {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}} +}; + + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] = +{ /* TW: Data from 650/301LVx 1.10.6s */ + {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}} +#if 0 /* TW: Data from 650/301LV */ + {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} +#endif +}; + +/* 1 2 4 5 6 1c 1d 1f 20 21 23 25 */ +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] = +{ /* TW: Temporary data, invalid */ + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] = +{ /* TW: Temporary data, invalid */ + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}} +}; + +static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] = +{ /* TW: Temporary data, invalid */ + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}, + {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}} +}; + +typedef struct _SiS310_LCDACRT1DataStruct +{ + UCHAR CR[17]; +}SiS310_LCDACRT1DataStruct; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1[] = +{ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1[]= +{ /* TW: Checked (1.10.6s) */ + {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f, + 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05, + 0x00}}, + {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f, + 0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05, + 0x00}}, + {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f, + 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05, + 0x00}}, + {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f, + 0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05, + 0x00}}, + {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e, + 0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05, + 0x00}}, + {{0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0, + 0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26, + 0x01}}, + {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1[]= +{ /* Checked (1.10.6s) */ + {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f, + 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06, + 0x00}}, + {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f, + 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06, + 0x00}}, + {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f, + 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06, + 0x00}}, + {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f, + 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06, + 0x00}}, + {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e, + 0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06, + 0x00}}, + {{0x92,0x63,0x63,0x96,0x6c,0x1a,0x80,0xf0, + 0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06, + 0x01}}, + {{0xae,0x7f,0x7f,0x92,0x88,0x96,0x28,0xf5, + 0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02, + 0x01}}, + {{0xce,0x9f,0x9f,0x92,0xa8,0x16,0x28,0x5a, + 0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07, + 0x01}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1[]= +{ /* Checked (1.10.6s) */ + {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f, + 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f, + 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f, + 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f, + 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f, + 0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x83,0x63,0x63,0x87,0x68,0x16,0x66,0xf0, + 0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x06, + 0x01}}, + {{0x9f,0x7f,0x7f,0x83,0x84,0x92,0x0e,0xf5, + 0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x02, + 0x01}}, + {{0xbf,0x9f,0x9f,0x83,0xa4,0x12,0x0e,0x5a, + 0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x07, + 0x01}}, + {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10, + 0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_1[]= +{ /* MISSING */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_1_H[]= +{ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1_H[]= +{ /* TW: Checked (1.10.6s) */ + {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f, + 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f, + 0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44, + 0x00}}, + {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f, + 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f, + 0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44, + 0x00}}, + {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e, + 0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45, + 0x00}}, + {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0, + 0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55, + 0x01}}, + {{0x63,0x3F,0x3F,0x87,0x4a,0x93,0x24,0xf5, + 0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1_H[]= +{ /* Checked (1.10.6s) */ + {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f, + 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1, /* <-- Invalid data - one byte missing in BIOS */ + 0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06, + 0x01}}, + {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f, + 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1, + 0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06, + 0x01}}, + {{0x56,0x27,0x27,0x9a,0x30,0x1e,0x08,0x3e, + 0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05, + 0x00}}, + {{0x60,0x31,0x31,0x84,0x3a,0x88,0x80,0xf0, + 0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01, + 0x01}}, + {{0x6e,0x3f,0x3f,0x92,0x48,0x96,0x28,0xf5, + 0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1_H[]= +{ /* Checked (1.10.6s) */ + {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, + 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x27,0x8b,0x30,0x1e,0x9e,0x1f, + 0x92,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0xee,0x1f, + 0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x51,0x31,0x31,0x95,0x36,0x04,0x66,0xf0, + 0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x01, + 0x01}}, + {{0x5f,0x3f,0x3f,0x83,0x44,0x92,0x0e,0xf5, + 0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x01, + 0x01}}, + {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x0e,0x5a, + 0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x05, + 0x01}}, + {{0x76,0x56,0x56,0x9a,0x5b,0x89,0x28,0x10, + 0x1c,0x80,0x19,0x19,0x29,0x0b,0x00,0x05, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_1_H[]= +{ /* MISSING */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2[]= +{ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2[]= +{ /* Checked (1.10.6s) */ + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2[]= +{ /* Checked (1.10.6s) */ + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2[]= +{ /* Checked (1.10.6s) */ + {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03, + 0x01}}, + {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9e, + 0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x03, + 0x00}}, + {{0xce,0x63,0x63,0x92,0x96,0x04,0x28,0xd4, + 0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x07, + 0x01}}, + {{0xce,0x7f,0x7f,0x92,0xa4,0x12,0x28,0xd4, + 0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x07, + 0x01}}, + {{0xce,0x9f,0x9f,0x92,0xb4,0x02,0x28,0x5a, + 0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x03, + 0x01}}, + {{0xce,0xae,0xae,0x92,0xbc,0x0a,0x28,0x10, + 0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x03, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_2[]= +{ /* MISSING */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT1800x600_2_H[]= +{ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2_H[]= +{ /* Checked (1.10.6s) */ + {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x8d,0x5d,0x25,0x30,0x00,0x01, /* <-- invalid data */ + 0x00 }}, + {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x31,0x31,0x93,0x3e,0x06,0x24,0xf1, + 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01, /* <-- invalid data */ + 0x01 }}, + {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, + 0x01 }} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2_H[]= +{ /* Checked (1.10.6s) */ + {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb, + 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x4f,0x31,0x31,0x93,0x3e,0x86,0x24,0xf1, + 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01, + 0x01 }}, + {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, + 0x01 }} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2_H[]= +{ /* Checked (1.10.6s) */ + {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9e, + 0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x06, + 0x00}}, + {{0x9c,0x31,0x31,0x80,0x64,0x92,0x28,0xd4, + 0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x06, + 0x01}}, + {{0x8e,0x3f,0x3f,0x92,0x64,0x12,0x28,0xd4, + 0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x06, + 0x01}}, + {{0x7e,0x4f,0x4f,0x82,0x64,0x12,0x28,0x5a, + 0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x06, + 0x01}}, + {{0x76,0x56,0x56,0x9a,0x64,0x92,0x28,0x10, + 0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x05, + 0x00}} +}; + +static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_2_H[]= +{ /* MISSING */ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00}} +}; + +typedef struct _SiS310_LVDSCRT1DataStruct +{ + UCHAR CR[15]; +} SiS310_LVDSCRT1DataStruct; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1320x480_1[] = +{ + {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, + 0x00 }}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01 }}, + {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] = /* TW: New */ +{ + {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00 }}, + {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00 }}, + {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, + 0x00 }}, + {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] = /* TW: New */ +{ + {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05, + 0x00}}, + {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x05, + 0x00}}, + {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05, + 0x00}}, + {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x05, + 0x00}}, + {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e, + 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05, + 0x00}}, + {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0, + 0x5A,0x81,0x57,0x7D,0x00,0x00,0x06, + 0x01}}, + {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5, + 0x02,0x89,0xFf,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] = /* TW: New */ +{ + {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f, + 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06, + 0x00 }}, + {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f, + 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06, + 0x00 }}, + {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f, + 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06, + 0x00 }}, + {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f, + 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06, + 0x00 }}, + {{0x7e,0x4f,0x82,0x56,0x04,0x08,0x3e, + 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06, + 0x00 }}, + {{0x92,0x63,0x96,0x6a,0x18,0x80,0xf0, + 0x58,0x8c,0x57,0x81,0x20,0x00,0x06, + 0x01 }}, + {{0xae,0x7f,0x92,0x86,0x94,0x28,0xf5, + 0x00,0x84,0xff,0x29,0x10,0x00,0x02, + 0x01 }}, + {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a, + 0x00,0x84,0xff,0x29,0x09,0x00,0x07, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] = /* TW: New */ +{ + {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f, + 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, + 0x00 }}, + {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, + 0x00 }}, + {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f, + 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05, + 0x00 }}, + {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f, + 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05, + 0x00 }}, + {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0, + 0x58,0x8d,0x57,0x73,0x20,0x00,0x01, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] = /* TW: New */ +{ + {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05, + 0x00 }}, + {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f, + 0x60,0x87,0x5D,0x83,0x01,0x00,0x05, + 0x00}}, + {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05, + 0x00}}, + {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f, + 0x60,0x87,0x5D,0x83,0x01,0x00,0x05, + 0x00}}, + {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e, + 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05, + 0x00}}, + {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0, + 0x5A,0x81,0x57,0x7D,0x00,0x00,0x01, + 0x01}}, + {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5, + 0x02,0x89,0xFf,0x25,0x10,0x00,0x01, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] = /* TW: New */ +{ + {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f, + 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05, + 0x00 }}, + {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f, + 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05, + 0x00 }}, + {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f, + 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05, + 0x00 }}, + {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f, + 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05, + 0x01 }}, + {{0x56,0x27,0x9a,0x2e,0x1c,0x08,0x3e, + 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05, + 0x00 }}, + {{0x60,0x31,0x84,0x38,0x86,0x80,0xf0, + 0x58,0x8c,0x57,0x81,0x20,0x00,0x01, + 0x01 }}, + {{0x6e,0x3f,0x92,0x46,0x94,0x28,0xf5, + 0x00,0x84,0xff,0x29,0x10,0x00,0x01, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]= /* TW: New */ +{ + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, + 0xff,0x84,0x8f,0x73,0x00,0x00,0x06, + 0x00 }}, + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, + 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06, + 0x00 }}, + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, + 0xff,0x84,0x8f,0x73,0x00,0x00,0x06, + 0x00 }}, + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e, + 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06, + 0x00 }}, + {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba, + 0x27,0x8c,0xdf,0x73,0x00,0x00,0x06, + 0x00 }}, + {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0, + 0x58,0x8d,0x57,0x73,0x20,0x00,0x06, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] = /* TW: New */ +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06, + 0x00 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06, + 0x01 }}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x7f,0x86,0xdf,0x25,0x10,0x00,0x06, + 0x00 }}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xbb,0x82,0x57,0x25,0x10,0x00,0x02, + 0x01 }}, + {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5, + 0x02,0x89,0xff,0x25,0x10,0x00,0x02, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] = /* TW: New */ +{ + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00 }}, + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, + 0x00 }}, + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00 }}, + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, + 0x00 }}, + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9e, + 0x03,0x87,0xdf,0x29,0x01,0x00,0x03, + 0x00 }}, + {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x03, + 0x01 }}, + {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x07, + 0x01 }}, + {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a, + 0x00,0x84,0xff,0x29,0x09,0x00,0x07, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] = /* TW: New */ +{ + {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e, + 0xff,0x84,0x8f,0x73,0x00,0x00,0x01, + 0x00 }}, + {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e, + 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01, + 0x00 }}, + {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e, + 0xff,0x84,0x8f,0x73,0x00,0x00,0x01, + 0x00 }}, + {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e, + 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01, + 0x00 }}, + {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba, + 0x27,0x8c,0xdf,0x73,0x00,0x00,0x01, + 0x00 }}, + {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0, + 0x63,0x88,0x57,0x73,0x00,0x00,0x01, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] = /* TW: New */ +{ + {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb, + 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb, + 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01, + 0x00 }}, + {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb, + 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01, + 0x00 }}, + {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb, + 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01, + 0x00 }}, + {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb, + 0x7f,0x86,0xdf,0x25,0x10,0x00,0x01, + 0x00 }}, + {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1, + 0xbb,0x82,0x57,0x25,0x10,0x00,0x01, + 0x01 }}, + {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5, + 0x0f,0x86,0xff,0x25,0x30,0x00,0x01, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] = /* TW: New */ +{ + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00 }}, + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, + 0x00 }}, + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00 }}, + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, + 0x00 }}, + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9e, + 0x03,0x87,0xdf,0x29,0x01,0x00,0x06, + 0x00 }}, + {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, + 0x01 }}, + {{0x8e,0x3f,0x92,0x79,0x07,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x06, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1[] = /* TW: New */ +{ + {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05, + 0x00}}, + {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05, + 0x00}}, + {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}}, + {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x07, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1_H[] = /* TW: New */ +{ + {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f, + 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00, + 0x00}}, + {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e, + 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, + 0x00}}, + {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0, + 0x58,0x8c,0x57,0x73,0x20,0x00,0x01, + 0x01}}, + {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] = /* TW: New */ +{ + {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, + 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, + 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f, + 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0, + 0x5a,0x8e,0x57,0x67,0x20,0x00,0x06, + 0x01}}, + {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf5, + 0x02,0x86,0xff,0x0f,0x10,0x00,0x02, + 0x01}}, + {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0x5a, + 0x02,0x86,0xff,0x0f,0x09,0x00,0x07, + 0x01}}, + {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10, + 0x1a,0x80,0x19,0x29,0x0f,0x00,0x03, + 0x00}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] = /* TW: New */ +{ + {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, + 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f, + 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f, + 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0, + 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01, + 0x01}}, + {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5, + 0x02,0x86,0xff,0x0f,0x10,0x00,0x01, + 0x01}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a, + 0x02,0x86,0xff,0x0f,0x09,0x00,0x05, + 0x01}}, + {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10, + 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05, + 0x00}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] = /* TW: New */ +{ + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, + 0x01}}, + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9e, + 0x03,0x87,0xdf,0x29,0x01,0x00,0x03, + 0x00}}, + {{0xce,0x63,0x92,0x96,0x04,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x07, + 0x01}}, + {{0xce,0x7f,0x92,0xa4,0x12,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x07, + 0x01}}, + {{0xce,0x9f,0x92,0xb4,0x02,0x28,0x5a, + 0x13,0x87,0xff,0x29,0x29,0x00,0x03, + 0x01}}, + {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10, + 0x20,0x84,0x19,0x29,0x0f,0x00,0x03, + 0x00}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] = /* TW: New */ +{ + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9e, + 0x03,0x87,0xdf,0x29,0x01,0x00,0x06, + 0x00}}, + {{0x9c,0x31,0x80,0x64,0x92,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, + 0x01}}, + {{0x8e,0x3f,0x92,0x64,0x12,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x06, + 0x01}}, + {{0x7e,0x4f,0x82,0x64,0x12,0x28,0x5a, + 0x13,0x87,0xff,0x29,0x29,0x00,0x06, + 0x01}}, + {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10, + 0x20,0x84,0x19,0x29,0x0f,0x00,0x05, + 0x00}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_1[] = /* TW: New */ +{ /* TW: Temp data, invalid */ + {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f, + 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06, + 0x00 }}, + {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f, + 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06, + 0x00 }}, + {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f, + 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06, + 0x00 }}, + {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f, + 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06, + 0x00 }}, + {{0x7e,0x4f,0x82,0x56,0x04,0x08,0x3e, + 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06, + 0x00 }}, + {{0x92,0x63,0x96,0x6a,0x18,0x80,0xf0, + 0x58,0x8c,0x57,0x81,0x20,0x00,0x06, + 0x01 }}, + {{0xae,0x7f,0x92,0x86,0x94,0x28,0xf5, + 0x00,0x84,0xff,0x29,0x10,0x00,0x02, + 0x01 }}, + {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a, + 0x00,0x84,0xff,0x29,0x09,0x00,0x07, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_1_H[] = /* TW: New */ +{ /* TW: Temp data, invalid */ + {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f, + 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05, + 0x00 }}, + {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f, + 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05, + 0x00 }}, + {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f, + 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05, + 0x00 }}, + {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f, + 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05, + 0x01 }}, + {{0x56,0x27,0x9a,0x2e,0x1c,0x08,0x3e, + 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05, + 0x00 }}, + {{0x60,0x31,0x84,0x38,0x86,0x80,0xf0, + 0x58,0x8c,0x57,0x81,0x20,0x00,0x01, + 0x01 }}, + {{0x6e,0x3f,0x92,0x46,0x94,0x28,0xf5, + 0x00,0x84,0xff,0x29,0x10,0x00,0x01, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_2[] = /* TW: New */ +{ /* TW: Temp data, invalid */ + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00 }}, + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, + 0x00 }}, + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00 }}, + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, + 0x00 }}, + {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9e, + 0x03,0x87,0xdf,0x29,0x01,0x00,0x03, + 0x00 }}, + {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x03, + 0x01 }}, + {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x07, + 0x01 }}, + {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a, + 0x00,0x84,0xff,0x29,0x09,0x00,0x07, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x768_2_H[] = /* TW: New */ +{ /* TW: Temp data, invalid */ + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00 }}, + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, + 0x00 }}, + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00 }}, + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, + 0x00 }}, + {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9e, + 0x03,0x87,0xdf,0x29,0x01,0x00,0x06, + 0x00 }}, + {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, + 0x01 }}, + {{0x8e,0x3f,0x92,0x79,0x07,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x06, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_1[] = +{ + {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, + 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, + 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e, + 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e, + 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba, + 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01, + 0x00}}, + {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1, + 0xae,0x85,0x57,0x1f,0x30,0x00,0x26, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1, + 0xae,0x85,0x57,0x1f,0x30,0x00,0x02, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_1_H[] = +{ + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, + 0x00}}, + {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x600_2_H[] = +{ + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x01, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_1[] = +{ + {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x01, + 0x00}}, + {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01, + 0x00}}, + {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_1_H[] = +{ + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f, + 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f, + 0x60,0x87,0x5d,0x83,0x10,0x00,0x44, + 0x00}}, + {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e, + 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44, + 0x00}}, + {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0, + 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_2[] = +{ + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x06, + 0x00}}, + {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x02, + 0x01}}, + {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11152x768_2_H[] = +{ + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x31,0x87,0x5d,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb, + 0x72,0x88,0xdf,0x25,0x30,0x00,0x01, + 0x00}}, + {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1, + 0xae,0x84,0x57,0x25,0x30,0x00,0x01, + 0x01}}, + {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5, + 0x02,0x88,0xff,0x25,0x10,0x00,0x01, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] = +{ /* TW: Temporary data - invalid */ + {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, + 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f, + 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f, + 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0, + 0x5a,0x8e,0x57,0x67,0x20,0x00,0x06, + 0x01}}, + {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf5, + 0x02,0x86,0xff,0x0f,0x10,0x00,0x02, + 0x01}}, + {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0x5a, + 0x02,0x86,0xff,0x0f,0x09,0x00,0x07, + 0x01}}, + {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10, + 0x1a,0x80,0x19,0x29,0x0f,0x00,0x03, + 0x00}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1_H[] = +{ /* TW: Temporary data - invalid */ + {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, + 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f, + 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f, + 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05, + 0x00}}, + {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f, + 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05, + 0x00}}, + {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0, + 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01, + 0x01}}, + {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5, + 0x02,0x86,0xff,0x0f,0x10,0x00,0x01, + 0x01}}, + {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a, + 0x02,0x86,0xff,0x0f,0x09,0x00,0x05, + 0x01}}, + {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10, + 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05, + 0x00}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2[] = +{ /* TW: Temporary data - invalid */ + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, + 0x01}}, + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03, + 0x00}}, + {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9e, + 0x03,0x87,0xdf,0x29,0x01,0x00,0x03, + 0x00}}, + {{0xce,0x63,0x92,0x96,0x04,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x07, + 0x01}}, + {{0xce,0x7f,0x92,0xa4,0x12,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x07, + 0x01}}, + {{0xce,0x9f,0x92,0xb4,0x02,0x28,0x5a, + 0x13,0x87,0xff,0x29,0x29,0x00,0x03, + 0x01}}, + {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10, + 0x20,0x84,0x19,0x29,0x0f,0x00,0x03, + 0x00}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] = /* TW: New */ +{ /* TW: Temporary data - invalid */ + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a, + 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06, + 0x00}}, + {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9e, + 0x03,0x87,0xdf,0x29,0x01,0x00,0x06, + 0x00}}, + {{0x9c,0x31,0x80,0x64,0x92,0x28,0xd4, + 0x3f,0x83,0x57,0x29,0x01,0x00,0x06, + 0x01}}, + {{0x8e,0x3f,0x92,0x64,0x12,0x28,0xd4, + 0x93,0x87,0xff,0x29,0x21,0x00,0x06, + 0x01}}, + {{0x7e,0x4f,0x82,0x64,0x12,0x28,0x5a, + 0x13,0x87,0xff,0x29,0x29,0x00,0x06, + 0x01}}, + {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10, + 0x20,0x84,0x19,0x29,0x0f,0x00,0x05, + 0x00}} +}; + + +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] = /* TW: New */ +{ + {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, + 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, + 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, + 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01, + 0x00 }}, + {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, + 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01, + 0x00 }}, + {{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba, + 0x0a,0x84,0xdf,0x57,0x00,0x00,0x01, + 0x00 }}, + {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0, + 0x7a,0x8f,0x57,0xed,0x20,0x00,0x06, + 0x01 }}, + {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5, /* TW: 1024x768 */ + 0x36,0x88,0xff,0xb0,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] = /* TW: New */ +{ + {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e, + 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e, + 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e, + 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01, + 0x00 }}, + {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e, + 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01, + 0x00 }}, + {{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e, + 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01, + 0x00 }}, + {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0, + 0x78,0x8a,0x57,0xbb,0x20,0x00,0x06, + 0x01 }}, + {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5, /* TW: 1024x768 */ + 0x15,0x88,0xff,0x47,0x70,0x00,0x02, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] = /* TW: New */ +{ + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba, + 0x15,0x83,0xdf,0x70,0x00,0x00,0x01, + 0x00 }}, + {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0, + 0x90,0x8c,0x57,0xed,0x20,0x00,0x05, + 0x01 }}, + {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5, /* TW: 1024x768 */ + 0x50,0x88,0xff,0xe7,0x10,0x00,0x02, + 0x01}} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] = /* TW: New */ +{ + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba, + 0x15,0x83,0xdf,0x70,0x00,0x00,0x01, + 0x00 }}, + {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0, + 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05, + 0x01 }}, + {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, /* TW: 1024x768 */ + 0x28,0x88,0xff,0x6a,0x10,0x00,0x02, + 0x01 }} +}; + +static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1SOPAL[] = /* TW: New */ +{ + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, + 0x00 }}, + {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, + 0xde,0x81,0x5d,0x70,0x00,0x00,0x05, + 0x00 }}, + {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba, + 0x15,0x83,0xdf,0x70,0x00,0x00,0x01, + 0x00 }}, + {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0, + 0x5a,0x8b,0x57,0x70,0x20,0x00,0x05, + 0x01 }}, + {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5, /* TW: 1024x768 */ + 0x28,0x88,0xff,0x6a,0x10,0x00,0x02, + 0x01 }} +}; + +/* TW: New data for Chrontel 7019 (From 650/LVDS BIOS 1.10.0) */ +typedef struct _SiS310_CHTVRegDataStruct +{ + UCHAR Reg[16]; +} SiS310_CHTVRegDataStruct; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] = +{ + {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x6a,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x7e,0x80,0x98,0x00}}, + {{0xcf,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x88,0x30,0x7f,0x00}}, + {{0xee,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xd3,0xf2,0x36,0x00}} +}; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] = +{ + {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x69,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x43,0x04,0x00}}, + {{0xce,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1c,0x00,0x82,0x97,0x00}}, + {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}} +}; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] = +{ + {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}}, + {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x1f,0x84,0x3d,0x28,0x00}}, + {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}} +}; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] = +{ + {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}}, + {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}}, + {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}} +}; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_SOPAL[] = +{ + {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}}, + {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}}, + {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}} +}; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] = +{ + {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x72,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}}, + {{0xd7,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}}, + {{0xf6,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}} +}; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] = +{ + {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x71,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}}, + {{0xd6,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}}, + {{0xf5,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}} +}; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] = +{ + {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}}, + {{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x19,0x78,0xef,0x35,0x00}}, + {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x1a,0x33,0x3f,0x2f,0x00}} +}; + +static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] = +{ + {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, + {{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}}, + {{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x1f,0x15,0xc0,0x1e,0x00}}, + {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x1d,0xf1,0x6c,0xcb,0x00}} +}; + +static const UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53}; + +static const UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51}; + +static const UCHAR SiS310_CHTVVCLKUPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54}; + +static const UCHAR SiS310_CHTVVCLKOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52}; + +static const UCHAR SiS310_CHTVVCLKSOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52}; + +static const UCHAR SiS310_CHTVVCLKUPALM[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53}; + +static const UCHAR SiS310_CHTVVCLKOPALM[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51}; + +static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54}; + +static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52}; + +/* TW: New end */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/init.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/init.c new file mode 100644 index 000000000..74c302c8f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/init.c @@ -0,0 +1,5968 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.6 2003/02/04 02:44:28 dawes Exp $ */ +/* + * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330 + * (Universal module for Linux kernel framebuffer and XFree86 4.x) + * + * Assembler-To-C translation + * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net> + * Minor parts Copyright SiS, Inc. + * + * Based on BIOS + * 1.10.07, 1.10a for SiS650/LVDS+CH7019 + * 1.11.05 for 650/LVDS (w/o Chrontel) + * 1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for SiS650/301(B/LV) + * 2.04.50 (I) and 2.04.5c (II) for SiS630/301(B) + * 2.06.50 for 630/301B (dual VGA) + * 2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005 + * 2.04.5c, 2.04.6c for 730+LVDS+CH7005 + * 1.09b for 315/301(B) + * 1.16.51 for 300+301LVX (ECS A907) + * 1.01.03 for 330 (Xabre 400) + * + * 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 the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER 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. + * + * TW says: This code looks awful, I know. But please don't do anything about + * this otherwise debugging will be hell. + * The code is extremely fragile as regards the different chipsets, different + * video bridges and combinations thereof. If anything is changed, extreme + * care has to be taken that that change doesn't break it for other chipsets, + * bridges or combinations thereof. + * All comments in this file are by me, regardless if they are marked TW or not. + * + */ + +#include "init.h" + +#ifdef SIS300 +#include "300vtbl.h" +#endif + +#ifdef SIS315H +#include "310vtbl.h" +#endif + +#ifdef LINUX_XF86 +BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); +DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn); +#ifdef SISDUALHEAD /* TW: For dual head */ +BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); +BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + ScrnInfoPtr pScrn, DisplayModePtr mode); +#endif /* dual head */ +#endif /* linux_xf86 */ + +#ifdef LINUXBIOS +BOOLEAN SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +#endif + +#ifdef LINUX_XF86 +BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch); +#else +BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeNo); +#endif + +#if defined(ALLOC_PRAGMA) +#pragma alloc_text(PAGE,SiSSetMode) +#pragma alloc_text(PAGE,SiSInit) +#endif + +static ULONG GetDRAMSize(SiS_Private *SiS_Pr, + PSIS_HW_DEVICE_INFO HwDeviceExtension); + +static void DelaySeconds(int seconds); +void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code); + +#ifdef LINUX_XF86 +/* TW: Mode table for X driver */ +const UShort ModeIndex_320x480[] = {0x5a, 0x5b, 0x00, 0x00}; /* DSTN/FSTN */ +const UShort ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c}; +const UShort ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e}; +const UShort ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62}; +const UShort ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35}; +const UShort ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36}; +const UShort ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76}; +const UShort ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63}; +const UShort ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e}; +const UShort ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45}; +const UShort ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64}; +const UShort ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77}; +const UShort ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */ +const UShort ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65}; +const UShort ModeIndex_300_1280x960[] = {0x6e, 0x6f, 0x00, 0x7b}; +const UShort ModeIndex_310_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e}; +const UShort ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */ +const UShort ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b}; +const UShort ModeIndex_1280x768[] = {0x23, 0x24, 0x00, 0x25}; /* 310/325 series only */ +const UShort ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78}; +const UShort ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e}; +const UShort ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 310/325 series only */ +const UShort ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66}; +const UShort ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b}; +const UShort ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00}; +const UShort ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e}; +#endif + +static void +DelaySeconds(int seconds) +{ + int i; +#ifdef WIN2000 + int j; +#endif + + for (i=0;i<seconds;i++) { +#ifdef TC + delay(1000); +#endif + +#ifdef WIN2000 + for (j=0;j<20000;j++) + VideoPortStallExecution(50); +#endif + +#ifdef WINCE_HEADER +#endif + +#ifdef LINUX_KERNEL +#endif + } +} + +void +SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code) +{ + OutPortByte(0x80, code); + DelaySeconds(0x3); +} + +#ifdef SIS300 +static void +InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS300_SModeIDTable; + SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable; + SiS_Pr->SiS_StandTable = (SiS_StandTableStruct *)SiS300_StandTable; + SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS300_EModeIDTable; + SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS300_RefIndex; + SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS300_CRT1Table; + if(HwDeviceExtension->jChipType == SIS_300) { + SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_300; /* 300 */ + } else { + SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630 */ + } + SiS_Pr->SiS_ECLKData = (SiS_ECLKDataStruct *)SiS300_ECLKData; + SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS300_VCLKData; + SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS300_VCLKData; + SiS_Pr->SiS_ScreenOffset = SiS300_ScreenOffset; + SiS_Pr->SiS_StResInfo = (SiS_StResInfoStruct *)SiS300_StResInfo; + SiS_Pr->SiS_ModeResInfo = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo; + + SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect; + SiS_Pr->pSiS_SoftSetting = &SiS300_SoftSetting; + + SiS_Pr->SiS_SR15 = SiS300_SR15; + +#ifndef LINUX_XF86 + SiS_Pr->pSiS_SR07 = &SiS300_SR07; + SiS_Pr->SiS_CR40 = SiS300_CR40; + SiS_Pr->SiS_CR49 = SiS300_CR49; + SiS_Pr->pSiS_SR1F = &SiS300_SR1F; + SiS_Pr->pSiS_SR21 = &SiS300_SR21; + SiS_Pr->pSiS_SR22 = &SiS300_SR22; + SiS_Pr->pSiS_SR23 = &SiS300_SR23; + SiS_Pr->pSiS_SR24 = &SiS300_SR24; + SiS_Pr->SiS_SR25 = SiS300_SR25; + SiS_Pr->pSiS_SR31 = &SiS300_SR31; + SiS_Pr->pSiS_SR32 = &SiS300_SR32; + SiS_Pr->pSiS_SR33 = &SiS300_SR33; + SiS_Pr->pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2; + SiS_Pr->pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D; + SiS_Pr->pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E; + SiS_Pr->pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10; + SiS_Pr->pSiS_RGBSenseData = &SiS300_RGBSenseData; + SiS_Pr->pSiS_VideoSenseData = &SiS300_VideoSenseData; + SiS_Pr->pSiS_YCSenseData = &SiS300_YCSenseData; + SiS_Pr->pSiS_RGBSenseData2 = &SiS300_RGBSenseData2; + SiS_Pr->pSiS_VideoSenseData2 = &SiS300_VideoSenseData2; + SiS_Pr->pSiS_YCSenseData2 = &SiS300_YCSenseData2; +#endif + + SiS_Pr->SiS_NTSCPhase = SiS300_NTSCPhase; + SiS_Pr->SiS_PALPhase = SiS300_PALPhase; + SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2; + SiS_Pr->SiS_PALPhase2 = SiS300_PALPhase2; + SiS_Pr->SiS_PALMPhase = SiS300_PALMPhase; + SiS_Pr->SiS_PALNPhase = SiS300_PALNPhase; + SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2; + SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2; + + SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data; + SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data; + SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data; + SiS_Pr->SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_StLCD1280x1024Data; + SiS_Pr->SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1280x1024Data; + SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data; + SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768; + SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024; + SiS_Pr->SiS_LCD1280x960Data = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data; + SiS_Pr->SiS_ExtLCD1400x1050Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data; + SiS_Pr->SiS_ExtLCD1600x1200Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data; + SiS_Pr->SiS_StLCD1400x1050Data = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data; + SiS_Pr->SiS_StLCD1600x1200Data = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data; + SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050; + SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200; + + SiS_Pr->SiS_StPALData = (SiS_TVDataStruct *)SiS300_StPALData; + SiS_Pr->SiS_ExtPALData = (SiS_TVDataStruct *)SiS300_ExtPALData; + SiS_Pr->SiS_StNTSCData = (SiS_TVDataStruct *)SiS300_StNTSCData; + SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData; +#ifdef oldHV + SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData; + SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData; + SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData; +#endif + + SiS_Pr->SiS_NTSCTiming = SiS300_NTSCTiming; + SiS_Pr->SiS_PALTiming = SiS300_PALTiming; +#ifdef oldHV + SiS_Pr->SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing; + SiS_Pr->SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing; + SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming; + SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data; + SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu; + SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text; +#endif + + SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl; + SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS; + + SiS_Pr->SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1; + SiS_Pr->SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2; + SiS_Pr->SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1; + SiS_Pr->SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2; + SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1; + SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2; + SiS_Pr->SiS_LVDS1280x960Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1; + SiS_Pr->SiS_LVDS1280x960Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2; + SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1; + SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2; + SiS_Pr->SiS_LVDS1280x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1; + SiS_Pr->SiS_LVDS1280x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2; + SiS_Pr->SiS_LVDS1024x600Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1; + SiS_Pr->SiS_LVDS1024x600Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2; + SiS_Pr->SiS_LVDS1152x768Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1; + SiS_Pr->SiS_LVDS1152x768Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2; + SiS_Pr->SiS_LVDSXXXxXXXData_1 = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1; + SiS_Pr->SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1; + SiS_Pr->SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1; + SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1; + SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2; + SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1; + SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2; + SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; + SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; + SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData; + SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData; + SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData; + SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1; + SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1; + SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1; + SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS300_PanelType03_1; + SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1; + SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS300_PanelType05_1; + SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS300_PanelType06_1; + SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS300_PanelType07_1; + SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS300_PanelType08_1; + SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS300_PanelType09_1; + SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_1; + SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_1; + SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_1; + SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_1; + SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_1; + SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_1; + SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS300_PanelType00_2; + SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS300_PanelType01_2; + SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS300_PanelType02_2; + SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS300_PanelType03_2; + SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2; + SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS300_PanelType05_2; + SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS300_PanelType06_2; + SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS300_PanelType07_2; + SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS300_PanelType08_2; + SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS300_PanelType09_2; + SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_2; + SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_2; + SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_2; + SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2; + SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2; + SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2; + SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData; + SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData; + SiS_Pr->SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData; + SiS_Pr->SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData; + SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1; + SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1; + SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1; + SiS_Pr->SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1; + SiS_Pr->SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1; + SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H; + SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H; + SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H; + SiS_Pr->SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H; + SiS_Pr->SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H; + SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2; + SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2; + SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2; + SiS_Pr->SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2; + SiS_Pr->SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2; + SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H; + SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H; + SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H; + SiS_Pr->SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H; + SiS_Pr->SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H; + SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC; + SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC; + SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL; + SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1OPAL; + SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1SOPAL; + SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC; + SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC; + SiS_Pr->SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL; + SiS_Pr->SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL; + SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_SOPAL; + SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC; + SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC; + SiS_Pr->SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL; + SiS_Pr->SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL; + SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */ + SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL; + + /* TW: New from 300/301LV BIOS */ + SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1; + SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1; + SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1; + SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_1; + SiS_Pr->SiS_CRT2Part2_1024x768_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_2; + SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_2; + SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_2; + SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_2; + SiS_Pr->SiS_CRT2Part2_1024x768_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_3; + SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_3; + SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3; + SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3; + + /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */ + SiS_Pr->SiS_Panel320x480 = Panel_320x480; + SiS_Pr->SiS_Panel640x480 = Panel_640x480; + SiS_Pr->SiS_Panel800x600 = Panel_800x600; + SiS_Pr->SiS_Panel1024x768 = Panel_1024x768; + SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024; + SiS_Pr->SiS_Panel1280x960 = Panel_1280x960; + SiS_Pr->SiS_Panel1024x600 = Panel_1024x600; + SiS_Pr->SiS_Panel1152x768 = Panel_1152x768; + SiS_Pr->SiS_Panel1600x1200 = 16; /* TW: Something illegal */ + SiS_Pr->SiS_Panel1400x1050 = 16; /* TW: Something illegal */ + SiS_Pr->SiS_Panel1152x864 = 16; /* TW: Something illegal */ + SiS_Pr->SiS_Panel1280x768 = 16; /* TW: Something illegal */ + SiS_Pr->SiS_PanelMax = Panel_320x480; /* TW: highest value */ + SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* TW: Lowest value LVDS */ + SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* TW: lowest value 301 */ +} +#endif + +#ifdef SIS315H +static void +InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS310_SModeIDTable; + SiS_Pr->SiS_StandTable = (SiS_StandTableStruct *)SiS310_StandTable; + SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS310_EModeIDTable; + SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS310_RefIndex; + SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS310_CRT1Table; + /* TW: MCLK is different */ + if(HwDeviceExtension->jChipType == SIS_330) { + SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330; /* 330 */ + } else if(HwDeviceExtension->jChipType > SIS_315PRO) { + SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650; /* 550, 650 */ + } else { + SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315; /* 315 */ + } + SiS_Pr->SiS_MCLKData_1 = (SiS_MCLKDataStruct *)SiS310_MCLKData_1; + SiS_Pr->SiS_ECLKData = (SiS_ECLKDataStruct *)SiS310_ECLKData; + SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS310_VCLKData; + SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData; + SiS_Pr->SiS_ScreenOffset = SiS310_ScreenOffset; + SiS_Pr->SiS_StResInfo = (SiS_StResInfoStruct *)SiS310_StResInfo; + SiS_Pr->SiS_ModeResInfo = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo; + + SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect; + SiS_Pr->pSiS_SoftSetting = &SiS310_SoftSetting; + + SiS_Pr->SiS_SR15 = SiS310_SR15; + +#ifndef LINUX_XF86 + SiS_Pr->pSiS_SR07 = &SiS310_SR07; + SiS_Pr->SiS_CR40 = SiS310_CR40; + SiS_Pr->SiS_CR49 = SiS310_CR49; + SiS_Pr->pSiS_SR1F = &SiS310_SR1F; + SiS_Pr->pSiS_SR21 = &SiS310_SR21; + SiS_Pr->pSiS_SR22 = &SiS310_SR22; + SiS_Pr->pSiS_SR23 = &SiS310_SR23; + SiS_Pr->pSiS_SR24 = &SiS310_SR24; + SiS_Pr->SiS_SR25 = SiS310_SR25; + SiS_Pr->pSiS_SR31 = &SiS310_SR31; + SiS_Pr->pSiS_SR32 = &SiS310_SR32; + SiS_Pr->pSiS_SR33 = &SiS310_SR33; + SiS_Pr->pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2; + SiS_Pr->pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D; + SiS_Pr->pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E; + SiS_Pr->pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10; + SiS_Pr->pSiS_RGBSenseData = &SiS310_RGBSenseData; + SiS_Pr->pSiS_VideoSenseData = &SiS310_VideoSenseData; + SiS_Pr->pSiS_YCSenseData = &SiS310_YCSenseData; + SiS_Pr->pSiS_RGBSenseData2 = &SiS310_RGBSenseData2; + SiS_Pr->pSiS_VideoSenseData2 = &SiS310_VideoSenseData2; + SiS_Pr->pSiS_YCSenseData2 = &SiS310_YCSenseData2; +#endif + + SiS_Pr->SiS_NTSCPhase = SiS310_NTSCPhase; + SiS_Pr->SiS_PALPhase = SiS310_PALPhase; + SiS_Pr->SiS_NTSCPhase2 = SiS310_NTSCPhase2; + SiS_Pr->SiS_PALPhase2 = SiS310_PALPhase2; + SiS_Pr->SiS_PALMPhase = SiS310_PALMPhase; + SiS_Pr->SiS_PALNPhase = SiS310_PALNPhase; + SiS_Pr->SiS_PALMPhase2 = SiS310_PALMPhase2; + SiS_Pr->SiS_PALNPhase2 = SiS310_PALNPhase2; + SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase; + + SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data; + SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data; + SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data; + SiS_Pr->SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_StLCD1280x1024Data; + SiS_Pr->SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1280x1024Data; + SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data; + SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768; + SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024; + SiS_Pr->SiS_LCD1280x960Data = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data; + SiS_Pr->SiS_ExtLCD1400x1050Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data; + SiS_Pr->SiS_ExtLCD1600x1200Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data; + SiS_Pr->SiS_StLCD1400x1050Data = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data; + SiS_Pr->SiS_StLCD1600x1200Data = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data; + SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050; + SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200; + + SiS_Pr->SiS_StPALData = (SiS_TVDataStruct *)SiS310_StPALData; + SiS_Pr->SiS_ExtPALData = (SiS_TVDataStruct *)SiS310_ExtPALData; + SiS_Pr->SiS_StNTSCData = (SiS_TVDataStruct *)SiS310_StNTSCData; + SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData; +#ifdef oldHV + SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData; + SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData; + SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData; +#endif + + SiS_Pr->SiS_NTSCTiming = SiS310_NTSCTiming; + SiS_Pr->SiS_PALTiming = SiS310_PALTiming; +#ifdef oldHV + SiS_Pr->SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing; + SiS_Pr->SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing; + SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming; + SiS_Pr->SiS_HiTVExtTiming = SiS310_HiTVExtTiming; + SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data; + SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu; + SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text; +#endif + + SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl; + SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS; + + SiS_Pr->SiS_LVDS800x600Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1; + SiS_Pr->SiS_LVDS800x600Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2; + SiS_Pr->SiS_LVDS1024x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1; + SiS_Pr->SiS_LVDS1024x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2; + SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1; + SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2; + SiS_Pr->SiS_LVDS1280x960Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1; + SiS_Pr->SiS_LVDS1280x960Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2; + SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1; + SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2; + SiS_Pr->SiS_LVDS1280x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1; + SiS_Pr->SiS_LVDS1280x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2; + SiS_Pr->SiS_LVDS1024x600Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1; + SiS_Pr->SiS_LVDS1024x600Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2; + SiS_Pr->SiS_LVDS1152x768Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1; + SiS_Pr->SiS_LVDS1152x768Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2; + SiS_Pr->SiS_LVDSXXXxXXXData_1 = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1; + SiS_Pr->SiS_LVDS320x480Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1; + SiS_Pr->SiS_LVDS640x480Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1; + SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1; + SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2; + SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1; + SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2; + SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData; + SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData; + SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData; + SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData; + SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData; + SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALMData; + SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData; + SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData; + SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData; + SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1; + SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1; + SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1; + SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS310_PanelType03_1; + SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS310_PanelType04_1; + SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS310_PanelType05_1; + SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS310_PanelType06_1; + SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS310_PanelType07_1; + SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS310_PanelType08_1; + SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS310_PanelType09_1; + SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_1; + SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_1; + SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_1; + SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_1; + SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_1; + SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_1; + SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS310_PanelType00_2; + SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS310_PanelType01_2; + SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS310_PanelType02_2; + SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS310_PanelType03_2; + SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS310_PanelType04_2; + SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS310_PanelType05_2; + SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS310_PanelType06_2; + SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS310_PanelType07_2; + SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS310_PanelType08_2; + SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS310_PanelType09_2; + SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_2; + SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_2; + SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_2; + SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2; + SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2; + SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2; + + SiS_Pr->LVDS1024x768Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1; + SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1; + SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ; + SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ; + SiS_Pr->LVDS1024x768Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2; + SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2; + SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2; + SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ; + + /* TW: New from 650/301LV BIOS */ + SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1; + SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1; + SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1; + SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_1; + SiS_Pr->SiS_CRT2Part2_1024x768_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_2; + SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_2; + SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_2; + SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_2; + SiS_Pr->SiS_CRT2Part2_1024x768_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_3; + SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_3; + SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3; + SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3; + + SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData; + SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData; + SiS_Pr->SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData; + SiS_Pr->SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData; + + SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1; + SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1; + SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1; + SiS_Pr->SiS_LVDSCRT11400x1050_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1; + SiS_Pr->SiS_LVDSCRT11280x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1; + SiS_Pr->SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1; + SiS_Pr->SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1; + SiS_Pr->SiS_LVDSCRT11600x1200_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1; + SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H; + SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H; + SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H; + SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H; + SiS_Pr->SiS_LVDSCRT11280x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H; + SiS_Pr->SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H; + SiS_Pr->SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H; + SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H; + SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2; + SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2; + SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2; + SiS_Pr->SiS_LVDSCRT11400x1050_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2; + SiS_Pr->SiS_LVDSCRT11280x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2; + SiS_Pr->SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2; + SiS_Pr->SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2; + SiS_Pr->SiS_LVDSCRT11600x1200_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2; + SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H; + SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H; + SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H; + SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H; + SiS_Pr->SiS_LVDSCRT11280x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H; + SiS_Pr->SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H; + SiS_Pr->SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H; + SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H; + SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1; + SiS_Pr->SiS_LVDSCRT1320x480_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1; + SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC; + SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC; + SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL; + SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL; + SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL; + SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC; + SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC; + SiS_Pr->SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL; + SiS_Pr->SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL; + SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALM; + SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALM; + SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN; + SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN; + SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL; + SiS_Pr->SiS_LCDACRT1800x600_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1; + SiS_Pr->SiS_LCDACRT11024x768_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1; + SiS_Pr->SiS_LCDACRT11280x1024_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1; + SiS_Pr->SiS_LCDACRT11400x1050_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1; + SiS_Pr->SiS_LCDACRT11600x1200_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1; + SiS_Pr->SiS_LCDACRT1800x600_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1_H; + SiS_Pr->SiS_LCDACRT11024x768_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1_H; + SiS_Pr->SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1_H; + SiS_Pr->SiS_LCDACRT11400x1050_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1_H; + SiS_Pr->SiS_LCDACRT11600x1200_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1_H; + SiS_Pr->SiS_LCDACRT1800x600_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2; + SiS_Pr->SiS_LCDACRT11024x768_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2; + SiS_Pr->SiS_LCDACRT11280x1024_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2; + SiS_Pr->SiS_LCDACRT11400x1050_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2; + SiS_Pr->SiS_LCDACRT11600x1200_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2; + SiS_Pr->SiS_LCDACRT1800x600_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2_H; + SiS_Pr->SiS_LCDACRT11024x768_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2_H; + SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H; + SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H; + SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H; + SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC; + SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC; + SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL; + SiS_Pr->SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL; + SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM; + SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM; + SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN; + SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN; + SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKSOPAL; + + SiS_Pr->SiS_Panel320x480 = Panel_320x480; + SiS_Pr->SiS_Panel640x480 = Panel_640x480; + SiS_Pr->SiS_Panel800x600 = Panel_800x600; + SiS_Pr->SiS_Panel1024x768 = Panel_1024x768; + SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024; + SiS_Pr->SiS_Panel1280x960 = Panel_1280x960; + SiS_Pr->SiS_Panel1600x1200 = Panel_1600x1200; + SiS_Pr->SiS_Panel1400x1050 = Panel_1400x1050; + SiS_Pr->SiS_Panel1152x768 = Panel_1152x768; + SiS_Pr->SiS_Panel1152x864 = Panel_1152x864; + SiS_Pr->SiS_Panel1280x768 = Panel_1280x768; + SiS_Pr->SiS_Panel1024x600 = Panel_1024x600; + SiS_Pr->SiS_PanelMax = Panel_320x480; /* TW: highest value */ + SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* TW: lowest value LVDS/LCDA */ + SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* TW: lowest value 301 */ +} +#endif + +#ifdef LINUXBIOS +/* -------------- SiSInit -----------------*/ +/* TW: I degraded this for LINUXBIOS only, because we + * don't need this otherwise. Under normal + * circumstances, the video BIOS has initialized + * the adapter for us. BTW, this code is incomplete + * and very possibly not functioning on newer chipsets. + */ +BOOLEAN +SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + ULONG FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress; + USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; + UCHAR i, temp=0; + UCHAR SR11; +#ifdef LINUX_KERNEL + UCHAR temp1; + ULONG base; +#endif + UCHAR SR13=0, SR14=0, SR16=0 + UCHAR SR17=0, SR19=0, SR1A=0; +#ifdef SIS300 + UCHAR SR18=0, SR12=0; +#endif +#ifdef SIS315H + UCHAR CR37=0, CR38=0, CR79=0, + UCHAR CR7A=0, CR7B=0, CR7C=0; + UCHAR SR1B=0, SR15=0; + PSIS_DSReg pSR; + ULONG Temp; +#endif + UCHAR VBIOSVersion[5]; + + if(FBAddr==0) return (FALSE); + if(BaseAddr==0) return (FALSE); + + SiS_SetReg3((USHORT)(BaseAddr+0x12), 0x67); /* Misc */ + +#ifdef SIS315H + if(HwDeviceExtension->jChipType > SIS_315PRO) { + if(!HwDeviceExtension->bIntegratedMMEnabled) + return (FALSE); + } +#endif + + SiS_MemoryCopy(VBIOSVersion,HwDeviceExtension->szVBIOSVer,4); + VBIOSVersion[4]= 0x00; + + SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr); + + /* TW: Init pointers */ +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO) || + (HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_330)) + InitTo310Pointer(SiS_Pr, HwDeviceExtension); +#endif + +#ifdef SIS300 + if((HwDeviceExtension->jChipType == SIS_540) || + (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730) || + (HwDeviceExtension->jChipType == SIS_300)) + InitTo300Pointer(SiS_Pr, HwDeviceExtension); +#endif + + /* TW: Set SiS Register definitions */ + SiSRegInit(SiS_Pr, BaseAddr); + + /* TW: Determine LVDS/CH70xx/TRUMPION */ + SiS_Set_LVDS_TRUMPION(SiS_Pr, HwDeviceExtension); + + /* TW: Unlock registers */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); + +#ifdef LINUX_KERNEL + +#ifdef SIS300 /* Set SR14 */ + if((HwDeviceExtension->jChipType==SIS_540) || + (HwDeviceExtension->jChipType==SIS_630) || + (HwDeviceExtension->jChipType==SIS_730)) { + base=0x80000060; + OutPortLong(base,0xcf8); + temp1 = InPortLong(0xcfc); + temp1 >>= (16+8+4); + temp1 &= 0x07; + temp1++; + temp1 = 1 << temp1; + SR14 = temp1 - 1; + base = 0x80000064; + OutPortLong(base,0xcf8); + temp1 = InPortLong(0xcfc); + temp1 &= 0x00000020; + if(temp1) SR14 |= 0x80; + else SR14 |= 0x40; + } +#endif + +#ifdef SIS315H /* Set SR14 */ + if(HwDeviceExtension->jChipType == SIS_550) { + base = 0x80000060; + OutPortLong(base,0xcf8); + temp1 = InPortLong(0xcfc); + temp1 >>= (16+8+4); + temp1 &= 0x07; + temp1++; + temp1 = 1 << temp1; + SR14 = temp1 - 1; + base = 0x80000064; + OutPortLong(base,0xcf8); + temp1 = InPortLong(0xcfc); + temp1 &= 0x00000020; + if(temp1) SR14 |= 0x80; + else SR14 |= 0x40; + } + + if((HwDeviceExtension->jChipType == SIS_740) || /* Set SR14 */ + (HwDeviceExtension->jChipType == SIS_650)) { + base = 0x80000064; + OutPortLong(base,0xcf8); + temp1=InPortLong(0xcfc); + temp1 >>= 4; + temp1 &= 0x07; + if(temp1 > 2) { + temp = temp1; + switch(temp) { + case 3: temp1 = 0x07; break; + case 4: temp1 = 0x0F; break; + case 5: temp1 = 0x1F; break; + case 6: temp1 = 0x05; break; + case 7: temp1 = 0x17; break; + case 8: break; + case 9: break; + } + } + SR14 = temp1; + base = 0x8000007C; + OutPortLong(base,0xcf8); + temp1 = InPortLong(0xcfc); + temp1 &= 0x00000020; + if(temp1) SR14 |= 0x80; + } +#endif + +#endif /* Linux kernel */ + +#ifdef SIS300 + if((HwDeviceExtension->jChipType == SIS_540)|| + (HwDeviceExtension->jChipType == SIS_630)|| + (HwDeviceExtension->jChipType == SIS_730)) { + SR12 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x12); + SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13); + SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17); + SR18 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18); + SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19); + SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A); + } else if(HwDeviceExtension->jChipType == SIS_300){ + SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13); + SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + } +#endif +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_650)) { + SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19); + SR19 = (SR19)||0x01; /* TW: ??? || ??? */ + if(SR19==0x00) { + SR13 = 0x22; + SR14 = 0x00; + SR15 = 0x01; + SR16 = 0x00; + SR17 = 0x00; + SR1A = 0x00; + SR1B = 0x00; + CR37 = 0x00; + CR38 = 0x00; + CR79 = 0x00; + CR7A = 0x00; + CR7B = 0x00; + CR7C = 0x00; + } else { + SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13); + SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + SR15 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15); + SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17); + SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A); + SR1B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1B); + CR37 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37); /* TW: Was 0x02 - why? */ + CR38 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + CR79 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79); + CR7A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7A); + CR7B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7B); + CR7C = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7C); + } + } +#endif + + /* Reset extended registers */ + + for(i=0x06; i< 0x20; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0); + for(i=0x21; i<=0x27; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0); + for(i=0x31; i<=0x3D; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0); + +#ifdef SIS300 + if((HwDeviceExtension->jChipType == SIS_540) || + (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730) || + (HwDeviceExtension->jChipType == SIS_300)) { + for(i=0x38; i<=0x3F; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0); + } +#endif + +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO) || + (HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_330)) { + for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0); + for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0); + } +#endif + + /* Restore Extended Registers */ + +#ifdef SIS300 + if((HwDeviceExtension->jChipType == SIS_540) || + (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730)) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A); + } +#endif + +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_650)) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,SR15); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1B,SR1B); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,CR37); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,CR38); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x79,CR79); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7A,CR7A); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7B,CR7B); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7C,CR7C); + } +#endif + +#ifdef SIS300 + if((HwDeviceExtension->jChipType==SIS_540) || + (HwDeviceExtension->jChipType==SIS_630) || + (HwDeviceExtension->jChipType==SIS_730)) { + temp = (UCHAR)SR1A & 0x03; + } else if(HwDeviceExtension->jChipType == SIS_300) { + /* TW: Nothing */ + } +#endif +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO) || + (HwDeviceExtension->jChipType == SIS_330) ) { + if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) { + temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03; + } + } + if((HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_650)) { + if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) { + temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07; + } + } +#endif + + SiS_Pr->SiS_RAMType = temp; + SiS_SetMemoryClock(SiS_Pr, ROMAddr, HwDeviceExtension); + + /* Set default register contents */ + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x07,*SiS_Pr->pSiS_SR07); /* DAC speed */ + + if((HwDeviceExtension->jChipType != SIS_540) && + (HwDeviceExtension->jChipType != SIS_630) && + (HwDeviceExtension->jChipType != SIS_730)){ + for(i=0x15;i<0x1C;i++) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]); + } + } + +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO) || + (HwDeviceExtension->jChipType == SIS_330)) { + for(i=0x40;i<=0x44;i++) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,SiS_Pr->SiS_CR40[i-0x40][SiS_Pr->SiS_RAMType]); + } + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x48,0x23); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[0]); + /* SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]); */ + } +#endif + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,*SiS_Pr->pSiS_SR1F); /* DAC pedestal */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xA0); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x23,*SiS_Pr->pSiS_SR23); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x24,*SiS_Pr->pSiS_SR24); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]); + +#ifdef SIS300 + if(HwDeviceExtension->jChipType == SIS_300) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,0x84); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,0x00); + } +#endif + + SR11 = 0x0F; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x11,SR11); /* Power Management & DDC port */ + + SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x00); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,*SiS_Pr->pSiS_CRT2Data_1_2); + +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO) || + (HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_330)) + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08); /* use VB */ +#endif + + temp = *SiS_Pr->pSiS_SR32; + if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)) { + temp &= 0xEF; + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp); + +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO) || + (HwDeviceExtension->jChipType == SIS_330)) { + HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,0x50,0,&Temp); + Temp >>= 20; + Temp &= 0xF; + if (Temp != 1) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[1]); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[1]); + } + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x27,0x1F); + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,*SiS_Pr->pSiS_SR31); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,*SiS_Pr->pSiS_SR32); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x33,*SiS_Pr->pSiS_SR33); + } +#endif + + if (SiS_BridgeIsOn(SiS_Pr, BaseAddr) == 0) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1C); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0D,*SiS_Pr->pSiS_CRT2Data_4_D); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0E,*SiS_Pr->pSiS_CRT2Data_4_E); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,*SiS_Pr->pSiS_CRT2Data_4_10); + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0F,0x3F); + } + SiS_LockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); + } + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x83,0x00); + +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO) || + (HwDeviceExtension->jChipType == SIS_330)) { + if(HwDeviceExtension->bSkipDramSizing==TRUE) { + SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr,HwDeviceExtension); + pSR = HwDeviceExtension->pSR; + if(pSR != NULL) { + while(pSR->jIdx != 0xFF) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,pSR->jIdx,pSR->jVal); + pSR++; + } + } + } else SiS_SetDRAMSize_310(SiS_Pr, HwDeviceExtension); + } +#endif + +#ifdef SIS315H + if(HwDeviceExtension->jChipType == SIS_550) { + /* SetDRAMConfig begin */ +/* SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A); */ + /* SetDRAMConfig end */ + } +#endif + +#ifdef SIS300 + if(HwDeviceExtension->jChipType == SIS_300) { + if (HwDeviceExtension->bSkipDramSizing == TRUE) { +/* SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension); + temp = (HwDeviceExtension->pSR)->jVal; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,temp); + temp = (HwDeviceExtension->pSR)->jVal; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,temp); */ + } else { +#ifdef TC + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14); + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x15,0xFF,0x04); +#else + SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension); + SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension); +#endif + } + } + if((HwDeviceExtension->jChipType==SIS_540)|| + (HwDeviceExtension->jChipType==SIS_630)|| + (HwDeviceExtension->jChipType==SIS_730)) { +#if 0 + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A); +#endif + } +/* SetDRAMSize end */ +#endif /* SIS300 */ + + /* Set default Ext2Regs */ +#if 0 + AGP=1; + temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A); + temp &= 0x30; + if(temp == 0x30) AGP=0; + if(AGP == 0) *SiS_Pr->pSiS_SR21 &= 0xEF; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21); + if(AGP == 1) *SiS_Pr->pSiS_SR22 &= 0x20; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22); +#endif + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22); + +#if 0 + SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff); + SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8); +#endif + +#ifdef LINUXBIOS /* TW: This is not needed for our purposes */ + SiS_DetectMonitor(SiS_Pr, HwDeviceExtension,BaseAddr); /* Sense CRT1 */ + SiS_GetSenseStatus(SiS_Pr, HwDeviceExtension,ROMAddr); /* Sense CRT2 */ +#endif + + return(TRUE); +} + +void +SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp = 0; + +#ifdef SiS300 + if((HwDeviceExtension->jChipType == SIS_540) || + (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730)) { + /* TW: Read POWER_ON_TRAP and copy to CR37 */ + temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A); + temp = (temp & 0xE0) >> 4; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp); + } +#endif +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_330)) { +#if 0 /* TW: This is not required */ + /* TW: Read POWER_ON_TRAP and copy to CR37 */ + temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A); + temp = (temp & 0xE0) >> 4; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp); +#endif + } +#endif + + SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, 0); +} + +/* =============== SiS 300 dram sizing begin =============== */ +#ifdef SIS300 +void +SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + ULONG FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress; + USHORT SR13, SR14=0, buswidth, Done; + SHORT i, j, k; + USHORT data, TotalCapacity, PhysicalAdrOtherPage=0; + ULONG Addr; + UCHAR temp; + int PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount; + int RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank; + int PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage; + + SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e); + + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20); /* Turn OFF Display */ + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0xBF); + + buswidth = SiS_ChkBUSWidth_300(SiS_Pr, FBAddr); + + MB2Bank = 16; + Done = 0; + for(i=6; i>=0; i--) { + if(Done == 1) break; + PseudoRankCapacity = 1 << i; + for(j=4; j>=1; j--) { + if(Done == 1) break; + PseudoTotalCapacity = PseudoRankCapacity * j; + PseudoAdrPinCount = 15 - j; + if(PseudoTotalCapacity <= 64) { + for(k=0; k<=16; k++) { + if(Done == 1) break; + RankCapacity = buswidth * SiS_DRAMType[k][3]; + AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0]; + if(RankCapacity == PseudoRankCapacity) + if(AdrPinCount <= PseudoAdrPinCount) { + if(j == 3) { /* Rank No */ + BankNumHigh = RankCapacity * MB2Bank * 3 - 1; + BankNumMid = RankCapacity * MB2Bank * 1 - 1; + } else { + BankNumHigh = RankCapacity * MB2Bank * j - 1; + BankNumMid = RankCapacity * MB2Bank * j / 2 - 1; + } + PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4; + PhysicalAdrHigh = BankNumHigh; + PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity; + PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh; + /* Write data */ + /*Test*/ + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x15,0xFB); + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x15,0x04); + /*/Test*/ + TotalCapacity = SiS_DRAMType[k][3] * buswidth; + SR13 = SiS_DRAMType[k][4]; + if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80; + if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40; + if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14); + + Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh; + *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; + Addr = FBAddr + (BankNumMid) * 64 * 1024 + PhysicalAdrHigh; + *((USHORT *)(Addr)) = (USHORT)BankNumMid; + Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHalfPage; + *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage; + Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrOtherPage; + *((USHORT *)(Addr)) = PhysicalAdrOtherPage; + + /* Read data */ + Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh; + data = *((USHORT *)(Addr)); + if(data == PhysicalAdrHigh) Done = 1; + } /* if struct */ + } /* for loop (k) */ + } /* if struct */ + } /* for loop (j) */ + } /* for loop (i) */ +} + +USHORT +SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress) +{ + PULONG pVideoMemory; + + pVideoMemory = (PULONG)FBAddress; + + pVideoMemory[0] = 0x01234567L; + pVideoMemory[1] = 0x456789ABL; + pVideoMemory[2] = 0x89ABCDEFL; + pVideoMemory[3] = 0xCDEF0123L; + if (pVideoMemory[3]==0xCDEF0123L) { /* Channel A 128bit */ + return(4); + } + if (pVideoMemory[1]==0x456789ABL) { /* Channel B 64bit */ + return(2); + } + return(1); +} +#endif +/* =============== SiS 300 dram sizing end =============== */ + +/* ============ SiS 310/325 dram sizing begin ============== */ +#ifdef SIS315H + +/* TW: Moved Get310DRAMType further down */ + +void +SiS_Delay15us(SiS_Private *SiS_Pr, ULONG ulMicrsoSec) +{ +} + +void +SiS_SDR_MRS(SiS_Private *SiS_Pr, ) +{ + USHORT data; + + data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + data &= 0x3F; /* SR16 D7=0, D6=0 */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data); /* enable mode register set(MRS) low */ + SiS_Delay15us(SiS_Pr, 0x100); + data |= 0x80; /* SR16 D7=1, D6=0 */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data); /* enable mode register set(MRS) high */ + SiS_Delay15us(SiS_Pr, 0x100); +} + +void +SiS_DDR_MRS(SiS_Private *SiS_Pr) +{ + USHORT data; + + /* SR16 <- 1F,DF,2F,AF */ + + /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */ + data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + data &= 0x0F; + data |= 0x10; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data); + + if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10)) + data &= 0x0F; + + /* SR16 D7=1,D6=1 */ + data |= 0xC0; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data); + + /* SR16 D7=1,D6=0,D5=1,D4=0 */ + data &= 0x0F; + data |= 0x20; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data); + if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10)) + data &= 0x0F; + + /* SR16 D7=1 */ + data |= 0x80; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data); +} + +void +SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + if (SiS_Get310DRAMType(ROMAddr,HwDeviceExtension) < 2) + SiS_SDR_MRS(SiS_Pr); + else + /* SR16 <- 0F,CF,0F,8F */ + SiS_DDR_MRS(SiS_Pr); +} + +void +SiS_DisableRefresh(SiS_Private *SiS_Pr) +{ + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x17,0xF8); + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x19,0x03); +} + +void +SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr) +{ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SiS_Pr->SiS_SR15[2][SiS_Pr->SiS_RAMType]); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SiS_Pr->SiS_SR15[4][SiS_Pr->SiS_RAMType]); +} + +void +SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index, + USHORT SiS_DDRDRAM_TYPE[][5]) +{ + USHORT data; + + data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15); + data &= 0x1F; + switch (SiS_DDRDRAM_TYPE[index][3]) + { + case 64: data |= 0; break; + case 32: data |= 0x20; break; + case 16: data |= 0x40; break; + case 4: data |= 0x60; break; + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data); +} + +void +SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index, USHORT DRAMTYPE_TABLE[][5]) +{ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,DRAMTYPE_TABLE[index][4]); + /* should delay 50 ns */ +} + +void +SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT data, temp; + PULONG volatile pVideoMemory; + + pVideoMemory = (PULONG)FBAddress; + + if(HwDeviceExtension->jChipType == SIS_330) temp = 1; + else temp = 2; + + if(SiS_Get310DRAMType(ROMAddress,HwDeviceExtension) < temp) { + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00); + if(HwDeviceExtension->jChipType != SIS_330) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x12); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02); + } + /* should delay */ + SiS_SDR_MRS(SiS_Pr); + + SiS_Pr->SiS_ChannelAB = 0; + SiS_Pr->SiS_DataBusWidth = 128; + pVideoMemory[0] = 0x01234567L; + pVideoMemory[1] = 0x456789ABL; + pVideoMemory[2] = 0x89ABCDEFL; + pVideoMemory[3] = 0xCDEF0123L; + pVideoMemory[4] = 0x55555555L; + pVideoMemory[5] = 0x55555555L; + pVideoMemory[6] = 0xFFFFFFFFL; + pVideoMemory[7] = 0xFFFFFFFFL; + if((pVideoMemory[3] != 0xCDEF0123L) || (pVideoMemory[2] != 0x89ABCDEFL)) { + /* Channel A 64Bit */ + SiS_Pr->SiS_DataBusWidth = 64; + SiS_Pr->SiS_ChannelAB = 0; + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x14, 0xFD); + } + if((pVideoMemory[1] != 0x456789ABL) || (pVideoMemory[0] != 0x01234567L)) { + /* Channel B 64Bit */ + SiS_Pr->SiS_DataBusWidth = 64; + SiS_Pr->SiS_ChannelAB = 1; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x14,0xfd,0x01); + } + return; + + } else { + + /* DDR Dual channel */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02); /* Channel A, 64bit */ + /* should delay */ + SiS_DDR_MRS(SiS_Pr); + + SiS_Pr->SiS_ChannelAB = 0; + SiS_Pr->SiS_DataBusWidth = 64; + pVideoMemory[0] = 0x01234567L; + pVideoMemory[1] = 0x456789ABL; + pVideoMemory[2] = 0x89ABCDEFL; + pVideoMemory[3] = 0xCDEF0123L; + pVideoMemory[4] = 0x55555555L; + pVideoMemory[5] = 0x55555555L; + pVideoMemory[6] = 0xAAAAAAAAL; + pVideoMemory[7] = 0xAAAAAAAAL; + + if (pVideoMemory[1] == 0x456789ABL) { + if (pVideoMemory[0] == 0x01234567L) { + /* Channel A 64bit */ + return; + } + } else { + if (pVideoMemory[0] == 0x01234567L) { + /* Channel A 32bit */ + SiS_Pr->SiS_DataBusWidth = 32; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x00); + return; + } + } + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x03); /* Channel B, 64bit */ + SiS_DDR_MRS(SiS_Pr); + + SiS_Pr->SiS_ChannelAB = 1; + SiS_Pr->SiS_DataBusWidth = 64; + pVideoMemory[0] = 0x01234567L; + pVideoMemory[1] = 0x456789ABL; + pVideoMemory[2] = 0x89ABCDEFL; + pVideoMemory[3] = 0xCDEF0123L; + pVideoMemory[4] = 0x55555555L; + pVideoMemory[5] = 0x55555555L; + pVideoMemory[6] = 0xAAAAAAAAL; + pVideoMemory[7] = 0xAAAAAAAAL; + if(pVideoMemory[1] == 0x456789ABL) { + /* Channel B 64 */ + if(pVideoMemory[0] == 0x01234567L) { + /* Channel B 64bit */ + return; + } else { + /* error */ + } + } else { + if(pVideoMemory[0] == 0x01234567L) { + /* Channel B 32 */ + SiS_Pr->SiS_DataBusWidth = 32; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x01); + } else { + /* error */ + } + } + } +} + +int +SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5]) +{ + USHORT data; + int RankSize; + + if ((RankNo==2)&&(DRAMTYPE_TABLE[index][0]==2)) + return 0; + + RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32; + + if (RankNo * RankSize <= 128) { + data = 0; + while((RankSize >>= 1) > 0) { + data += 0x10; + } + data |= (RankNo - 1) << 2; + data |= (SiS_Pr->SiS_DataBusWidth / 64) & 2; + data |= SiS_Pr->SiS_ChannelAB; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data); + /* should delay */ + SiS_SDR_MRS(SiS_Pr); + return 1; + } else + return 0; +} + +int +SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo, + USHORT DRAMTYPE_TABLE[][5]) +{ + USHORT data; + int RankSize; + + RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32; + /* RankSize = DRAMTYPE_TABLE[index][3]; */ + if (ChannelNo * RankSize <= 128) { + data = 0; + while((RankSize >>= 1) > 0) { + data += 0x10; + } + if(ChannelNo == 2) data |= 0x0C; + data |= (SiS_Pr->SiS_DataBusWidth / 32) & 2; + data |= SiS_Pr->SiS_ChannelAB; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data); + /* should delay */ + SiS_DDR_MRS(SiS_Pr); + return 1; + } else + return 0; +} + +int +SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress) +{ + int i; + ULONG Increment,Position; + + /*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 1); */ + Increment = 1 << (10 + SiS_Pr->SiS_DataBusWidth / 64); + + for (i=0,Position=0;i<2;i++) { + *((PULONG)(FBAddress + Position)) = Position; + Position += Increment; + } + + for (i=0,Position=0;i<2;i++) { +/* if (FBAddress[Position]!=Position) */ + if((*(PULONG)(FBAddress + Position)) != Position) + return 0; + Position += Increment; + } + return 1; +} + +int +SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress) +{ + int i; + ULONG Increment,Position; + Increment = 1 << (DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 2); + + for (i=0,Position=0;i<4;i++) { +/* FBAddress[Position]=Position; */ + *((PULONG)(FBAddress + Position)) = Position; + Position += Increment; + } + + for (i=0,Position=0;i<4;i++) { +/* if (FBAddress[Position]!=Position) */ + if((*(PULONG)(FBAddress + Position)) != Position) + return 0; + Position += Increment; + } + return 1; +} + +int +SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress) +{ + int i; + ULONG Increment,Position; + Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] + + DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo); + + for (i=0,Position=0;i<2;i++) { +/* FBAddress[Position]=Position; */ + *((PULONG)(FBAddress+Position))=Position; + /* *((PULONG)(FBAddress))=Position; */ + Position += Increment; + } + + for (i=0,Position=0;i<2;i++) { +/* if (FBAddress[Position]!=Position) */ + if ( (*(PULONG) (FBAddress + Position)) !=Position) + /*if ( (*(PULONG) (FBAddress )) !=Position) */ + return 0; + Position += Increment; + } + return 1; +} + +int +SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress) +{ + ULONG Increment,Position; + USHORT data; + + Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] + + DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo); + + Increment += Increment/2; + + Position =0; + *((PULONG)(FBAddress+Position + 0)) = 0x01234567; + *((PULONG)(FBAddress+Position + 1)) = 0x456789AB; + *((PULONG)(FBAddress+Position + 2)) = 0x55555555; + *((PULONG)(FBAddress+Position + 3)) = 0x55555555; + *((PULONG)(FBAddress+Position + 4)) = 0xAAAAAAAA; + *((PULONG)(FBAddress+Position + 5)) = 0xAAAAAAAA; + + if ( (*(PULONG) (FBAddress + 1)) == 0x456789AB) + return 1; + + if ( (*(PULONG) (FBAddress + 0)) == 0x01234567) + return 0; + + data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + data &= 0xF3; + data |= 0x08; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data); + data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15); + data += 0x20; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data); + + return 1; +} + +int +SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress) +{ + int r; + + for (r=RankNo;r>=1;r--) { + if (!SiS_CheckRank(SiS_Pr, r, index, DRAMTYPE_TABLE, FBAddress)) + return 0; + } + if (!SiS_CheckBanks(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress)) + return 0; + + if (!SiS_CheckColumn(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress)) + return 0; + + return 1; +} + +int +SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5], + ULONG FBAddress) +{ + int r; + + for (r=RankNo;r>=1;r--) { + if (!SiS_CheckDDRRank(SiS_Pr, r,index,DRAMTYPE_TABLE,FBAddress)) + return 0; + } + if (!SiS_CheckBanks(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress)) + return 0; + + if (!SiS_CheckColumn(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress)) + return 0; + + return 1; +} + +int +SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress) +{ + int i; + UCHAR j; + + for (i=0;i<13;i++) { + SiS_SetDRAMSizingType(SiS_Pr, i, SiS_SDRDRAM_TYPE); + for (j=2;j>0;j--) { + if (!SiS_SetRank(SiS_Pr, i,(UCHAR) j, SiS_SDRDRAM_TYPE)) + continue; + else { + if (SiS_CheckRanks(SiS_Pr, j,i,SiS_SDRDRAM_TYPE, FBAddress)) + return 1; + } + } + } + return 0; +} + +int +SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress) +{ + + int i; + UCHAR j; + + for (i=0; i<4; i++){ + SiS_SetDRAMSizingType(SiS_Pr, i, SiS_DDRDRAM_TYPE); + SiS_DisableChannelInterleaving(SiS_Pr, i, SiS_DDRDRAM_TYPE); + for (j=2; j>0; j--) { + SiS_SetDDRChannel(SiS_Pr, i, j, SiS_DDRDRAM_TYPE); + if (!SiS_SetRank(SiS_Pr, i, (UCHAR) j, SiS_DDRDRAM_TYPE)) + continue; + else { + if (SiS_CheckDDRRanks(SiS_Pr, j, i, SiS_DDRDRAM_TYPE, FBAddress)) + return 1; + } + } + } + return 0; +} + +/* + check if read cache pointer is correct +*/ +void +SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr) +{ + PUCHAR pVideoMemory = (PUCHAR) FBAddr; + UCHAR i, j; + USHORT Temp,SR21; + + pVideoMemory[0] = 0xaa; /* alan */ + pVideoMemory[16] = 0x55; /* note: PCI read cache is off */ + + if((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) { + for (i=0,j=16; i<2; i++,j+=16) { + SR21 = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21); + Temp = SR21 & 0xFB; /* disable PCI post write buffer empty gating */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,Temp); + + Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x3C); + Temp |= 0x01; /* MCLK reset */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp); + Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3C); + Temp &= 0xFE; /* MCLK normal operation */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,SR21); + + pVideoMemory[16+j] = j; + if(pVideoMemory[16+j] == j) { + pVideoMemory[j] = j; + break; + } + } + } +} + +/* TW: Is this a 315E? */ +int +Is315E(SiS_Private *SiS_Pr) +{ + USHORT data; + + data = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5F); + if(data & 0x10) return 1; + else return 0; +} + +/* TW: For 315 only */ +void +SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + ULONG FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress; + USHORT data; + +#ifdef SIS301 /* TW: SIS301 ??? */ + /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x40); */ +#endif +#ifdef SIS302 /* TW: SIS302 ??? */ + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x4D); /* alan,should change value */ + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0xc0); /* alan,should change value */ + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,0x3F); /* alan,should change value */ +#endif + + SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e); + + data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x21,0xDF); /* disable read cache */ + + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20); /* Turn OFF Display */ + + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x16,0x0F); /* assume lowest speed DRAM */ + + SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr, HwDeviceExtension); + SiS_DisableRefresh(SiS_Pr); + SiS_CheckBusWidth_310(SiS_Pr, ROMAddr, FBAddr, HwDeviceExtension); + + SiS_VerifyMclk(SiS_Pr, FBAddr); + + if(HwDeviceExtension->jChipType == SIS_330) temp = 1; + else temp = 2; + + if(SiS_Get310DRAMType(SiS_Pr, ROMAddr, HwDeviceExtension) < temp) + SiS_SDRSizing(SiS_Pr, FBAddr); + else + SiS_DDRSizing(SiS_Pr, FBAddr); + + if(HwDeviceExtension->jChipType != SIS_330) { + if(Is315E(SiS_Pr)) { + data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + if((data & 0x0C) == 0x0C) { /* dual channel */ + if((data & 0xF0) > 0x40) + data = (data & 0x0F) | 0x40; + } else { /* single channel */ + if((data & 0xF0) > 0x50) + data = (data & 0x0F) | 0x50; + } + } + } + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType]); /* restore SR16 */ + + SiS_EnableRefresh(SiS_Pr, ROMAddr); + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x21,0x20); /* enable read cache */ +} +#endif + +void +SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR28); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR29); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2A,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR2A); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2E); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2F); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x30,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR30); + +#ifdef SIS315H + if (Is315E(SiS_Pr)) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,0x3B); /* 143 */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,0x22); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,0x3B); /* 143 */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,0x22); + } +#endif +} + +#endif /* ifdef LINUXBIOS */ + +#ifdef SIS315H +UCHAR +SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + UCHAR data, temp; + + if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) { + data = *SiS_Pr->pSiS_SoftSetting & 0x03; + } else { + if((HwDeviceExtension->jChipType > SIS_315PRO) && + (HwDeviceExtension->jChipType < SIS_330)) { + data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07; + } else { /* TW: 315, 330 */ + data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03; + if(HwDeviceExtension->jChipType == SIS_330) { + if(data > 1) { + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0x30; + switch(temp) { + case 0x00: data = 1; break; + case 0x10: data = 3; break; + case 0x20: data = 3; break; + case 0x30: data = 2; break; + } + } else { + data = 0; + } + } + } + } + + return data; +} +#endif + +/* SiSInit END */ + +/* ----------------------------------------- */ + +void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr) +{ + SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; + SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; + SiS_Pr->SiS_P3c0 = BaseAddr + 0x10; + SiS_Pr->SiS_P3ce = BaseAddr + 0x1e; + SiS_Pr->SiS_P3c2 = BaseAddr + 0x12; + SiS_Pr->SiS_P3ca = BaseAddr + 0x1a; + SiS_Pr->SiS_P3c6 = BaseAddr + 0x16; + SiS_Pr->SiS_P3c7 = BaseAddr + 0x17; + SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; + SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; + SiS_Pr->SiS_P3da = BaseAddr + 0x2A; + SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */ + SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */ + SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */ + SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */ + SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */ + SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */ +} + +void +SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ +/* #ifdef LINUX_XF86 */ + if ((HwDeviceExtension->jChipType == SIS_540)|| + (HwDeviceExtension->jChipType == SIS_630)|| + (HwDeviceExtension->jChipType == SIS_730)|| + (HwDeviceExtension->jChipType == SIS_300)) { + /* TW: Set - PCI LINEAR ADDRESSING ENABLE (0x80) + - PCI IO ENABLE (0x20) + - MMIO ENABLE (0x1) + */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1); + /* TW: Enable 2D (0x42) & 3D accelerator (0x18) */ + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A); + } + if((HwDeviceExtension->jChipType == SIS_315H)|| + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO)|| + (HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_330)) { + /* TW: This seems to be done the same way on these chipsets */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1); + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A); + } +/* #endif */ +} + +void +SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo) +{ + ULONG temp; + + SiS_Pr->SiS_IF_DEF_LVDS = 0; + SiS_Pr->SiS_IF_DEF_TRUMPION = 0; + SiS_Pr->SiS_IF_DEF_CH70xx = 0; + SiS_Pr->SiS_IF_DEF_HiVision = 0; + SiS_Pr->SiS_IF_DEF_DSTN = 0; + SiS_Pr->SiS_IF_DEF_FSTN = 0; + + SiS_Pr->SiS_ChrontelInit = 0; + + if((ModeNo == 0x5a) || (ModeNo == 0x5b)) { + SiS_Pr->SiS_IF_DEF_DSTN = 1; /* for 550 dstn */ + SiS_Pr->SiS_IF_DEF_FSTN = 1; /* for fstn */ + } + +#ifdef SIS300 + if((HwDeviceExtension->jChipType == SIS_540) || + (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730)) + { + /* TW: Check for SiS30x first */ + temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00); + if((temp == 1) || (temp == 2)) return; + temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37); + temp = (temp & 0x0E) >> 1; + if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1; + if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1; + if((temp == 4) || (temp == 5)) { + /* TW: Save power status (and error check) - UNUSED */ + SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e); + SiS_Pr->SiS_IF_DEF_CH70xx = 1; + } + } +#endif +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_330)) + { + /* TW: CR37 is different on 310/325 series */ + if(SiS_Pr->SiS_IF_DEF_FSTN) /* fstn: set CR37=0x04 */ + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04); /* (fake LVDS bridge) */ + + temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37); + temp = (temp & 0x0E) >> 1; + if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1; + if(temp == 3) { + SiS_Pr->SiS_IF_DEF_CH70xx = 2; + } + + /* HiVision (HDTV) is done differently now. */ + /* SiS_Pr->SiS_IF_DEF_HiVision = 1; */ + } +#endif +} + +void +SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ +#ifdef SIS315H + if((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO) || + (HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_650) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_330)) + InitTo310Pointer(SiS_Pr, HwDeviceExtension); +#endif + +#ifdef SIS300 + if ((HwDeviceExtension->jChipType == SIS_540) || + (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730) || + (HwDeviceExtension->jChipType == SIS_300)) + InitTo300Pointer(SiS_Pr, HwDeviceExtension); +#endif +} + +void +SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr) +{ + if((ROMAddr) && (HwDeviceExtension->UseROM)) { + if((ROMAddr[0x00] != 0x55) || (ROMAddr[0x01] != 0xAA)) { + SiS_Pr->SiS_UseROM = FALSE; + } else if(HwDeviceExtension->jChipType == SIS_300) { + /* TW: 300: We check if the code starts below 0x220 by + * checking the jmp instruction at the beginning + * of the BIOS image. + */ + if((ROMAddr[3] == 0xe9) && + ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a) + SiS_Pr->SiS_UseROM = TRUE; + else SiS_Pr->SiS_UseROM = FALSE; + } else if(HwDeviceExtension->jChipType < SIS_315H) { + /* TW: Rest of 300 series: We don't use the ROM image if + * the BIOS version < 2.0.0 as such old BIOSes don't + * have the needed data at the expected locations. + */ + if(ROMAddr[0x06] < '2') SiS_Pr->SiS_UseROM = FALSE; + else SiS_Pr->SiS_UseROM = TRUE; + } else { + /* TW: 310/325/330 series stick to the standard */ + SiS_Pr->SiS_UseROM = TRUE; + } + } else SiS_Pr->SiS_UseROM = FALSE; + +} + +/* + ========================================= + ======== SiS SetMode Functions ========== + ========================================= +*/ +#ifdef LINUX_XF86 +/* TW: This is used for non-Dual-Head mode from X */ +BOOLEAN +SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn, + DisplayModePtr mode, BOOLEAN IsCustom) +{ + SISPtr pSiS = SISPTR(pScrn); + UShort ModeNo=0; + + SiS_Pr->UseCustomMode = FALSE; + + if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", + SiS_Pr->CHDisplay, SiS_Pr->CVDisplay); + + return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE)); + + } + + ModeNo = SiS_CalcModeIndex(pScrn, mode); + if(!ModeNo) return FALSE; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo); + + return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE)); +} + +#ifdef SISDUALHEAD +/* TW: Set CRT1 mode (used for dual head) */ +BOOLEAN +SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn, + DisplayModePtr mode, BOOLEAN IsCustom) +{ + ULONG temp; + USHORT ModeIdIndex; + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; + SISPtr pSiS = SISPTR(pScrn); + SISEntPtr pSiSEnt = pSiS->entityPrivate; + unsigned char backupreg=0; + BOOLEAN backupcustom; + + UShort ModeNo=0; + + SiS_Pr->UseCustomMode = FALSE; + + if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Setting custom mode %dx%d in CRT1\n", + SiS_Pr->CHDisplay, SiS_Pr->CVDisplay); + ModeNo = 0xfe; + + } else { + + ModeNo = SiS_CalcModeIndex(pScrn, mode); + if(!ModeNo) return FALSE; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Setting mode 0x%x on CRT1\n", ModeNo); + } + + SiSInitPtr(SiS_Pr, HwDeviceExtension); + + SiSRegInit(SiS_Pr, BaseAddr); + + SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); + + SiSInitPCIetc(SiS_Pr, HwDeviceExtension); + + SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo); + + SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr); + + /* TW: We don't clear the buffer under X */ + SiS_Pr->SiS_flag_clearbuffer = 0; + + /* 1.Openkey */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); + + SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); + + if(!SiS_Pr->UseCustomMode) { + /* 2.Get ModeID Table */ + temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex); + if(temp == 0) return(0); + } else { + ModeIdIndex = 0; + } + + /* TW: Determine VBType (301,301B,301LV,302B,302LV) */ + SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension); + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + } else { + backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35); + } + } + + SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension); + + /* TW: Get VB information (connectors, connected devices) */ + /* (We don't care if the current mode is a CRT2 mode) */ + SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0); + SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) { + /* TW: I am not sure the flag's name is correct */ + if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA; + } + + /* TW: New from 650/LV 1.10.6x */ + if(IS_SIS650740) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); + } + } + } + + /* TW: Set mode on CRT1 */ + SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr); + + pSiSEnt->CRT1ModeNo = ModeNo; + pSiSEnt->CRT1DMode = mode; + + /* TW: SetPitch: Adapt to virtual size & position */ + SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr); + + /* We have to reset CRT2 if changing mode on CRT1 */ + if(pSiSEnt->CRT2ModeNo != -1) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "(Re-)Setting mode 0x%x on CRT2\n", + pSiSEnt->CRT2ModeNo); + backupcustom = SiS_Pr->UseCustomMode; + if(SiS_Pr->UseCustomMode) { + SiS_Pr->CRT1UsesCustomMode = TRUE; + } else { + SiS_Pr->CRT1UsesCustomMode = FALSE; + } + SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1, + pSiSEnt->CRT2DMode); + SiS_Pr->UseCustomMode = backupcustom; + SiS_Pr->CRT1UsesCustomMode = FALSE; + } + + if(IS_SIS650740) { /* TW: *** For 650 only! *** */ + SiS_HandleCRT1(SiS_Pr); + } + + SiS_DisplayOn(SiS_Pr); + SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF); + + /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */ + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg); + } else if((HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730)) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg); + } + } + + /* Backup/Set ModeNo in BIOS scratch area */ + SiS_GetSetModeID(pScrn,ModeNo); + + return TRUE; +} + +/* TW: Set CRT2 mode (used for dual head) */ +BOOLEAN +SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn, + DisplayModePtr mode) +{ + ULONG temp; + USHORT ModeIdIndex; + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; + UShort ModeNo = 0; + SISPtr pSiS = SISPTR(pScrn); + SISEntPtr pSiSEnt = pSiS->entityPrivate; + unsigned char tempr1, tempr2, backupreg=0; + + SiS_Pr->UseCustomMode = FALSE; + + ModeNo = SiS_CalcModeIndex(pScrn, mode); + if(!ModeNo) return FALSE; + + SiSInitPtr(SiS_Pr, HwDeviceExtension); + + SiSRegInit(SiS_Pr, BaseAddr); + + SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); + + SiSInitPCIetc(SiS_Pr, HwDeviceExtension); + + SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo); + + SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr); + + /* TW: We don't clear the buffer under X */ + SiS_Pr->SiS_flag_clearbuffer=0; + + /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */ + pSiSEnt->CRT2ModeNo = ModeNo; + pSiSEnt->CRT2DMode = mode; + + /* TW: We can't set CRT2 mode before CRT1 mode is set */ + if(pSiSEnt->CRT1ModeNo == -1) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Setting CRT2 mode delayed until after setting CRT1 mode\n"); + return TRUE; + } + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Setting mode 0x%x on CRT2\n", ModeNo); + + /* 1.Openkey */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); + + SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); + + /* 2.Get ModeID */ + temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex); + if(temp == 0) return(0); + + /* TW: Determine VBType (301,301B,301LV,302B,302LV) */ + SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension); + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr); + if(HwDeviceExtension->jChipType < SIS_330) { + if(ROMAddr && SiS_Pr->SiS_UseROM) { + temp = ROMAddr[VB310Data_1_2_Offset]; + temp |= 0x40; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp); + } + } + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); + + SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c); + + backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + } else { + backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35); + } + } + + /* TW: Get VB information (connectors, connected devices) */ + SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension); + SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1); + SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) { + /* TW: I am not sure the flag's name is correct */ + if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA; + } + } + + /* Set mode on CRT2 */ + switch (HwDeviceExtension->ujVBChipID) { + case VB_CHIP_301: + case VB_CHIP_301B: + case VB_CHIP_301LV: + case VB_CHIP_301LVX: + case VB_CHIP_302: + case VB_CHIP_302B: + case VB_CHIP_302LV: + case VB_CHIP_302LVX: + SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); + break; + case VB_CHIP_303: + break; + case VB_CHIP_UNKNOWN: + if (SiS_Pr->SiS_IF_DEF_LVDS == 1 || + SiS_Pr->SiS_IF_DEF_CH70xx != 0 || + SiS_Pr->SiS_IF_DEF_TRUMPION != 0) { + SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); + } + break; + } + + SiS_DisplayOn(SiS_Pr); + SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF); + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); + } + } + } + + /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */ + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); + } else { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); + } + + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg); + + tempr1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + tempr2 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00); + if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7; + if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2); + + if(tempr1 & SetCRT2ToLCD) { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); + } + } else if((HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730)) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg); + } + } + + /* TW: SetPitch: Adapt to virtual size & position */ + SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr); + + return TRUE; +} +#endif /* Dualhead */ +#endif /* Linux_XF86 */ + +#ifdef LINUX_XF86 +/* TW: We need pScrn for setting the pitch correctly */ +BOOLEAN +SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch) +#else +BOOLEAN +SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo) +#endif +{ + ULONG temp; + USHORT ModeIdIndex,KeepLockReg; + UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase; + USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; + unsigned char backupreg=0, tempr1, tempr2; + +#ifndef LINUX_XF86 + SiS_Pr->UseCustomMode = FALSE; + SiS_Pr->CRT1UsesCustomMode = FALSE; +#endif + + if(SiS_Pr->UseCustomMode) { + ModeNo = 0xfe; + } + + SiSInitPtr(SiS_Pr, HwDeviceExtension); + + SiSRegInit(SiS_Pr, BaseAddr); + +#ifdef LINUX_XF86 + if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); + else +#endif + SiS_Pr->SiS_VGAINFO = 0x11; + + SiSInitPCIetc(SiS_Pr, HwDeviceExtension); + + SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo); + + SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr); + + if(!SiS_Pr->UseCustomMode) { + /* TW: Shift the clear-buffer-bit away */ + ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f); + } + +#ifdef LINUX_XF86 + /* TW: We never clear the buffer in X */ + ModeNo |= 0x8000; +#endif + + if(ModeNo & 0x8000) { + ModeNo &= 0x7fff; + SiS_Pr->SiS_flag_clearbuffer = 0; + } else { + SiS_Pr->SiS_flag_clearbuffer = 1; + } + + /* 1.Openkey */ + KeepLockReg = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); + + SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); + + if(!SiS_Pr->UseCustomMode) { + + /* 2.Get ModeID Table */ + temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex); + if(temp == 0) return(0); + + } else { + + ModeIdIndex = 0; + + } + + /* TW: Determine VBType (301,301B,301LV,302B,302LV) */ + SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension); + + /* TW: Init/restore some VB registers */ + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr); + if(HwDeviceExtension->jChipType < SIS_330) { + if(ROMAddr && SiS_Pr->SiS_UseROM) { + temp = ROMAddr[VB310Data_1_2_Offset]; + temp |= 0x40; + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp); + } + } + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); + + SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c); + + backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38); + } else { + backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35); + } + } + + /* TW: Get VB information (connectors, connected devices) */ + SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension); + SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1); + SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + + /* 3. Check memory size */ + temp = SiS_CheckMemorySize(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex); + if(!temp) return(0); + + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08) { + /* TW: I am not sure the flag's name is correct */ + if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= CRT2IsVGA; + } + + /* TW: New from 650/LV 1.10.6x */ + if(IS_SIS650740) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); + } + } + } + + /* TW: Set mode on CRT1 */ + if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) { + SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr); + } else { + if(!(SiS_Pr->SiS_VBInfo & SwitchToCRT2)) { + SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr); + } + } + + /* TW: Set mode on CRT2 */ + if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) { + switch (HwDeviceExtension->ujVBChipID) { + case VB_CHIP_301: + case VB_CHIP_301B: + case VB_CHIP_301LV: + case VB_CHIP_301LVX: + case VB_CHIP_302: + case VB_CHIP_302B: + case VB_CHIP_302LV: + case VB_CHIP_302LVX: + SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); + break; + case VB_CHIP_303: + break; + case VB_CHIP_UNKNOWN: + if(SiS_Pr->SiS_IF_DEF_LVDS == 1 || + SiS_Pr->SiS_IF_DEF_CH70xx != 0 || + SiS_Pr->SiS_IF_DEF_TRUMPION != 0) + SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension); + break; + } + } + + if(IS_SIS650740) { /* TW: For 650 only! */ + SiS_HandleCRT1(SiS_Pr); + } + + SiS_DisplayOn(SiS_Pr); + SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF); + + if(HwDeviceExtension->jChipType >= SIS_315H) { +#if 0 + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { + SiS_Handle301B_1400x1050(SiS_Pr, ModeNo); + } + } +#endif + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) { + SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); + } + } + } + + /* TW: New from 650/LV 1.10.6x and 1.10.7w */ + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); + } else { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); + } + + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg); + + tempr1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30); + tempr2 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00); + if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7; + if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB; + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2); + + if((IS_SIS650740) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) { + if((ModeNo == 0x03) || (ModeNo == 0x10)) { + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80); + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08); + } + } + + if(tempr1 & SetCRT2ToLCD) { +/* if(ModeNo <= 0x13) { - not in 1.10.8r */ + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); +/* } */ + } + } else if((HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730)) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg); + } + } + +#ifdef LINUX_XF86 + if(pScrn) { + /* TW: SetPitch: Adapt to virtual size & position */ + if((ModeNo > 0x13) && (dosetpitch)) { + SiS_SetPitch(SiS_Pr, pScrn, BaseAddr); + } + + /* Backup/Set ModeNo in BIOS scratch area */ + SiS_GetSetModeID(pScrn, ModeNo); + } +#endif + +#ifndef LINUX_XF86 /* TW: We never lock registers in XF86 */ + if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86); + else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00); +#endif + + return TRUE; +} + +void +SiS_SetEnableDstn(SiS_Private *SiS_Pr) /* TW: Called from sis_main.c */ +{ + /* For 550 dstn */ + SiS_Pr->SiS_IF_DEF_DSTN = 1; +} + +void +SiS_HandleCRT1(SiS_Private *SiS_Pr) +{ + /* TW: Do this on 650 only! */ + + /* TW: No, we don't do this at all. There is a new + * CRT1-is-connected-at-boot-time logic in the 650, which + * confuses our own. So just clear the bit and skip the rest. + */ + + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf); + +#if 0 + if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01)) + SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40); + } +#endif +} + +#if 0 +void +SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo) +{ + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { + if(ModeNo <= 0x13) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (SetNotSimuMode >> 8)) { + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xFC); + } + } + } +} +#endif + +void +SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr) +{ + USHORT StandTableIndex,RefreshRateTableIndex; + + SiS_Pr->SiS_CRT1Mode = ModeNo; + StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex); + if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { + if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2)) { + SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr); + } + } + + SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex); + SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex); + SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex); + SiS_SetATTRegs(SiS_Pr,ROMAddr,StandTableIndex,HwDeviceExtension); + SiS_SetGRCRegs(SiS_Pr,ROMAddr,StandTableIndex); + SiS_ClearExt1Regs(SiS_Pr,HwDeviceExtension); + SiS_ResetCRT1VCLK(SiS_Pr,ROMAddr,HwDeviceExtension); + + SiS_Pr->SiS_SelectCRT2Rate = 0; + SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); + +#ifdef LINUX_XF86 + xf86DrvMsgVerb(0, X_PROBED, 3, "(init: VBType=0x%04x, VBInfo=0x%04x)\n", + SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo); +#endif + + if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; + } + } + + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; + } + + RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + + if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2; + } + + if(RefreshRateTableIndex != 0xFFFF) { + SiS_SetSync(SiS_Pr,ROMAddr,RefreshRateTableIndex); + SiS_SetCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension); + SiS_SetCRT1Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension); + SiS_SetCRT1VCLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex); + } + +#ifdef SIS300 + if(HwDeviceExtension->jChipType == SIS_300) { + SiS_SetCRT1FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex); + } + if((HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730) || + (HwDeviceExtension->jChipType == SIS_540)) { + SiS_SetCRT1FIFO_630(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex); + } +#endif +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetCRT1FIFO_310(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); + } +#endif + + SiS_SetCRT1ModeRegs(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex); + + SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex); + +#ifndef LINUX_XF86 + if(SiS_Pr->SiS_flag_clearbuffer) { + SiS_ClearBuffer(SiS_Pr,HwDeviceExtension,ModeNo); + } +#endif + + if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) { + SiS_LongWait(SiS_Pr); + SiS_DisplayOn(SiS_Pr); + } +} + +#ifdef LINUX_XF86 +void +SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr) +{ + SISPtr pSiS = SISPTR(pScrn); + + /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */ + if( (pSiS->VBFlags & DISPTYPE_DISP1) || + ( (pSiS->VBFlags & VB_VIDEOBRIDGE) && + ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) || + ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) { + SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr); + } + if (pSiS->VBFlags & DISPTYPE_DISP2) { + SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr); + } +} + +void +SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr) +{ + SISPtr pSiS = SISPTR(pScrn); + ULong HDisplay,temp; + + HDisplay = pSiS->scrnPitch / 8; + SiS_SetReg1(SiS_Pr->SiS_P3d4, 0x13, (HDisplay & 0xFF)); + temp = (SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8); + SiS_SetReg1(SiS_Pr->SiS_P3c4, 0x0E, temp); +} + +void +SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr) +{ + SISPtr pSiS = SISPTR(pScrn); + ULong HDisplay,temp; + + HDisplay = pSiS->scrnPitch / 8; + + /* Unlock CRT2 */ + if (pSiS->VGAEngine == SIS_315_VGA) + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01); + else + SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01); + + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07, (HDisplay & 0xFF)); + temp = (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF); + SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09, temp); +} +#endif + +/* TW: Checked against 650/301 and 630/301B BIOS */ +/* TW: Re-written for 650/301LVx 1.10.6s BIOS */ +void +SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT flag=0, rev=0, nolcd=0; + + SiS_Pr->SiS_VBType = 0; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return; + + flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00); + + /* TW: Illegal values not welcome... */ + if(flag > 10) return; + + rev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01); + + if (flag >= 2) { + SiS_Pr->SiS_VBType = VB_SIS302B; + } else if (flag == 1) { + SiS_Pr->SiS_VBType = VB_SIS301; + if(rev >= 0xB0) { + SiS_Pr->SiS_VBType = VB_SIS301B; + if((HwDeviceExtension->jChipType >= SIS_315H) || + (HwDeviceExtension->jChipType == SIS_300)) { + /* 650/301LV and 300/301LV use this, 630/301B does not */ + nolcd = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x23); + if(!(nolcd & 0x02)) + SiS_Pr->SiS_VBType |= VB_NoLCD; + } + } + } + if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) { + if(rev >= 0xD0) { + SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS302B); + SiS_Pr->SiS_VBType |= VB_SIS30xLV; + SiS_Pr->SiS_VBType &= ~(VB_NoLCD); + if(rev >= 0xE0) { + SiS_Pr->SiS_VBType &= ~(VB_SIS30xLV); + SiS_Pr->SiS_VBType |= VB_SIS30xNEW; + } + } + } +} + +/* TW: Checked against 650/301LVx 1.10.6s */ +BOOLEAN +SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex) +{ + UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO; + + if(*ModeNo <= 0x13) { + + if((*ModeNo) <= 5) (*ModeNo) |= 1; + + for(*ModeIdIndex=0;;(*ModeIdIndex)++) { + if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break; + if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF) return FALSE; + } + + if(*ModeNo == 0x07) { + if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ + /* else 350 lines */ + } + if(*ModeNo <= 3) { + if(!(VGAINFO & 0x80)) (*ModeIdIndex)++; + if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ + /* else 350 lines */ + } + /* else 200 lines */ + + } else { + + for(*ModeIdIndex=0;;(*ModeIdIndex)++) { + if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break; + if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return FALSE; + } + + } + return TRUE; +} + +/* For SiS 300 oem util: Search VBModeID */ +BOOLEAN +SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo) +{ + USHORT ModeIdIndex; + UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO; + + if(*ModeNo <= 5) *ModeNo |= 1; + + for(ModeIdIndex=0; ; ModeIdIndex++) { + if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break; + if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return FALSE; + } + + if(*ModeNo != 0x07) { + if(*ModeNo > 0x03) return ((BOOLEAN)ModeIdIndex); + if(VGAINFO & 0x80) return ((BOOLEAN)ModeIdIndex); + ModeIdIndex++; + } + if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */ + /* else 350 lines */ + return ((BOOLEAN)ModeIdIndex); +} + +/* TW: Checked against 630/301B, 315 1.09 and 650/301LVx 1.10.6s BIOS */ +BOOLEAN +SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT memorysize,modeflag; + ULONG temp; + + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + } else { + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + } + + memorysize = modeflag & MemoryInfoFlag; + memorysize >>= MemorySizeShift; /* Get required memory size */ + memorysize++; + + temp = GetDRAMSize(SiS_Pr, HwDeviceExtension); /* Get adapter memory size */ + temp /= (1024*1024); /* (in MB) */ + + if(temp < memorysize) return(FALSE); + else return(TRUE); +} + +UCHAR +SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + UCHAR index; + + if(ModeNo <= 0x13) { + index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex; + } else { + if(SiS_Pr->SiS_ModeType <= 0x02) index = 0x1B; /* 02 -> ModeEGA */ + else index = 0x0F; + } + return index; +} + +/* TW: Checked against 300, 330, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */ +void +SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) +{ + UCHAR SRdata; + USHORT i; + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x00,0x03); /* Set SR0 */ + + SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0]; + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + SRdata |= 0x01; + } + } + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + SRdata |= 0x01; /* 8 dot clock */ + } + } + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + SRdata |= 0x01; /* 8 dot clock */ + } + } + } + + SRdata |= 0x20; /* screen off */ + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x01,SRdata); + + for(i = 2; i <= 4; i++) { + SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1]; + SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SRdata); + } +} + +/* Checked against 300, 650/301LVx 1.10.6s and 650/LVDS 1.10.07 BIOS */ +void +SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) +{ + UCHAR Miscdata; + + Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC; + + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { + Miscdata |= 0x0C; + } + } + + SiS_SetReg3(SiS_Pr->SiS_P3c2,Miscdata); +} + +/* Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS (630 code still there!) */ +void +SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT StandTableIndex) +{ + UCHAR CRTCdata; + USHORT i; + + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /* Unlock CRTC */ + + for(i = 0; i <= 0x18; i++) { + CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,CRTCdata); /* Set CRTC(3d4) */ + } + if( ( (HwDeviceExtension->jChipType == SIS_630) || + (HwDeviceExtension->jChipType == SIS_730) ) && + (HwDeviceExtension->jChipRevision >= 0x30) ) { /* for 630S0 */ + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE); + } + } + } +} + +/* TW: Checked against 300, 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 630/301B BIOS */ +void +SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + UCHAR ARdata; + USHORT i; + + for(i = 0; i <= 0x13; i++) { + ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; +#if 0 + if((i <= 0x0f) || (i == 0x11)) { + if(ds:489 & 0x08) { + continue; + } + } +#endif + if(i == 0x13) { + if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata=0; + } + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { + if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; + } + } + } + if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { + if(HwDeviceExtension->jChipType >= SIS_315H) { + /* TW: From 650/LVDS 1.10.07, 1.10a; 650/301LVx 1.10.6s; not in 330 BIOS */ + ARdata = 0; + } else { + if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { + ARdata=0; + } + } + } + } + SiS_GetReg2(SiS_Pr->SiS_P3da); /* reset 3da */ + SiS_SetReg3(SiS_Pr->SiS_P3c0,i); /* set index */ + SiS_SetReg3(SiS_Pr->SiS_P3c0,ARdata); /* set data */ + } + SiS_GetReg2(SiS_Pr->SiS_P3da); /* reset 3da */ + SiS_SetReg3(SiS_Pr->SiS_P3c0,0x14); /* set index */ + SiS_SetReg3(SiS_Pr->SiS_P3c0,0x00); /* set data */ + + SiS_GetReg2(SiS_Pr->SiS_P3da); + SiS_SetReg3(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */ + SiS_GetReg2(SiS_Pr->SiS_P3da); +} + +/* TW: Checked against 300, 330, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */ +void +SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex) +{ + UCHAR GRdata; + USHORT i; + + for(i = 0; i <= 0x08; i++) { + GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; + SiS_SetReg1(SiS_Pr->SiS_P3ce,i,GRdata); /* Set GR(3ce) */ + } + + if(SiS_Pr->SiS_ModeType > ModeVGA) { + SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF); /* 256 color disable */ + } +} + +/* TW: Checked against 650/LVDS (1.10.07, 1.10a), 650/301LVx (1.10.6s) and 630/301B BIOS */ +void +SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT i; + + for(i = 0x0A; i <= 0x0E; i++) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0x00); /* Clear SR0A-SR0E */ + } + + /* TW: New from 330, 650/LVDS/301LV BIOSes: */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE); + } +} + +/* TW: Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LV BIOS */ +void +SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex) +{ + USHORT sync; + USHORT temp; + + if(SiS_Pr->UseCustomMode) { + sync = SiS_Pr->CInfoFlag >> 8; + } else { + sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; + } + + sync &= 0xC0; + temp = 0x2F | sync; + SiS_SetReg3(SiS_Pr->SiS_P3c2,temp); /* Set Misc(3c2) */ +} + +/* TW: Checked against 300, 330, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS */ +void +SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + UCHAR index; + USHORT tempah,i,modeflag,j; +#ifdef SIS315H + USHORT temp; + USHORT ResInfo,DisplayType; + const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL; +#endif + + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /*unlock cr0-7 */ + + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + } else { + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + } + + if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { + +#ifdef SIS315H + + /* LCDA */ + + temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,&ResInfo,&DisplayType); + + switch(DisplayType) { + case Panel_800x600 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1; break; + case Panel_1024x768 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break; + case Panel_1280x1024 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1; break; + case Panel_1400x1050 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1; break; + case Panel_1600x1200 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1; break; + case Panel_800x600 + 16 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1_H; break; + case Panel_1024x768 + 16 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H; break; + case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H; break; + case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H; break; + case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H; break; + case Panel_800x600 + 32 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2; break; + case Panel_1024x768 + 32 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2; break; + case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2; break; + case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2; break; + case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2; break; + case Panel_800x600 + 48 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2_H; break; + case Panel_1024x768 + 48 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H; break; + case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H; break; + case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H; break; + case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H; break; + default: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break; + } + + tempah = (LCDACRT1Ptr+ResInfo)->CR[0]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah); + for(i=0x01,j=1;i<=0x07;i++,j++){ + tempah = (LCDACRT1Ptr+ResInfo)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); + } + for(i=0x10,j=8;i<=0x12;i++,j++){ + tempah = (LCDACRT1Ptr+ResInfo)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); + } + for(i=0x15,j=11;i<=0x16;i++,j++){ + tempah =(LCDACRT1Ptr+ResInfo)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah); + } + for(i=0x0A,j=13;i<=0x0C;i++,j++){ + tempah = (LCDACRT1Ptr+ResInfo)->CR[j]; + SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah); + } + + tempah = (LCDACRT1Ptr+ResInfo)->CR[16]; + tempah &= 0x0E0; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah); + + tempah = (LCDACRT1Ptr+ResInfo)->CR[16]; + tempah &= 0x01; + tempah <<= 5; + if(modeflag & DoubleScanMode) tempah |= 0x080; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah); + +#endif + + } else { + + /* LVDS, 301, 301B, 301LV, 302LV, ... (non-LCDA) */ + + if(SiS_Pr->UseCustomMode) { + + for(i=0,j=0;i<=07;i++,j++) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); + } + for(j=0x10;i<=10;i++,j++) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); + } + for(j=0x15;i<=12;i++,j++) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); + } + for(j=0x0A;i<=15;i++,j++) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]); + } + + tempah = SiS_Pr->CCRT1CRTC[16] & 0xE0; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah); + + tempah = SiS_Pr->CCRT1CRTC[16]; + tempah &= 0x01; + tempah <<= 5; + if(modeflag & DoubleScanMode) tempah |= 0x80; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah); + + + } else { + + index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */ +#if 0 /* Not any longer... */ + if(HwDeviceExtension->jChipType < SIS_315H) { + index &= 0x3F; + } +#endif + + for(i=0,j=0;i<=07;i++,j++) { + tempah=SiS_Pr->SiS_CRT1Table[index].CR[i]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah); + } + for(j=0x10;i<=10;i++,j++) { + tempah=SiS_Pr->SiS_CRT1Table[index].CR[i]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah); + } + for(j=0x15;i<=12;i++,j++) { + tempah=SiS_Pr->SiS_CRT1Table[index].CR[i]; + SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah); + } + for(j=0x0A;i<=15;i++,j++) { + tempah=SiS_Pr->SiS_CRT1Table[index].CR[i]; + SiS_SetReg1(SiS_Pr->SiS_P3c4,j,tempah); + } + + tempah = SiS_Pr->SiS_CRT1Table[index].CR[16]; + tempah &= 0xE0; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah); + + tempah = SiS_Pr->SiS_CRT1Table[index].CR[16]; + tempah &= 0x01; + tempah <<= 5; + if(modeflag & DoubleScanMode) tempah |= 0x80; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah); + + } + } + + if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg1(SiS_Pr->SiS_P3d4,0x14,0x4F); +} + +BOOLEAN +SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *ResInfo, + USHORT *DisplayType) + { + USHORT tempbx=0,modeflag=0; + USHORT CRT2CRTC=0; + + if(ModeNo <= 0x13) { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + } + + tempbx = SiS_Pr->SiS_LCDResInfo; + + if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 32; + if(modeflag & HalfDCLK) tempbx += 16; + + *ResInfo = CRT2CRTC & 0x3F; + *DisplayType = tempbx; + + return 1; +} + +/* TW: Set offset and pitch - partly overruled by SetPitch() in XF86 */ +/* TW: Checked against 330, 650/LVDS (1.10.07), 650/301LV and 315 BIOS */ +void +SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp, DisplayUnit, infoflag; + + if(SiS_Pr->UseCustomMode) { + infoflag = SiS_Pr->CInfoFlag; + } else { + infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + } + + DisplayUnit = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + + temp = (DisplayUnit >> 8) & 0x0f; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp); + + temp = DisplayUnit & 0xFF; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x13,temp); + + if(infoflag & InterlaceMode) DisplayUnit >>= 1; + + DisplayUnit <<= 5; + temp = (DisplayUnit & 0xff00) >> 8; + if (DisplayUnit & 0xff) temp++; + temp++; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x10,temp); +} + +/* TW: New from 650/LVDS 1.10.07, 630/301B and 630/LVDS BIOS */ +void +SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT index; + + /* TW: We only need to do this if Panel Link is to be + * initialized, thus on 630/LVDS/301B, and 650/LVDS + */ + if(HwDeviceExtension->jChipType >= SIS_315H) { + if (SiS_Pr->SiS_IF_DEF_LVDS == 0) return; + } else { + if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && + (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) { + return; + } + } + + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20); + } + index = 1; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80); + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10); + } + index = 0; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80); +} + +/* TW: Checked against 300, 330, 650/LVDS, 650/301LVx, 315, 630/301B, 630/LVDS BIOS */ +void +SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT RefreshRateTableIndex) +{ + USHORT index=0; + + if(!SiS_Pr->UseCustomMode) { + index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + } + + if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) + && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){ + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF); + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VBVCLKData[index].Part4_A); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VBVCLKData[index].Part4_B); + + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80); + } + + } else { + + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00); + } + + if(SiS_Pr->UseCustomMode) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->CSR2B); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->CSR2C); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B); + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C); + } + + if(HwDeviceExtension->jChipType >= SIS_315H) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80); + } + } +} + +#if 0 /* TW: Not used */ +void +SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT ModeFlag; + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0x7F); + + if(ModeNo > 0x13) { + ModeFlag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) { + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x80); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xF7); + } + } +} +#endif + +/* TW: Checked against 300, 630/LVDS, 650/LVDS, 315 and 330 BIOS */ +void +SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex) +{ + USHORT data,data2,data3; + USHORT infoflag=0,modeflag; + USHORT resindex,xres; + + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + infoflag = SiS_Pr->CInfoFlag; + } else { + if(ModeNo > 0x13) { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + } else { + modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } + } + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F); /* DAC pedestal */ + + if(ModeNo > 0x13) data = infoflag; + else data = 0; + + data2 = 0; + if(ModeNo > 0x13) { + if(SiS_Pr->SiS_ModeType > 0x02) { + data2 |= 0x02; + data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2; + data2 |= data3; + } + } +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n", + data, HwDeviceExtension->jChipType); +#endif + if(data & InterlaceMode) data2 |= 0x20; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data2); + + if(SiS_Pr->UseCustomMode) { + xres = SiS_Pr->CHDisplay; + } else { + resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex); + if(ModeNo <= 0x13) { + xres = SiS_Pr->SiS_StResInfo[resindex].HTotal; + } else { + xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal; + } + } + + if(HwDeviceExtension->jChipType != SIS_300) { + data = 0x0000; + if(infoflag & InterlaceMode) { + if(xres == 1024) data = 0x0035; + else data = 0x0048; + } + data2 = data & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data2); + data2 = (data & 0xFF00) >> 8; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,data2); + } + + if(modeflag & HalfDCLK) { + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08); + } + + if(HwDeviceExtension->jChipType == SIS_300) { + if(modeflag & LineCompareOff) { + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x08); + } else { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xF7); + } + } else if(HwDeviceExtension->jChipType < SIS_315H) { + if(modeflag & LineCompareOff) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08); + } else { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7); + } + /* 630 BIOS does something for mode 0x12 here */ + } else { + if(modeflag & LineCompareOff) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08); + } else { + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7); + } + } + + if(HwDeviceExtension->jChipType != SIS_300) { + if(SiS_Pr->SiS_ModeType == ModeEGA) { + if(ModeNo > 0x13) { + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40); + } + } + } + +#ifdef SIS315H + /* TW: 315 BIOS sets SR17 at this point */ + if(HwDeviceExtension->jChipType == SIS_315PRO) { + data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension); + data = SiS_Pr->SiS_SR15[2][data]; + if(SiS_Pr->SiS_ModeType == ModeText) { + data &= 0xc7; + } else { + data2 = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + data2 >>= 1; + if(infoflag & InterlaceMode) data2 >>= 1; + data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex); + data3 >>= 1; + if(data3 == 0) data3++; + data2 /= data3; + if(data2 >= 0x50) { + data &= 0x0f; + data |= 0x50; + } + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data); + } + + /* TW: 330 BIOS sets SR17 at this point */ + if(HwDeviceExtension->jChipType == SIS_330) { + data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension); + data = SiS_Pr->SiS_SR15[2][data]; + if(SiS_Pr->SiS_ModeType <= ModeEGA) { + data &= 0xc7; + } else { + if(SiS_Pr->UseCustomMode) { + data2 = SiS_Pr->CSRClock; + } else { + data2 = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK; + } + + data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex); + data3 >>= 1; + + data2 *= data3; + + data3 = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension); + data3 *= 1024; + + data2 = data3 / data2; + + if(SiS_Pr->SiS_ModeType != Mode16Bpp) { + if(data2 >= 0x19c) data = 0xba; + else if(data2 >= 0x140) data = 0x7a; + else if(data2 >= 0x101) data = 0x3a; + else if(data2 >= 0xf5) data = 0x32; + else if(data2 >= 0xe2) data = 0x2a; + else if(data2 >= 0xc4) data = 0x22; + else if(data2 >= 0xac) data = 0x1a; + else if(data2 >= 0x9e) data = 0x12; + else if(data2 >= 0x8e) data = 0x0a; + else data = 0x02; + } else { + if(data2 >= 0x127) data = 0xba; + else data = 0x7a; + } + } + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data); + } +#endif + + data = 0x60; + if(SiS_Pr->SiS_ModeType != ModeText) { + data ^= 0x60; + if(SiS_Pr->SiS_ModeType != ModeEGA) { + data ^= 0xA0; + } + } + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data); + + SiS_SetVCLKState(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex); + +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x2c); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x6c); + } + } +#endif +} + +/* TW: Checked against 300, 315, 330, 650/LVDS, 650/301LVx, 630/301B and 630/LVDS BIOS */ +void +SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeNo,USHORT RefreshRateTableIndex, + USHORT ModeIdIndex) +{ + USHORT data, data2=0; + USHORT VCLK, index=0; + + if (ModeNo <= 0x13) VCLK = 0; + else { + if(SiS_Pr->UseCustomMode) { + VCLK = SiS_Pr->CSRClock; + } else { + index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, + RefreshRateTableIndex,HwDeviceExtension); + VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; + } + } + + if(HwDeviceExtension->jChipType < SIS_315H) { /* 300 series */ + + data2 = 0x00; + if(VCLK > 150) data2 |= 0x80; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2); /* DAC speed */ + + data2 = 0x00; + if(VCLK >= 150) data2 |= 0x08; /* VCLK > 150 */ + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2); + + } else { /* 310/325 series */ + + data = 0; + if(VCLK >= 166) data |= 0x0c; /* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */ + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); + + if(VCLK >= 166) { /* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */ + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7); + } +#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */ + data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F); /* DAC pedestal */ + data &= 0xE7; + if(VCLK<200) data |= 0x10; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data); /* DAC pedestal */ +#endif + } + + data2 = 0x03; + if((VCLK >= 135) && (VCLK < 160)) data2 = 0x02; + if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01; + if(VCLK >= 260) data2 = 0x00; + + if(HwDeviceExtension->jChipType == SIS_540) { + if((VCLK == 203) || (VCLK < 234)) data2 = 0x02; + } + + if(HwDeviceExtension->jChipType < SIS_315H) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2); /* DAC speed */ + } else { + if(HwDeviceExtension->jChipType > SIS_315PRO) { + /* TW: This "if" is done in 330 and 650/LVDS/301LV BIOSes; Not in 315 BIOS */ + if(ModeNo > 0x13) data2 &= 0xfc; + } + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2); /* DAC speed */ + } +} + +/* TW: Checked against 650/301LVx 1.10.6s, 315, 630/301B BIOS */ +void +SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex) +{ + USHORT data,data2; + USHORT time,i,j,k; + USHORT m,n,o; + USHORT si,di,bx,dl; + USHORT al,ah,dh; + USHORT DACAddr, DACData, shiftflag; + const USHORT *table = NULL; +#if 0 + USHORT tempah,tempch,tempcl,tempdh,tempal,tempbx; +#endif + + if(ModeNo <= 0x13) { + data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + if(SiS_Pr->UseCustomMode) { + data = SiS_Pr->CModeFlag; + } else { + data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + } + +#if 0 + if(!(ds:489 & 0x08)) { +#endif + + data &= DACInfoFlag; + time = 64; + if(data == 0x00) table = SiS_MDA_DAC; + if(data == 0x08) table = SiS_CGA_DAC; + if(data == 0x10) table = SiS_EGA_DAC; + if(data == 0x18) { + time = 256; + table = SiS_VGA_DAC; + } + if(time == 256) j = 16; + else j = time; + + if( ( (HwDeviceExtension->jChipType == SIS_630) && /* 630/301B LCD */ + (SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) && + (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) || + (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */ + (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */ + DACAddr = SiS_Pr->SiS_P3c8; + DACData = SiS_Pr->SiS_P3c9; + shiftflag = 0; + SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF); + } else { + shiftflag = 1; + DACAddr = SiS_Pr->SiS_Part5Port; + DACData = SiS_Pr->SiS_Part5Port + 1; + } + + SiS_SetReg3(DACAddr,0x00); + + for(i=0; i<j; i++) { + data = table[i]; + for(k=0; k<3; k++) { + data2 = 0; + if(data & 0x01) data2 = 0x2A; + if(data & 0x02) data2 += 0x15; + if(shiftflag) data2 <<= 2; + SiS_SetReg3(DACData,data2); + data >>= 2; + } + } + + if(time == 256) { + for(i = 16; i < 32; i++) { + data = table[i]; + if(shiftflag) data <<= 2; + for(k=0; k<3; k++) SiS_SetReg3(DACData,data); + } + si = 32; + for(m = 0; m < 9; m++) { + di = si; + bx = si + 4; + dl = 0; + for(n = 0; n < 3; n++) { + for(o = 0; o < 5; o++) { + dh = table[si]; + ah = table[di]; + al = table[bx]; + si++; + SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh); + } + si -= 2; + for(o = 0; o < 3; o++) { + dh = table[bx]; + ah = table[di]; + al = table[si]; + si--; + SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh); + } + dl++; + } /* for n < 3 */ + si += 5; + } /* for m < 9 */ + } +#if 0 + } /* ds:489 & 0x08 */ +#endif + +#if 0 + if((!(ds:489 & 0x08)) && (ds:489 & 0x06)) { + tempbx = 0; + for(i=0; i< 256; i++) { + SiS_SetReg3(SiS_Pr->SiS_P3c8-1,tempbx); /* 7f87 */ + tempah = SiS_GetReg3(SiS_Pr->SiS_P3c8+1); /* 7f83 */ + tempch = SiS_GetReg3(SiS_Pr->SiS_P3c8+1); + tempcl = SiS_GetReg3(SiS_Pr->SiS_P3c8+1); + tempdh = tempah; + tempal = 0x4d * tempdh; /* 7fb8 */ + tempbx += tempal; + tempal = 0x97 * tempch; + tempbx += tempal; + tempal = 0x1c * tempcl; + tempbx += tempal; + if((tempbx & 0x00ff) > 0x80) tempbx += 0x100; + tempdh = (tempbx & 0x00ff) >> 8; + tempch = tempdh; + tempcl = tempdh; + SiS_SetReg3(SiS_Pr->SiS_P3c8,(tempbx & 0xff)); /* 7f7c */ + SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempdh); /* 7f92 */ + SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempch); + SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempcl); + } + } +#endif +} + +void +SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT DACData, USHORT shiftflag, + USHORT dl, USHORT ah, USHORT al, USHORT dh) +{ + USHORT temp; + USHORT bh,bl; + + bh = ah; + bl = al; + if(dl != 0) { + temp = bh; + bh = dh; + dh = temp; + if(dl == 1) { + temp = bl; + bl = dh; + dh = temp; + } else { + temp = bl; + bl = bh; + bh = temp; + } + } + if(shiftflag) { + dh <<= 2; + bh <<= 2; + bl <<= 2; + } + SiS_SetReg3(DACData,(USHORT)dh); + SiS_SetReg3(DACData,(USHORT)bh); + SiS_SetReg3(DACData,(USHORT)bl); +} + +static ULONG +GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + ULONG AdapterMemorySize = 0; +#ifdef SIS315H + USHORT counter; +#endif + +#ifdef SIS315H + if ((HwDeviceExtension->jChipType == SIS_315H) || + (HwDeviceExtension->jChipType == SIS_315) || + (HwDeviceExtension->jChipType == SIS_315PRO)) { + + counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + AdapterMemorySize = 1 << ((counter & 0xF0) >> 4); + counter >>= 2; + counter &= 0x03; + if(counter == 0x02) { + AdapterMemorySize += (AdapterMemorySize / 2); /* DDR asymetric */ + } else if(counter != 0) { + AdapterMemorySize <<= 1; /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */ + } + AdapterMemorySize *= (1024*1024); + + } else if(HwDeviceExtension->jChipType == SIS_330) { + + counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + AdapterMemorySize = 1 << ((counter & 0xF0) >> 4); + counter &= 0x0c; + if(counter != 0) { + AdapterMemorySize <<= 1; + } + AdapterMemorySize *= (1024*1024); + + } else if((HwDeviceExtension->jChipType == SIS_550) || + (HwDeviceExtension->jChipType == SIS_740) || + (HwDeviceExtension->jChipType == SIS_650)) { + + counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F; + counter++; + AdapterMemorySize = counter * 4; + AdapterMemorySize *= (1024*1024); + } +#endif + +#ifdef SIS300 + if ((HwDeviceExtension->jChipType==SIS_300) || + (HwDeviceExtension->jChipType==SIS_540) || + (HwDeviceExtension->jChipType==SIS_630) || + (HwDeviceExtension->jChipType==SIS_730)) { + + AdapterMemorySize = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F; + AdapterMemorySize++; + AdapterMemorySize *= (1024*1024); + + } +#endif + + return AdapterMemorySize; +} + +#ifndef LINUX_XF86 +void +SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo) +{ + PVOID VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress; + ULONG AdapterMemorySize = (ULONG)HwDeviceExtension->ulVideoMemorySize; + PUSHORT pBuffer; + int i; + + if (SiS_Pr->SiS_ModeType>=ModeEGA) { + if(ModeNo > 0x13) { + AdapterMemorySize = GetDRAMSize(SiS_Pr, HwDeviceExtension); + SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0); + } else { + pBuffer = VideoMemoryAddress; + for(i=0; i<0x4000; i++) + pBuffer[i] = 0x0000; + } + } else { + pBuffer = VideoMemoryAddress; + if (SiS_Pr->SiS_ModeType < ModeCGA) { + for(i=0; i<0x4000; i++) + pBuffer[i] = 0x0720; + } else { + SiS_SetMemory(VideoMemoryAddress,0x8000,0); + } + } +} +#endif + +void +SiS_DisplayOn(SiS_Private *SiS_Pr) +{ + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00); +} + +void +SiS_DisplayOff(SiS_Private *SiS_Pr) +{ + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20); +} + + +/* ========================================== */ +/* SR CRTC GR */ +void +SiS_SetReg1(USHORT port, USHORT index, USHORT data) +{ + OutPortByte(port,index); + OutPortByte(port+1,data); +} + +/* ========================================== */ +/* AR(3C0) */ +void +SiS_SetReg2(SiS_Private *SiS_Pr, USHORT port, USHORT index, USHORT data) +{ + InPortByte(port+0x3da-0x3c0); + OutPortByte(SiS_Pr->SiS_P3c0,index); + OutPortByte(SiS_Pr->SiS_P3c0,data); + OutPortByte(SiS_Pr->SiS_P3c0,0x20); +} + +void +SiS_SetReg3(USHORT port, USHORT data) +{ + OutPortByte(port,data); +} + +void +SiS_SetReg4(USHORT port, ULONG data) +{ + OutPortLong(port,data); +} + +void +SiS_SetReg5(USHORT port, USHORT data) +{ + OutPortWord(port,data); +} + +UCHAR SiS_GetReg1(USHORT port, USHORT index) +{ + UCHAR data; + + OutPortByte(port,index); + data = InPortByte(port+1); + + return(data); +} + +UCHAR +SiS_GetReg2(USHORT port) +{ + UCHAR data; + + data= InPortByte(port); + + return(data); +} + +ULONG +SiS_GetReg3(USHORT port) +{ + ULONG data; + + data = InPortLong(port); + + return(data); +} + +USHORT +SiS_GetReg4(USHORT port) +{ + ULONG data; + + data = InPortWord(port); + + return(data); +} + +void +SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port) +{ + int i; + + OutPortByte(port, 0); + port++; + for (i=0; i < (256 * 3); i++) { + OutPortByte(port, 0); + } + +} + +#if 0 /* TW: Unused */ +void +SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex) +{ + ULONG Temp; + USHORT data,Temp2; + + if (ModeNo<=0x13) return; + + Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x01); + Temp++; + Temp <<= 3; + + if(Temp == 1024) data = 0x0035; + else if(Temp == 1280) data = 0x0048; + else data = 0x0000; + + Temp2 = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + Temp2 &= InterlaceMode; + if(Temp2 == 0) data=0x0000; + + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data); + + Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x1A); + Temp = (USHORT)(Temp & 0xFC); + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp); + + Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x0f); + Temp2 = (USHORT)Temp & 0xBF; + if(ModeNo==0x37) Temp2 |= 0x40; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp2); +} +#endif + +/* TW: Checked against 330, 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 315 BIOS */ +#ifdef SIS315H +void +SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT modeflag; + + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE); /* disable auto-threshold */ + + if(ModeNo > 0x13) { + if(SiS_Pr->UseCustomMode) { + modeflag = SiS_Pr->CModeFlag; + } else { + modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0x34); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0); + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0); + } + } else { + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE); + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0); + } +} +#endif + +#ifdef SIS300 +void +SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT RefreshRateTableIndex) +{ + USHORT ThresholdLow = 0; + USHORT index, VCLK, MCLK, colorth=0; + USHORT tempah, temp; + + if(ModeNo > 0x13) { + + if(SiS_Pr->UseCustomMode) { + VCLK = SiS_Pr->CSRClock; + } else { + index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + index &= 0x3F; + VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */ + } + + switch (SiS_Pr->SiS_ModeType - ModeEGA) { /* Get half colordepth */ + case 0 : colorth = 1; break; + case 1 : colorth = 1; break; + case 2 : colorth = 2; break; + case 3 : colorth = 2; break; + case 4 : colorth = 3; break; + case 5 : colorth = 4; break; + } + + index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A); + index &= 0x07; + MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */ + + tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35); + tempah &= 0xc3; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah); + + do { + ThresholdLow = SiS_CalcDelay(SiS_Pr, ROMAddr, VCLK, colorth, MCLK); + ThresholdLow++; + if(ThresholdLow < 0x13) break; + SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc); + ThresholdLow = 0x13; + tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + tempah >>= 6; + if(!(tempah)) break; + tempah--; + tempah <<= 6; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah); + } while(0); + + } else ThresholdLow = 2; + + /* Write CRT/CPU threshold low, CRT/Engine threshold high */ + temp = (ThresholdLow << 4) | 0x0f; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,temp); + + temp = (ThresholdLow & 0x10) << 1; + if(ModeNo > 0x13) temp |= 0x40; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp); + + /* What is this? */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09); + + /* Write CRT/CPU threshold high */ + temp = ThresholdLow + 3; + if(temp > 0x0f) temp = 0x0f; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x09,temp); +} + +USHORT +SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK, USHORT colordepth, USHORT MCLK) +{ + USHORT tempax, tempbx; + + tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0); + tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1); + if(tempax < 4) tempax = 4; + tempax -= 4; + if(tempbx < tempax) tempbx = tempax; + return(tempbx); +} + +USHORT +SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key) +{ + const UCHAR ThLowA[] = { 61, 3,52, 5,68, 7,100,11, + 43, 3,42, 5,54, 7, 78,11, + 34, 3,37, 5,47, 7, 67,11 }; + + const UCHAR ThLowB[] = { 81, 4,72, 6,88, 8,120,12, + 55, 4,54, 6,66, 8, 90,12, + 42, 4,45, 6,55, 8, 75,12 }; + + const UCHAR ThTiming[] = { 1, 2, 2, 3, 0, 1, 1, 2 }; + + USHORT tempah, tempal, tempcl, tempbx, temp; + ULONG longtemp; + + tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18); + tempah &= 0x62; + tempah >>= 1; + tempal = tempah; + tempah >>= 3; + tempal |= tempah; + tempal &= 0x07; + tempcl = ThTiming[tempal]; + tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + tempbx >>= 6; + tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + tempah >>= 4; + tempah &= 0x0c; + tempbx |= tempah; + tempbx <<= 1; + if(key == 0) { + tempal = ThLowA[tempbx + 1]; + tempal *= tempcl; + tempal += ThLowA[tempbx]; + } else { + tempal = ThLowB[tempbx + 1]; + tempal *= tempcl; + tempal += ThLowB[tempbx]; + } + longtemp = tempal * VCLK * colordepth; + temp = longtemp % (MCLK * 16); + longtemp /= (MCLK * 16); + if(temp) longtemp++; + return((USHORT)longtemp); +} + +#if 0 /* TW: Old fragment, unused */ +USHORT +SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT key) +{ + USHORT data,data2,temp0,temp1; + UCHAR ThLowA[]= {61,3,52,5,68,7,100,11, + 43,3,42,5,54,7, 78,11, + 34,3,37,5,47,7, 67,11}; + + UCHAR ThLowB[]= {81,4,72,6,88,8,120,12, + 55,4,54,6,66,8, 90,12, + 42,4,45,6,55,8, 75,12}; + + UCHAR ThTiming[]= {1,2,2,3,0,1,1,2}; + + data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16); + data=data>>6; + data2=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + data2=(data2>>4)&0x0C; + data=data|data2; + data=data<1; + if(key==0) { + temp0=(USHORT)ThLowA[data]; + temp1=(USHORT)ThLowA[data+1]; + } else { + temp0=(USHORT)ThLowB[data]; + temp1=(USHORT)ThLowB[data+1]; + } + + data2=0; + data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18); + if(data&0x02) data2=data2|0x01; + if(data&0x20) data2=data2|0x02; + if(data&0x40) data2=data2|0x04; + + data=temp1*ThTiming[data2]+temp0; + return(data); +} +#endif + +void +SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT RefreshRateTableIndex) +{ + USHORT i,index,data,VCLK,MCLK,colorth=0; + ULONG B,eax,bl,data2; + USHORT ThresholdLow=0; + UCHAR FQBQData[]= { + 0x01,0x21,0x41,0x61,0x81, + 0x31,0x51,0x71,0x91,0xb1, + 0x00,0x20,0x40,0x60,0x80, + 0x30,0x50,0x70,0x90,0xb0, + 0xFF + }; + UCHAR FQBQData730[]= { + 0x34,0x74,0xb4, + 0x23,0x63,0xa3, + 0x12,0x52,0x92, + 0x01,0x41,0x81, + 0x00,0x40,0x80, + 0xff + }; + + i=0; + if(ModeNo >= 0x13) { + if(SiS_Pr->UseCustomMode) { + VCLK = SiS_Pr->CSRClock; + } else { + index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + index &= 0x3F; + VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */ + } + + index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A); + index &= 0x07; + MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */ + + data2 = SiS_Pr->SiS_ModeType - ModeEGA; /* Get half colordepth */ + switch (data2) { + case 0 : colorth = 1; break; + case 1 : colorth = 1; break; + case 2 : colorth = 2; break; + case 3 : colorth = 2; break; + case 4 : colorth = 3; break; + case 5 : colorth = 4; break; + } + + if(HwDeviceExtension->jChipType == SIS_730) { + + do { + B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData730[i], HwDeviceExtension) * VCLK * colorth; + bl = B / (MCLK * 16); + + if(B == bl * 16 * MCLK) { + bl = bl + 1; + } else { + bl = bl + 2; + } + + if(bl > 0x13) { + if(FQBQData730[i+1] == 0xFF) { + ThresholdLow = 0x13; + break; + } + i++; + } else { + ThresholdLow = bl; + break; + } + } while(FQBQData730[i] != 0xFF); + + } else { + + do { + B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData[i], HwDeviceExtension) * VCLK * colorth; + bl = B / (MCLK * 16); + + if(B == bl * 16 * MCLK) { + bl = bl + 1; + } else { + bl = bl + 2; + } + + if(bl > 0x13) { + if(FQBQData[i+1] == 0xFF) { + ThresholdLow = 0x13; + break; + } + i++; + } else { + ThresholdLow = bl; + break; + } + } while(FQBQData[i] != 0xFF); + } + } + else { + if(HwDeviceExtension->jChipType == SIS_730) { + } else { + i = 9; + } + ThresholdLow = 0x02; + } + + /* Write foreground and background queue */ + if(HwDeviceExtension->jChipType == SIS_730) { + + data2 = FQBQData730[i]; + data2 = (data2 & 0xC0) >> 5; + data2 <<= 8; + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x80000050); + eax = SiS_GetReg3(0xcfc); + eax &= 0xfffff9ff; + eax |= data2; + SiS_SetReg4(0xcfc,eax); +#else + /* We use pci functions X offers. We use pcitag 0, because + * we want to read/write to the host bridge (which is always + * 00:00.0 on 630, 730 and 540), not the VGA device. + */ + eax = pciReadLong(0x00000000, 0x50); + eax &= 0xfffff9ff; + eax |= data2; + pciWriteLong(0x00000000, 0x50, eax); +#endif + + /* Write GUI grant timer (PCI config 0xA3) */ + data2 = FQBQData730[i] << 8; + data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8); + data2 <<= 20; + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x800000A0); + eax = SiS_GetReg3(0xcfc); + eax &= 0x00ffffff; + eax |= data2; + SiS_SetReg4(0xcfc,eax); +#else + eax = pciReadLong(0x00000000, 0xA0); + eax &= 0x00ffffff; + eax |= data2; + pciWriteLong(0x00000000, 0xA0, eax); +#endif + + } else { + + data2 = FQBQData[i]; + data2 = (data2 & 0xf0) >> 4; + data2 <<= 24; + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x80000050); + eax = SiS_GetReg3(0xcfc); + eax &= 0xf0ffffff; + eax |= data2; + SiS_SetReg4(0xcfc,eax); +#else + eax = pciReadLong(0x00000000, 0x50); + eax &= 0xf0ffffff; + eax |= data2; + pciWriteLong(0x00000000, 0x50, eax); +#endif + + /* Write GUI grant timer (PCI config 0xA3) */ + data2 = FQBQData[i]; + data2 &= 0x0f; + data2 <<= 24; + +#ifndef LINUX_XF86 + SiS_SetReg4(0xcf8,0x800000A0); + eax = SiS_GetReg3(0xcfc); + eax &= 0xf0ffffff; + eax |= data2; + SiS_SetReg4(0xcfc,eax); +#else + eax = pciReadLong(0x00000000, 0xA0); + eax &= 0xf0ffffff; + eax |= data2; + pciWriteLong(0x00000000, 0xA0, eax); +#endif + + } + + /* Write CRT/CPU threshold low, CRT/Engine threshold high */ + data = ((ThresholdLow & 0x0f) << 4) | 0x0f; + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,data); + + data = (ThresholdLow & 0x10) << 1; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data); + + /* What is this? */ + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09); + + /* Write CRT/CPU threshold high (gap = 3) */ + data = ThresholdLow + 3; + if(data > 0x0f) data = 0x0f; + SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data); +} + +USHORT +SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr,UCHAR key, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT data,index; + const UCHAR LatencyFactor[] = { + 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */ + 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */ + 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */ + 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */ + 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */ + 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */ + 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */ + 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */ + }; + const UCHAR LatencyFactor730[] = { + 69, 63, 61, + 86, 79, 77, + 103, 96, 94, + 120,113,111, + 137,130,128, /* --- Table ends with this entry, data below */ + 137,130,128, /* to avoid using illegal values */ + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + 137,130,128, + }; + + if(HwDeviceExtension->jChipType == SIS_730) { + index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6); + data = LatencyFactor730[index]; + } else { + index = (key & 0xE0) >> 5; + if(key & 0x10) index +=6; + if(!(key & 0x01)) index += 24; + data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14); + if(data & 0x0080) index += 12; + data = LatencyFactor[index]; + } + return(data); +} +#endif + +/* =============== Autodetection ================ */ +/* I N C O M P L E T E */ + +BOOLEAN +SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + const USHORT PanelTypeTable300[16] = { + 0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072, + 0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2 + }; + const USHORT PanelTypeTable31030x[16] = { + 0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179, + 0x0189, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }; + const USHORT PanelTypeTable310LVDS[16] = { + 0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188, + 0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }; + USHORT tempax,tempbx,tempah,temp; + + if(HwDeviceExtension->jChipType < SIS_315H) { + + tempax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18); + tempbx = tempax & 0x0F; + if(!(tempax & 0x10)){ + if(SiS_Pr->SiS_IF_DEF_LVDS == 1){ + tempbx = 0; + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38); + if(temp & 0x40) tempbx |= 0x08; + if(temp & 0x20) tempbx |= 0x02; + if(temp & 0x01) tempbx |= 0x01; + temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x39); + if(temp & 0x80) tempbx |= 0x04; + } else { + return 0; + } + } + tempbx = PanelTypeTable300[tempbx]; + tempbx |= LCDSync; + temp = tempbx & 0x00FF; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp); + temp = (tempbx & 0xFF00) >> 8; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp); + + } else { + + tempax = tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1a); + tempax &= 0x1e; + tempax >>= 1; + if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { + if(tempax == 0) { + /* TODO: Include HUGE detection routine + (Probably not worth bothering) + */ + return 0; + } + temp = tempax & 0xff; + tempax--; + tempbx = PanelTypeTable310LVDS[tempax]; + } else { + tempbx = PanelTypeTable31030x[tempax]; + temp = tempbx & 0xff; + } + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp); + tempbx = (tempbx & 0xff00) >> 8; + temp = tempbx & 0xc1; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp); + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + temp = tempbx & 0x04; + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp); + } + + } + return 1; +} + + +#ifdef LINUXBIOS + +void +SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr) +{ + UCHAR DAC_TEST_PARMS[] = {0x0F,0x0F,0x0F}; + UCHAR DAC_CLR_PARMS[] = {0x00,0x00,0x00}; + USHORT SR1F; + + SR1F = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F); /* backup DAC pedestal */ + SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1F,0x04); + + if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { + if(!(SiS_BridgeIsOn(SiS_Pr, BaseAddr))) { + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x41); + } + } + + SiSSetMode(SiS_Pr,HwDeviceExtension,0x2E); + if(HwDeviceExtension->jChipType >= SIS_650) { + /* TW: On 650 only - enable CRT1 */ + SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf); + } + SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff); + SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8); + SiS_LongWait(SiS_Pr); + SiS_LongWait(SiS_Pr); + SiS_LongWait(SiS_Pr); + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x00); + if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20); + } else if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) { + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20); + } + SiS_TestMonitorType(SiS_Pr, DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]); + + SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,SR1F); +} + +USHORT +SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC) +{ + USHORT temp,tempbx; + + tempbx = R_DAC * 0x4d + G_DAC * 0x97 + B_DAC * 0x1c; + if((tempbx & 0x00ff) > 0x80) tempbx += 0x100; + tempbx = (tempbx & 0xFF00) >> 8; + R_DAC = (UCHAR) tempbx; + G_DAC = (UCHAR) tempbx; + B_DAC = (UCHAR) tempbx; + + SiS_SetReg3(SiS_Pr->SiS_P3c8,0x00); + SiS_SetReg3(SiS_Pr->SiS_P3c9,R_DAC); + SiS_SetReg3(SiS_Pr->SiS_P3c9,G_DAC); + SiS_SetReg3(SiS_Pr->SiS_P3c9,B_DAC); + SiS_LongWait(SiS_Pr); + temp=SiS_GetReg2(SiS_Pr->SiS_P3c2); + if(temp & 0x10) return(1); + else return(0); +} + +void +SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr) +{ + USHORT tempax=0,tempbx,tempcx,temp; + USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*SiS_Pr->pSiS_OutputSelect; + USHORT ModeIdIndex,i; + USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress; + + if(SiS_Pr->SiS_IF_DEF_LVDS == 1){ + SiS_GetPanelID(SiS_Pr); + temp=LCDSense; + temp=temp|SiS_SenseCHTV(SiS_Pr); + tempbx=~(LCDSense|AVIDEOSense|SVIDEOSense); + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,tempbx,temp); + } else { /* for 301 */ + if(SiS_Pr->SiS_IF_DEF_HiVision==1) { /* for HiVision */ + tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38); + temp=tempax&0x01; + tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A); + temp=temp|(tempax&0x02); + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xA0,temp); + } else { + if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)==0) { /* TW: Inserted "==0" */ + P2reg0 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00); + if(!(SiS_BridgeIsEnable(SiS_Pr, BaseAddr,HwDeviceExtension))) { + SenseModeNo=0x2e; + temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&SenseModeNo,&ModeIdIndex); + SiS_Pr->SiS_SetFlag = 0x00; + SiS_Pr->SiS_ModeType = ModeVGA; + SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode; + SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension); + for(i=0;i<20;i++) { + SiS_LongWait(SiS_Pr); + } + } + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1c); + tempax=0; + tempbx=*SiS_Pr->pSiS_RGBSenseData; + if(SiS_Is301B(SiS_Pr, BaseAddr)){ + tempbx=*SiS_Pr->pSiS_RGBSenseData2; + } + tempcx=0x0E08; + if(SiS_Sense(SiS_Pr, tempbx,tempcx)){ + if(SiS_Sense(SiS_Pr, tempbx,tempcx)){ + tempax=tempax|Monitor2Sense; + } + } + tempbx=*SiS_Pr->pSiS_YCSenseData; + if(SiS_Is301B(SiS_Pr, BaseAddr)){ + tempbx=*SiS_Pr->pSiS_YCSenseData2; + } + tempcx=0x0604; + if(SiS_Sense(SiS_Pr, tempbx,tempcx)){ + if(SiS_Sense(SiS_Pr,tempbx,tempcx)){ + tempax=tempax|SVIDEOSense; + } + } + + if(ROMAddr && SiS_Pr->SiS_UseROM) { +#ifdef SIS300 + if((HwDeviceExtension->jChipType==SIS_630)|| + (HwDeviceExtension->jChipType==SIS_730)) { + OutputSelect = ROMAddr[0xfe]; + } +#endif +#ifdef SIS315H + if(HwDeviceExtension->jChipType >= SIS_315H) { + OutputSelect = ROMAddr[0xf3]; + if(HwDeviceExtension->jChipType == SIS_330) { + OutputSelect = ROMAddr[0x11b]; + } + } +#endif + } + if(OutputSelect & BoardTVType){ + tempbx = *SiS_Pr->pSiS_VideoSenseData; + if(SiS_Is301B(SiS_Pr, BaseAddr)){ + tempbx = *SiS_Pr->pSiS_VideoSenseData2; + } + tempcx = 0x0804; + if(SiS_Sense(SiS_Pr, tempbx,tempcx)){ + if(SiS_Sense(SiS_Pr, tempbx,tempcx)){ + tempax |= AVIDEOSense; + } + } + } else { + if(!(tempax & SVIDEOSense)){ + tempbx = *SiS_Pr->pSiS_VideoSenseData; + if(SiS_Is301B(SiS_Pr, BaseAddr)){ + tempbx = *SiS_Pr->pSiS_VideoSenseData2; + } + tempcx = 0x0804; + if(SiS_Sense(SiS_Pr,tempbx,tempcx)){ + if(SiS_Sense(SiS_Pr, tempbx,tempcx)){ + tempax |= AVIDEOSense; + } + } + } + } + } + + if(SiS_SenseLCD(SiS_Pr, HwDeviceExtension)){ + tempax |= LCDSense; + } + + tempbx=0; + tempcx=0; + SiS_Sense(SiS_Pr, tempbx,tempcx); + + if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xNEW)) { + tempax &= 0x00ef; /* 301lv to disable CRT2*/ + } + SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,~0xDF,tempax); + SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0); + if(!(P2reg0 & 0x20)) { + SiS_Pr->SiS_VBInfo = DisableCRT2Display; + SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension); + } + } + } +} + +BOOLEAN +SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx) +{ + USHORT temp,i,tempch; + + temp = tempbx & 0xFF; + SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x11,temp); + temp = (tempbx & 0xFF00) >> 8; + temp |= (tempcx & 0x00FF); + SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,~0x1F,temp); + + for(i=0; i<10; i++) SiS_LongWait(SiS_Pr); + + tempch = (tempcx & 0x7F00) >> 8; + temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x03); + temp ^= 0x0E; + temp &= tempch; + if(temp>0) return 1; + else return 0; +} + +USHORT +SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp; + + temp=SiS_GetPanelID(SiS_Pr); + if(!temp) temp=SiS_GetLCDDDCInfo(SiS_Pr, HwDeviceExtension); + return(temp); +} + +BOOLEAN +SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension) +{ + USHORT temp; + /*add lcd sense*/ + if(HwDeviceExtension->ulCRT2LCDType==LCD_UNKNOWN) + return 0; + else{ + temp=(USHORT)HwDeviceExtension->ulCRT2LCDType; + SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp); + return 1; + } +} + +USHORT +SiS_SenseCHTV(SiS_Private *SiS_Pr) +{ + USHORT temp,push0e,status; + + status=0; + push0e = SiS_GetCH700x(SiS_Pr, 0x0e); + push0e = (push0e << 8) | 0x0e; + SiS_SetCH700x(SiS_Pr, 0x0b0e); + SiS_SetCH700x(SiS_Pr, 0x0110); + SiS_SetCH700x(SiS_Pr, 0x0010); + temp = SiS_GetCH700x(SiS_Pr, 0x10); + if(temp & 0x08) status |= SVIDEOSense; + if(temp & 0x02) status |= AVIDEOSense; + SiS_SetCH700x(SiS_Pr, push0e); + return(status); +} +#endif /* LINUXBIOS */ + +/* ================ for TC only ================= */ + +#ifdef TC + +int +INT1AReturnCode(union REGS regs) +{ + if (regs.x.cflag) + { + /*printf("Error to find pci device!\n"); */ + return 1; + } + + switch(regs.h.ah) + { + case 0: return 0; + break; + case 0x81: printf("Function not support\n"); + break; + case 0x83: printf("bad vendor id\n"); + break; + case 0x86: printf("device not found\n"); + break; + case 0x87: printf("bad register number\n"); + break; + case 0x88: printf("set failed\n"); + break; + case 0x89: printf("buffer too small"); + break; + } + return 1; +} + +unsigned +FindPCIIOBase(unsigned index,unsigned deviceid) +{ + union REGS regs; + + regs.h.ah = 0xb1; /*PCI_FUNCTION_ID */ + regs.h.al = 0x02; /*FIND_PCI_DEVICE */ + regs.x.cx = deviceid; + regs.x.dx = 0x1039; + regs.x.si = index; /* find n-th device */ + + int86(0x1A, ®s, ®s); + + if (INT1AReturnCode(regs)!=0) + return 0; + + /* regs.h.bh *//* bus number */ + /* regs.h.bl *//* device number */ + regs.h.ah = 0xb1; /*PCI_FUNCTION_ID */ + regs.h.al = 0x09; /*READ_CONFIG_WORD */ + regs.x.cx = deviceid; + regs.x.dx = 0x1039; + regs.x.di = 0x18; /* register number */ + int86(0x1A, ®s, ®s); + + if (INT1AReturnCode(regs)!=0) + return 0; + return regs.x.cx; +} + + +void +main(int argc, char *argv[]) +{ + SIS_HW_DEVICE_INFO HwDeviceExtension; + USHORT temp; + USHORT ModeNo; + + /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */ + /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/ + +#ifdef SIS300 + HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30; + HwDeviceExtension.jChipType = SIS_630; +#endif + +#ifdef SIS315H +// HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30; +// HwDeviceExtension.jChipType = SIS_550; + HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30; + HwDeviceExtension.jChipType = SIS_315H; +#endif + + HwDeviceExtension.ujVBChipID = VB_CHIP_301; + strcpy(HwDeviceExtension.szVBIOSVer,"0.84"); + HwDeviceExtension.bSkipDramSizing = FALSE; + HwDeviceExtension.ulVideoMemorySize = 0; + if(argc==2) { + ModeNo=atoi(argv[1]); + } + else { + ModeNo=0x2e; + /*ModeNo=0x37; */ /* 1024x768x 4bpp */ + /*ModeNo=0x38; *//* 1024x768x 8bpp */ + /*ModeNo=0x4A; *//* 1024x768x 16bpp */ + /*ModeNo=0x47;*/ /* 800x600x 16bpp */ + } + /* SiSInit(SiS_Pr, &HwDeviceExtension);*/ + SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo); +} +#endif /* TC END */ + +/* ================ LINUX XFREE86 ====================== */ + +/* Helper functions */ + +#ifdef LINUX_XF86 +USHORT +SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + SISPtr pSiS = SISPTR(pScrn); + UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; + UShort ModeIndex = 0; + + if((pSiS->HaveCustomModes) && (!(mode->type & M_T_DEFAULT))) + return 0xfe; + + switch(mode->HDisplay) + { + case 320: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_320x480[i]; + } + break; + case 512: + if(mode->VDisplay == 384) { + ModeIndex = ModeIndex_512x384[i]; + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 720: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_720x480[i]; + } else if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_720x576[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } else if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_800x480[i]; + } + break; + case 848: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_848x480[i]; + } + break; + case 856: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_856x480[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1024x768[i]; + } else if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_1024x576[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_1024x600[i]; + } + } + break; + case 1152: + if(mode->VDisplay == 864) { + ModeIndex = ModeIndex_1152x864[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1152x768[i]; + } + } + break; + case 1280: + if(mode->VDisplay == 960) { + if(pSiS->VGAEngine == SIS_300_VGA) { + ModeIndex = ModeIndex_300_1280x960[i]; + } else { + ModeIndex = ModeIndex_310_1280x960[i]; + } + } else if (mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } else if (mode->VDisplay == 720) { + ModeIndex = ModeIndex_1280x720[i]; + } else if(pSiS->VGAEngine == SIS_315_VGA) { + if (mode->VDisplay == 768) { + ModeIndex = ModeIndex_1280x768[i]; + } + } + break; + case 1360: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1360x768[i]; + } + break; + case 1400: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(mode->VDisplay == 1050) { + ModeIndex = ModeIndex_1400x1050[i]; + } + } + break; + case 1600: + if(mode->VDisplay == 1200) { + ModeIndex = ModeIndex_1600x1200[i]; + } + break; + case 1920: + if(mode->VDisplay == 1440) { + ModeIndex = ModeIndex_1920x1440[i]; + } + break; + case 2048: + if(mode->VDisplay == 1536) { + if(pSiS->VGAEngine == SIS_300_VGA) { + ModeIndex = ModeIndex_300_2048x1536[i]; + } else { + ModeIndex = ModeIndex_310_2048x1536[i]; + } + } + break; + } + + return(ModeIndex); +} + +USHORT +SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) +{ + SISPtr pSiS = SISPTR(pScrn); + UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; + UShort ModeIndex = 0; + + if(VBFlags & CRT2_LCD) { + + if( (mode->HDisplay <= pSiS->LCDwidth) && + (mode->VDisplay <= pSiS->LCDheight) ) { + + if(VBFlags & VB_LVDS) { /* LCD on LVDS */ + + switch(mode->HDisplay) + { + case 512: + if(mode->VDisplay == 384) { + if(pSiS->LCDwidth != 1024 || pSiS->LCDheight != 600) { /* not supported on 1024x600 panels */ + ModeIndex = ModeIndex_512x384[i]; + } + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1024x768[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 600) { + if(pSiS->LCDheight == 600) { /* This mode only supported on 1024x600 panels */ + ModeIndex = ModeIndex_1024x600[i]; + } + } + } + break; + case 1152: + if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1152x768[i]; + } + } + break; + case 1280: + if(mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } else if(pSiS->VGAEngine == SIS_315_VGA) { + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1280x768[i]; + } + } + break; + case 1400: + if(mode->VDisplay == 1050) { + if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_1400x1050[i]; + } + } + break; + } + + } else { /* LCD on 301(B) */ + + switch(mode->HDisplay) + { + case 512: + if(mode->VDisplay == 384) { + ModeIndex = ModeIndex_512x384[i]; + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1024x768[i]; + } + break; + case 1280: + if(mode->VDisplay == 960) { + if(pSiS->VGAEngine == SIS_300_VGA) { + ModeIndex = ModeIndex_300_1280x960[i]; + } else { + ModeIndex = ModeIndex_310_1280x960[i]; + } + } else if (mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } + break; + case 1400: + if(mode->VDisplay == 1050) { + if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_1400x1050[i]; + } + } + break; + case 1600: + if(mode->VDisplay == 1200) { + ModeIndex = ModeIndex_1600x1200[i]; + } + break; + } + + } + + } + + } else if(VBFlags & CRT2_TV) { + + if(VBFlags & VB_CHRONTEL) { /* TV on Chrontel */ + + switch(mode->HDisplay) + { + case 512: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(mode->VDisplay == 384) { + ModeIndex = ModeIndex_512x384[i]; + } + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + if(pSiS->VGAEngine == SIS_315_VGA) { + ModeIndex = ModeIndex_1024x768[i]; + } + } + break; + } + + } else { /* TV on 301(B/LV) */ + + switch(mode->HDisplay) + { + case 512: + if(mode->VDisplay == 384) { + ModeIndex = ModeIndex_512x384[i]; + } + break; + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } + break; + case 720: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_720x480[i]; + } else if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_720x576[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } + break; + case 1024: /* Not supported with depth 32 */ + if((mode->VDisplay == 768) && (i != 3) ) { + if(VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) { + ModeIndex = ModeIndex_1024x768[i]; + } + } + break; + } + + } + + } else if(VBFlags & CRT2_VGA) { /* CRT2 is VGA2 */ + + switch(mode->HDisplay) + { + case 640: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_640x480[i]; + } else if(mode->VDisplay == 400) { + ModeIndex = ModeIndex_640x400[i]; + } + break; + case 800: + if(mode->VDisplay == 600) { + ModeIndex = ModeIndex_800x600[i]; + } else if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_800x480[i]; + } + break; + case 848: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_848x480[i]; + } + break; + case 856: + if(mode->VDisplay == 480) { + ModeIndex = ModeIndex_856x480[i]; + } + break; + case 1024: + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1024x768[i]; + } else if(mode->VDisplay == 576) { + ModeIndex = ModeIndex_1024x576[i]; + } + break; + case 1152: + if(mode->VDisplay == 864) { + ModeIndex = ModeIndex_1152x864[i]; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(mode->VDisplay == 768) { + ModeIndex = ModeIndex_1152x768[i]; + } + } + break; + case 1280: + if (mode->VDisplay == 1024) { + ModeIndex = ModeIndex_1280x1024[i]; + } else if (mode->VDisplay == 720) { + ModeIndex = ModeIndex_1280x720[i]; + } else if(pSiS->VGAEngine == SIS_315_VGA) { + if (mode->VDisplay == 768) { + ModeIndex = ModeIndex_1280x768[i]; + } + } + break; + } + + } else { /* CRT1 only, no CRT2 */ + + ModeIndex = SiS_CalcModeIndex(pScrn, mode); + + } + + return(ModeIndex); +} + +USHORT +SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) +{ + SISPtr pSiS = SISPTR(pScrn); + int out_n, out_dn, out_div, out_sbit, out_scale; + int depth = pSiS->CurrentLayout.bitsPerPixel; + +#ifdef SISDUALHEAD + if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) || + ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0; +#else + if(VBFlags & DISPTYPE_DISP2) return 0; +#endif + + pSiS->SiS_Pr->CDClock = mode->Clock; + + pSiS->SiS_Pr->CHDisplay = mode->HDisplay; + pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart; + pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd; + pSiS->SiS_Pr->CHTotal = mode->HTotal; + pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay; + pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal; + + pSiS->SiS_Pr->CVDisplay = mode->VDisplay; + pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart; + pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd; + pSiS->SiS_Pr->CVTotal = mode->VTotal; + pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1; + pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal; + + pSiS->SiS_Pr->CFlags = mode->Flags; + + SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale); + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n", + pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale); +#endif + + pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00; + pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f); + pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f; + pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5); + pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7); + pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1; + + pSiS->SiS_Pr->CCRT1CRTC[0] = ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff; + pSiS->SiS_Pr->CCRT1CRTC[1] = (pSiS->SiS_Pr->CHDisplay >> 3) - 1; + pSiS->SiS_Pr->CCRT1CRTC[2] = (pSiS->SiS_Pr->CHBlankStart >> 3) - 1; + pSiS->SiS_Pr->CCRT1CRTC[3] = (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; + pSiS->SiS_Pr->CCRT1CRTC[4] = (pSiS->SiS_Pr->CHSyncStart >> 3) + 3; + pSiS->SiS_Pr->CCRT1CRTC[5] = ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | + (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F); + + pSiS->SiS_Pr->CCRT1CRTC[6] = (pSiS->SiS_Pr->CVTotal - 2) & 0xFF; + pSiS->SiS_Pr->CCRT1CRTC[7] = (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8) + | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7) + | ((pSiS->SiS_Pr->CVSyncStart & 0x100) >> 6) + | (((pSiS->SiS_Pr->CVBlankStart - 1) & 0x100) >> 5) + | 0x10 + | (((pSiS->SiS_Pr->CVTotal - 2) & 0x200) >> 4) + | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3) + | ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2); + + pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* cr9 */ + +#if 0 + if (mode->VScan >= 32) + regp->CRTC[9] |= 0x1F; + else if (mode->VScan > 1) + regp->CRTC[9] |= mode->VScan - 1; +#endif + + pSiS->SiS_Pr->CCRT1CRTC[8] = (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF; /* cr10 */ + pSiS->SiS_Pr->CCRT1CRTC[9] = ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80; /* cr11 */ + pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF; /* cr12 */ + pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF; /* cr15 */ + pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF; /* cr16 */ + + pSiS->SiS_Pr->CCRT1CRTC[13] = + GETBITSTR((pSiS->SiS_Pr->CVTotal -2), 10:10, 0:0) | + GETBITSTR((pSiS->SiS_Pr->CVDisplay -1), 10:10, 1:1) | + GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) | + GETBITSTR((pSiS->SiS_Pr->CVSyncStart ), 10:10, 3:3) | + GETBITSTR((pSiS->SiS_Pr->CVBlankEnd -1), 8:8, 4:4) | + GETBITSTR((pSiS->SiS_Pr->CVSyncEnd -1), 4:4, 5:5) ; + + pSiS->SiS_Pr->CCRT1CRTC[14] = + GETBITSTR((pSiS->SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) | + GETBITSTR((pSiS->SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) | + GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) | + GETBITSTR((pSiS->SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ; + + + pSiS->SiS_Pr->CCRT1CRTC[15] = + GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) | + GETBITSTR((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ; + + switch(depth) { + case 8: + pSiS->SiS_Pr->CModeFlag = 0x223b; + break; + case 16: + pSiS->SiS_Pr->CModeFlag = 0x227d; + break; + case 32: + pSiS->SiS_Pr->CModeFlag = 0x22ff; + break; + default: + return 0; + } + + if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) + pSiS->SiS_Pr->CModeFlag |= DoubleScanMode; + if((pSiS->SiS_Pr->CVDisplay >= 1024) || + (pSiS->SiS_Pr->CVTotal >= 1024) || + (pSiS->SiS_Pr->CHDisplay >= 1024)) + pSiS->SiS_Pr->CModeFlag |= LineCompareOff; + if(pSiS->SiS_Pr->CFlags & V_CLKDIV2) + pSiS->SiS_Pr->CModeFlag |= HalfDCLK; + + pSiS->SiS_Pr->CInfoFlag = 0x0007; + if(pSiS->SiS_Pr->CFlags & V_NHSYNC) + pSiS->SiS_Pr->CInfoFlag |= 0x4000; + if(pSiS->SiS_Pr->CFlags & V_NVSYNC) + pSiS->SiS_Pr->CInfoFlag |= 0x8000; + if(pSiS->SiS_Pr->CFlags & V_INTERLACE) + pSiS->SiS_Pr->CInfoFlag |= InterlaceMode; + + pSiS->SiS_Pr->UseCustomMode = TRUE; +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n", + pSiS->SiS_Pr->CHDisplay,pSiS->SiS_Pr->CVDisplay); + xf86DrvMsg(0, X_INFO, "Modeflag %04x, Infoflag %04x\n", + pSiS->SiS_Pr->CModeFlag, pSiS->SiS_Pr->CInfoFlag); + xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", + pSiS->SiS_Pr->CCRT1CRTC[0], + pSiS->SiS_Pr->CCRT1CRTC[1], + pSiS->SiS_Pr->CCRT1CRTC[2], + pSiS->SiS_Pr->CCRT1CRTC[3], + pSiS->SiS_Pr->CCRT1CRTC[4], + pSiS->SiS_Pr->CCRT1CRTC[5], + pSiS->SiS_Pr->CCRT1CRTC[6], + pSiS->SiS_Pr->CCRT1CRTC[7]); + xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", + pSiS->SiS_Pr->CCRT1CRTC[8], + pSiS->SiS_Pr->CCRT1CRTC[9], + pSiS->SiS_Pr->CCRT1CRTC[10], + pSiS->SiS_Pr->CCRT1CRTC[11], + pSiS->SiS_Pr->CCRT1CRTC[12], + pSiS->SiS_Pr->CCRT1CRTC[13], + pSiS->SiS_Pr->CCRT1CRTC[14], + pSiS->SiS_Pr->CCRT1CRTC[15]); + xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", pSiS->SiS_Pr->CCRT1CRTC[16]); + xf86DrvMsg(0, X_INFO, "Clock: 0x%02x, 0x%02x, %d\n", + pSiS->SiS_Pr->CSR2B, + pSiS->SiS_Pr->CSR2C, + pSiS->SiS_Pr->CSRClock); +#endif + return 1; +} + +/* TW: Build a list of supported modes */ +DisplayModePtr +SiSBuildBuiltInModeList(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned short VRE, VBE, VRS, VBS, VDE, VT; + unsigned short HRE, HBE, HRS, HBS, HDE, HT; + unsigned char sr_data, cr_data, cr_data2, cr_data3; + unsigned char sr2b, sr2c; + float num, denum, postscalar, divider; + int A, B, C, D, E, F, temp, i, j, index, vclkindex; + DisplayModePtr new = NULL, current = NULL, first = NULL, backup = NULL; + + pSiS->backupmodelist = NULL; + + /* Initialize our pointers */ + if(pSiS->VGAEngine == SIS_300_VGA) { +#ifdef SIS300 + InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext); +#else + return NULL; +#endif + } else if(pSiS->VGAEngine == SIS_315_VGA) { +#ifdef SIS315H + InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext); +#else + return NULL; +#endif + } else return NULL; + + i = 0; + while(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag != 0xFFFF) { + + index = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRT1CRTC; +#if 0 /* Not any longer */ + if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F; +#endif + + if(((pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && (!pSiS->DSTN)) || + ((pSiS->DSTN) && + (pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && + (pSiS->SiS_Pr->SiS_RefIndex[i].XRes != 320) && + (pSiS->SiS_Pr->SiS_RefIndex[i].YRes != 480))) { + i++; + continue; + } + + if(!(new = xalloc(sizeof(DisplayModeRec)))) return first; + memset(new, 0, sizeof(DisplayModeRec)); + if(!(new->name = xalloc(10))) { + xfree(new); + return first; + } + if(!first) first = new; + if(current) { + current->next = new; + new->prev = current; + } + + current = new; + + sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes, + pSiS->SiS_Pr->SiS_RefIndex[i].YRes); + + current->status = MODE_OK; + + current->type = M_T_DEFAULT; + + vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK; + if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F; + + sr2b = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2B; + sr2c = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2C; + + divider = (sr2b & 0x80) ? 2.0 : 1.0; + postscalar = (sr2c & 0x80) ? + ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0); + num = (sr2b & 0x7f) + 1.0; + denum = (sr2c & 0x1f) + 1.0; + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "------------\n"); + xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n", + sr2b, sr2c, divider, postscalar, num, denum); +#endif + + current->Clock = (int)(14318 * (divider / postscalar) * (num / denum)); + + sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[14]; + /* inSISIDXREG(SISSR, 0x0b, sr_data); */ + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[0]; + /* inSISIDXREG(SISCR, 0x00, cr_data); */ + + /* Horizontal total */ + HT = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0x03) << 8); + A = HT + 5; + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[1]; + /* inSISIDXREG(SISCR, 0x01, cr_data); */ + + /* Horizontal display enable end */ + HDE = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0x0C) << 6); + E = HDE + 1; + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[4]; + /* inSISIDXREG(SISCR, 0x04, cr_data); */ + + /* Horizontal retrace (=sync) start */ + HRS = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0xC0) << 2); + F = HRS - E - 3; + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[2]; + /* inSISIDXREG(SISCR, 0x02, cr_data); */ + + /* Horizontal blank start */ + HBS = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0x30) << 4); + + sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[15]; + /* inSISIDXREG(SISSR, 0x0c, sr_data); */ + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[3]; + /* inSISIDXREG(SISCR, 0x03, cr_data); */ + + cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[5]; + /* inSISIDXREG(SISCR, 0x05, cr_data2); */ + + /* Horizontal blank end */ + HBE = (cr_data & 0x1f) | + ((unsigned short) (cr_data2 & 0x80) >> 2) | + ((unsigned short) (sr_data & 0x03) << 6); + + /* Horizontal retrace (=sync) end */ + HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3); + + temp = HBE - ((E - 1) & 255); + B = (temp > 0) ? temp : (temp + 256); + + temp = HRE - ((E + F + 3) & 63); + C = (temp > 0) ? temp : (temp + 64); + + D = B - F - C; + + current->HDisplay = (E * 8); + current->HSyncStart = (E * 8) + (F * 8); + current->HSyncEnd = (E * 8) + (F * 8) + (C * 8); + current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8); + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, + "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n", + A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE); +#endif + + sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[13]; + /* inSISIDXREG(SISSR, 0x0A, sr_data); */ + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[6]; + /* inSISIDXREG(SISCR, 0x06, cr_data); */ + + cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[7]; + /* inSISIDXREG(SISCR, 0x07, cr_data2); */ + + /* Vertical total */ + VT = (cr_data & 0xFF) | + ((unsigned short) (cr_data2 & 0x01) << 8) | + ((unsigned short)(cr_data2 & 0x20) << 4) | + ((unsigned short) (sr_data & 0x01) << 10); + A = VT + 2; + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[10]; + /* inSISIDXREG(SISCR, 0x12, cr_data); */ + + /* Vertical display enable end */ + VDE = (cr_data & 0xff) | + ((unsigned short) (cr_data2 & 0x02) << 7) | + ((unsigned short) (cr_data2 & 0x40) << 3) | + ((unsigned short) (sr_data & 0x02) << 9); + E = VDE + 1; + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[8]; + /* inSISIDXREG(SISCR, 0x10, cr_data); */ + + /* Vertical retrace (=sync) start */ + VRS = (cr_data & 0xff) | + ((unsigned short) (cr_data2 & 0x04) << 6) | + ((unsigned short) (cr_data2 & 0x80) << 2) | + ((unsigned short) (sr_data & 0x08) << 7); + F = VRS + 1 - E; + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[11]; + /* inSISIDXREG(SISCR, 0x15, cr_data); */ + + cr_data3 = (pSiS->SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5; + /* inSISIDXREG(SISCR, 0x09, cr_data3); */ + + /* Vertical blank start */ + VBS = (cr_data & 0xff) | + ((unsigned short) (cr_data2 & 0x08) << 5) | + ((unsigned short) (cr_data3 & 0x20) << 4) | + ((unsigned short) (sr_data & 0x04) << 8); + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[12]; + /* inSISIDXREG(SISCR, 0x16, cr_data); */ + + /* Vertical blank end */ + VBE = (cr_data & 0xff) | + ((unsigned short) (sr_data & 0x10) << 4); + temp = VBE - ((E - 1) & 511); + B = (temp > 0) ? temp : (temp + 512); + + cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[9]; + /* inSISIDXREG(SISCR, 0x11, cr_data); */ + + /* Vertical retrace (=sync) end */ + VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1); + temp = VRE - ((E + F - 1) & 31); + C = (temp > 0) ? temp : (temp + 32); + + D = B - F - C; + + current->VDisplay = VDE + 1; + current->VSyncStart = VRS + 1; + current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1; + if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32; + current->VTotal = E + D + C + F; + +#if 0 + current->VDisplay = E; + current->VSyncStart = E + D; + current->VSyncEnd = E + D + C; + current->VTotal = E + D + C + F; +#endif + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, + "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n", + A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE); +#endif + + if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x4000) + current->Flags |= V_NHSYNC; + else + current->Flags |= V_PHSYNC; + + if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x8000) + current->Flags |= V_NVSYNC; + else + current->Flags |= V_PVSYNC; + + if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x0080) + current->Flags |= V_INTERLACE; + + j = 0; + while(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) { + if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID == + pSiS->SiS_Pr->SiS_RefIndex[i].ModeID) { + if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) { + current->Flags |= V_DBLSCAN; + } + break; + } + j++; + } + + if(current->Flags & V_INTERLACE) { + current->VDisplay <<= 1; + current->VSyncStart <<= 1; + current->VSyncEnd <<= 1; + current->VTotal <<= 1; + current->VTotal |= 1; + } + if(current->Flags & V_DBLSCAN) { + current->Clock >>= 1; + current->VDisplay >>= 1; + current->VSyncStart >>= 1; + current->VSyncEnd >>= 1; + current->VTotal >>= 1; + } + + if((backup = xalloc(sizeof(DisplayModeRec)))) { + if(!pSiS->backupmodelist) pSiS->backupmodelist = backup; + else { + pSiS->backupmodelist->next = backup; + backup->prev = pSiS->backupmodelist; + } + backup->next = NULL; + backup->HDisplay = current->HDisplay; + backup->HSyncStart = current->HSyncStart; + backup->HSyncEnd = current->HSyncEnd; + backup->HTotal = current->HTotal; + backup->VDisplay = current->VDisplay; + backup->VSyncStart = current->VSyncStart; + backup->VSyncEnd = current->VSyncEnd; + backup->VTotal = current->VTotal; + backup->Flags = current->Flags; + backup->Clock = current->Clock; + } + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Built-in: %s %.2f %d %d %d %d %d %d %d %d\n", + current->name, (float)current->Clock / 1000, + current->HDisplay, current->HSyncStart, current->HSyncEnd, current->HTotal, + current->VDisplay, current->VSyncStart, current->VSyncEnd, current->VTotal); +#endif + + i++; + } + + return first; + +} + +#define MODEID_OFF 0x449 + +unsigned char +SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id) +{ + return(SiS_GetSetBIOSScratch(pScrn, MODEID_OFF, id)); +} + +unsigned char +SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value) +{ + unsigned char ret; + unsigned char *base; + + base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000); + if(!base) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "(init.c: Could not map BIOS scratch area)\n"); + return 0; + } + + ret = *(base + offset); + + /* value != 0xff means: set register */ + if (value != 0xff) + *(base + offset) = value; + + xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000); + + return ret; +} + +#endif + + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/init.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/init.h new file mode 100644 index 000000000..86635092d --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/init.h @@ -0,0 +1,316 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.h,v 1.5 2003/02/10 01:14:16 tsi Exp $ */ + +#ifndef _INIT_ +#define _INIT_ + +#include "osdef.h" +#include "initdef.h" +#include "vgatypes.h" +#include "vstruct.h" + +#ifdef TC +#include <stdio.h> +#include <string.h> +#include <conio.h> +#include <dos.h> +#include <stdlib.h> +#endif + +#ifdef LINUX_XF86 +#include "xf86.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xf86_OSproc.h" +#include "sis.h" +#include "sis_regs.h" +#endif + +#ifdef LINUX_KERNEL +#include <linux/types.h> +#include <asm/io.h> +#include <linux/sisfb.h> +#endif + +#ifdef WIN2000 +#include <stdio.h> +#include <string.h> +#include <miniport.h> +#include "dderror.h" +#include "devioctl.h" +#include "miniport.h" +#include "ntddvdeo.h" +#include "video.h" +#include "sisv.h" +#include "tools.h" +#endif + +const USHORT SiS_DRAMType[17][5]={ + {0x0C,0x0A,0x02,0x40,0x39}, + {0x0D,0x0A,0x01,0x40,0x48}, + {0x0C,0x09,0x02,0x20,0x35}, + {0x0D,0x09,0x01,0x20,0x44}, + {0x0C,0x08,0x02,0x10,0x31}, + {0x0D,0x08,0x01,0x10,0x40}, + {0x0C,0x0A,0x01,0x20,0x34}, + {0x0C,0x09,0x01,0x08,0x32}, + {0x0B,0x08,0x02,0x08,0x21}, + {0x0C,0x08,0x01,0x08,0x30}, + {0x0A,0x08,0x02,0x04,0x11}, + {0x0B,0x0A,0x01,0x10,0x28}, + {0x09,0x08,0x02,0x02,0x01}, + {0x0B,0x09,0x01,0x08,0x24}, + {0x0B,0x08,0x01,0x04,0x20}, + {0x0A,0x08,0x01,0x02,0x10}, + {0x09,0x08,0x01,0x01,0x00} +}; + +const USHORT SiS_SDRDRAM_TYPE[13][5] = +{ + { 2,12, 9,64,0x35}, + { 1,13, 9,64,0x44}, + { 2,12, 8,32,0x31}, + { 2,11, 9,32,0x25}, + { 1,12, 9,32,0x34}, + { 1,13, 8,32,0x40}, + { 2,11, 8,16,0x21}, + { 1,12, 8,16,0x30}, + { 1,11, 9,16,0x24}, + { 1,11, 8, 8,0x20}, + { 2, 9, 8, 4,0x01}, + { 1,10, 8, 4,0x10}, + { 1, 9, 8, 2,0x00} +}; + +const USHORT SiS_DDRDRAM_TYPE[4][5] = +{ + { 2,12, 9,64,0x35}, + { 2,12, 8,32,0x31}, + { 2,11, 8,16,0x21}, + { 2, 9, 8, 4,0x01} +}; + +const USHORT SiS_MDA_DAC[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F +}; + +const USHORT SiS_CGA_DAC[] = +{ + 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, + 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, + 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, + 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, + 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, + 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, + 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, + 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F +}; + +const USHORT SiS_EGA_DAC[] = +{ + 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15, + 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35, + 0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D, + 0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D, + 0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17, + 0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37, + 0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F, + 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F +}; + +const USHORT SiS_VGA_DAC[] = +{ + 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, + 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, + 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18, + 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F, + 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F, + 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00, + 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18, + 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04, + 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10, + 0x0B,0x0C,0x0D,0x0F,0x10 +}; + +void SiS_SetReg1(USHORT, USHORT, USHORT); +void SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT); +void SiS_SetReg3(USHORT, USHORT); +void SiS_SetReg4(USHORT, ULONG); +void SiS_SetReg5(USHORT, USHORT); +UCHAR SiS_GetReg1(USHORT, USHORT); +UCHAR SiS_GetReg2(USHORT); +ULONG SiS_GetReg3(USHORT); +USHORT SiS_GetReg4(USHORT); +void SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG); +void SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); +BOOLEAN SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo); +void SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); + +#ifdef SIS300 +void SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +USHORT SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress); +#endif + +#ifdef SIS315H +UCHAR SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_DDR_MRS(SiS_Private *SiS_Pr); +void SiS_SDR_MRS(SiS_Private *SiS_Pr); +void SiS_DisableRefresh(SiS_Private *SiS_Pr); +void SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr); +void SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO); +void SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index,USHORT SiS_DDRDRAM_TYPE[][5]); +void SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5]); +void SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +int SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5]); +int SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo, + USHORT DRAMTYPE_TABLE[][5]); +int SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress); +int SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress); +int SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress); +int SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress); +int SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress); +int SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress); +int SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress); +int SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress); +int Is315E(SiS_Private *SiS_Pr); +void SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr); +#endif + +void SiS_HandleCRT1(SiS_Private *SiS_Pr); +void SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo); +void SiS_SetEnableDstn(SiS_Private *SiS_Pr); +void SiS_Delay15us(SiS_Private *SiS_Pr); +BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex); +BOOLEAN SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeNo,USHORT ModeIdIndex); +UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex); +void SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex); +void SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex); +void SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT StandTableIndex); +void SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex); +void SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex); +void SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +BOOLEAN SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType); +void SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO, + USHORT RefreshRateTableIndex); +void SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO, USHORT ModeNo, + USHORT RefreshRateTableIndex, USHORT ModeIdIndex); +void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); +void SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT, USHORT, USHORT, USHORT, USHORT, USHORT); +void SiS_DisplayOn(SiS_Private *SiS_Pr); +void SiS_DisplayOff(SiS_Private *SiS_Pr); +void SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO,USHORT ModeNo, + USHORT ModeIdIndex,USHORT RefreshRateTableIndex); +void SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO); +USHORT SiS_ChkBUSWidth(SiS_Private *SiS_Pr, UCHAR *ROMAddr); +USHORT SiS_GetModeIDLength(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT); +USHORT SiS_GetRefindexLength(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT); +void SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex); +void SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT,USHORT,USHORT,PSIS_HW_DEVICE_INFO); +#ifdef SIS315H +void SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT,USHORT,PSIS_HW_DEVICE_INFO); +#endif +#ifdef SIS300 +void SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO, + USHORT RefreshRateTableIndex); +void SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO, + USHORT RefreshRateTableIndex); +USHORT SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK, + USHORT colordepth, USHORT MCLK); +USHORT SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key); +USHORT SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, UCHAR,PSIS_HW_DEVICE_INFO HwDeviceExtension); +#endif +void SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT ModeNo); +void SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension, + USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr); +void SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr); +void SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr); +USHORT SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC); +USHORT SiS_SenseCHTV(SiS_Private *SiS_Pr); +BOOLEAN SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx); +BOOLEAN SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO); +BOOLEAN SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO); +USHORT SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO); +void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr); +void SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo); +void SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +void SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr); + +#ifdef LINUX_XF86 +USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode); +USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags); +USHORT SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags); +void SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr); +void SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr); +void SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr); +unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id); +unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value); +extern int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div, + int *out_sbit, int *out_scale); +#endif + +extern USHORT SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); +extern void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +extern BOOLEAN SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern void SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr); +extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr); +extern BOOLEAN SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr); +extern BOOLEAN SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO ); +extern void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, int chkcrt2mode); +extern BOOLEAN SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, + USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern void SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern USHORT SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern void SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo); +extern void SiS_LongWait(SiS_Private *SiS_Pr); +extern void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR); +extern void SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND); +extern void SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR); +extern USHORT SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex); +extern void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax); +extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax); +extern void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax); +extern USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax); +extern void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax); +extern USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax); +extern BOOLEAN SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + USHORT *ResInfo,USHORT *DisplayType); +extern USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, + USHORT RefreshRateTableIndex, + PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern BOOLEAN SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr); +extern BOOLEAN SiS_IsM650(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +extern BOOLEAN SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern BOOLEAN SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +extern BOOLEAN SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr); +extern USHORT SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension); + +#endif + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h new file mode 100644 index 000000000..8f7e524de --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h @@ -0,0 +1,1005 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h,v 1.3 2003/02/10 01:14:16 tsi Exp $ */ + +/* OEM Data for 300 series */ + +const UCHAR SiS300_OEMTVDelay301[8][4] = +{ + {0x08,0x08,0x08,0x08}, + {0x08,0x08,0x08,0x08}, + {0x08,0x08,0x08,0x08}, + {0x2c,0x2c,0x2c,0x2c}, + {0x08,0x08,0x08,0x08}, + {0x08,0x08,0x08,0x08}, + {0x08,0x08,0x08,0x08}, + {0x20,0x20,0x20,0x20} +}; + +const UCHAR SiS300_OEMTVDelayLVDS[8][4] = +{ + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20} +}; + +const UCHAR SiS300_OEMTVFlicker[8][4] = +{ + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00} +}; + +#if 0 /* TW: Not used */ +const UCHAR SiS300_OEMLCDDelay1[12][4]={ + {0x2c,0x2c,0x2c,0x2c}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x2c,0x2c,0x2c,0x2c}, + {0x2c,0x2c,0x2c,0x2c}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x24,0x24,0x24,0x24}, + {0x24,0x24,0x24,0x24}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x24,0x24,0x24,0x24} +}; +#endif + +/* TW: From 630/301B BIOS */ +const UCHAR SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302LV */ +{ + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20} +}; + +/* TW: From 300/301LV BIOS */ +const UCHAR SiS300_OEMLCDDelay4[12][4] = +{ + {0x2c,0x2c,0x2c,0x2c}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x2c,0x2c,0x2c,0x2c}, + {0x2c,0x2c,0x2c,0x2c}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x24,0x24,0x24,0x24}, + {0x24,0x24,0x24,0x24}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x24,0x24,0x24,0x24} +}; + +/* TW: From 300/301LV BIOS */ +const UCHAR SiS300_OEMLCDDelay5[32][4] = +{ + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, +}; + +/* TW: Added for LVDS */ +const UCHAR SiS300_OEMLCDDelay3[64][4] = { /* For LVDS */ + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20}, + {0x20,0x20,0x20,0x20} +}; + +const UCHAR SiS300_Phase1[8][6][4] = +{ + { + {0x21,0xed,0x00,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x21,0xed,0x00,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + } +}; + + +const UCHAR SiS300_Phase2[8][6][4] = +{ + { + {0x21,0xed,0x00,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x21,0xed,0x00,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0x21,0xed,0x8a,0x08}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00}, + {0xff,0xff,0xff,0xff} + } +}; + +const UCHAR SiS300_Filter1[10][16][4] = +{ + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x10,0x18}, + {0xf7,0x06,0x19,0x14}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x15,0x25,0xf6}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x10,0x32}, + {0xf3,0x00,0x1d,0x20}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xfc,0xfb,0x14,0x2a}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x10,0x32}, + {0xf3,0x00,0x1d,0x20}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xfc,0xfb,0x14,0x2a}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x10,0x32}, + {0xf3,0x00,0x1d,0x20}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xfc,0xfb,0x14,0x2a}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x10,0x18}, + {0xf7,0x06,0x19,0x14}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x15,0x25,0xf6}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x10,0x32}, + {0xf3,0x00,0x1d,0x20}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xfc,0xfb,0x14,0x2a}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x10,0x32}, + {0xf3,0x00,0x1d,0x20}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xfc,0xfb,0x14,0x2a}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x10,0x32}, + {0xf3,0x00,0x1d,0x20}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xfc,0xfb,0x14,0x2a}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32}, + {0xf1,0xf7,0x1f,0x32} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x10,0x18}, + {0xf7,0x06,0x19,0x14}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x15,0x25,0xf6}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x10,0x18}, + {0xf7,0x06,0x19,0x14}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x15,0x25,0xf6}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18} + }, +}; + +const UCHAR SiS300_Filter2[10][9][7] = +{ + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + } +}; + +const UCHAR SiS300_LCDHData[24][11][5] = { + { + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x65,0xef,0x83,0x5c,0x00}, + {0x65,0xef,0x83,0x5c,0x00}, + {0x8a,0x14,0x00,0x80,0x00}, + {0x8a,0x14,0x00,0x80,0x00} + }, + { + {0x4e,0x18,0x90,0x38,0x00}, + {0x4e,0x18,0x90,0x38,0x00}, + {0x8e,0x18,0x28,0x78,0x00}, + {0x8e,0x18,0x28,0x78,0x00}, + {0x8e,0x18,0x28,0x78,0x00}, + {0x4e,0x18,0x90,0x38,0x00}, + {0x4e,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9a,0x56,0x00}, + {0x67,0x11,0x9a,0x56,0x00}, + {0x8a,0x14,0x00,0x80,0x00}, + {0x8a,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x65,0xef,0x83,0x5c,0x00}, + {0x65,0xef,0x83,0x5c,0x00}, + {0x8a,0x14,0x00,0x80,0x00}, + {0x8a,0x14,0x00,0x80,0x00} + }, + { + {0x4e,0x18,0x90,0x38,0x00}, + {0x4e,0x18,0x90,0x38,0x00}, + {0x8e,0x18,0x28,0x78,0x00}, + {0x8e,0x18,0x28,0x78,0x00}, + {0x8e,0x18,0x28,0x78,0x00}, + {0x4e,0x18,0x90,0x38,0x00}, + {0x4e,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9a,0x56,0x00}, + {0x67,0x11,0x9a,0x56,0x00}, + {0x8a,0x14,0x00,0x80,0x00}, + {0x8a,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x67,0x91,0x84,0x5e,0x00}, + {0x65,0xef,0x83,0x5c,0x00}, + {0x65,0xef,0x83,0x5c,0x00}, + {0x8a,0x14,0x00,0x80,0x00}, + {0x8a,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x67,0x91,0x84,0x5E,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x65,0xEF,0x83,0x5C,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + }, + { + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x8E,0x18,0x28,0x78,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x4E,0x18,0x90,0x38,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x67,0x11,0x9A,0x56,0x00}, + {0x8A,0x14,0x00,0x80,0x00}, + {0x8A,0x14,0x00,0x80,0x00} + } +}; + +#if 0 +const UCHAR SiS300_LCDVData[24][11][6] = { + { + { + }, +}; +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h new file mode 100644 index 000000000..c4415aaee --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h @@ -0,0 +1,377 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem310.h,v 1.4 2003/02/10 01:14:16 tsi Exp $ */ + +/* OEM Data for 310/325 series */ + +const UCHAR SiS310_CRT2DelayCompensation1 = 0x04; /* 301 */ + +const UCHAR SiS310_CRT2DelayCompensation2 = 0x00; /* 301B */ + +const UCHAR SiS310_CRT2DelayCompensation3 = 0x00; /* LVDS */ + +const UCHAR SiS310_LCDDelayCompensation1[] = /* 301 */ +{ + 0x00,0x00,0x00, /* 800x600 */ + 0x0b,0x0b,0x0b, /* 1024x768 */ + 0x08,0x08,0x08, /* 1280x1024 */ + 0x00,0x00,0x00, /* 640x480 (unknown) */ + 0x00,0x00,0x00, /* 1024x600 (unknown) */ + 0x00,0x00,0x00, /* 1152x864 (unknown) */ + 0x08,0x08,0x08, /* 1280x960 (guessed) */ + 0x00,0x00,0x00, /* 1152x768 (unknown) */ + 0x08,0x08,0x08, /* 1400x1050 */ + 0x08,0x08,0x08, /* 1280x768 (guessed) */ + 0x00,0x00,0x00, /* 1600x1200 */ + 0x00,0x00,0x00, /* 320x480 (unknown) */ + 0x00,0x00,0x00, + 0x00,0x00,0x00, + 0x00,0x00,0x00 +}; + +UCHAR SiS310_LCDDelayCompensation2[] = /* 30xB,LV,LVX */ +{ + 0x01,0x01,0x01, /* 800x600 */ + 0x01,0x01,0x01, /* 1024x768 */ + 0x01,0x01,0x01, /* 1280x1024 */ + 0x01,0x01,0x01, /* 640x480 (unknown) */ + 0x01,0x01,0x01, /* 1024x600 (unknown) */ + 0x01,0x01,0x01, /* 1152x864 (unknown) */ + 0x01,0x01,0x01, /* 1280x960 (guessed) */ + 0x01,0x01,0x01, /* 1152x768 (unknown) */ + 0x01,0x01,0x01, /* 1400x1050 */ + 0x01,0x01,0x01, /* 1280x768 (guessed) */ + 0x01,0x01,0x01, /* 1600x1200 */ + 0x02,0x02,0x02, + 0x02,0x02,0x02, + 0x02,0x02,0x02, + 0x02,0x02,0x02 +}; + +const UCHAR SiS310_LCDDelayCompensation3[] = /* LVDS */ +{ + 0x00,0x00,0x00, /* 800x600 */ + 0x00,0x00,0x00, /* 1024x768 */ + 0x00,0x00,0x00, /* 1280x1024 */ + 0x00,0x00,0x00, /* 640x480 (unknown) */ + 0x00,0x00,0x00, /* 1024x600 (unknown) */ + 0x00,0x00,0x00, /* 1152x864 (unknown) */ + 0x00,0x00,0x00, /* 1280x960 (guessed) */ + 0x00,0x00,0x00, /* 1152x768 (unknown) */ + 0x00,0x00,0x00, /* 1400x1050 */ + 0x00,0x00,0x00, /* 1280x768 (guessed) */ + 0x00,0x00,0x00, /* 1600x1200 */ + 0x00,0x00,0x00, + 0x00,0x00,0x00, + 0x00,0x00,0x00, + 0x00,0x00,0x00 +}; + +const UCHAR SiS310_LCDDelayCompensation4[] = /* 650 */ +{ + 0x01,0x01,0x01, /* 800x600 (guessed)*/ + 0x01,0x01,0x01, /* 1024x768 */ + 0x01,0x01,0x01, /* 1280x1024 */ + 0x01,0x01,0x01, /* 640x480 (unknown) */ + 0x01,0x01,0x01, /* 1024x600 (unknown) */ + 0x01,0x01,0x01, /* 1152x864 (unknown) */ + 0x01,0x01,0x01, /* 1280x960 (guessed) */ + 0x01,0x01,0x01, /* 1152x768 (unknown) */ + 0x01,0x01,0x01, /* 1400x1050 */ + 0x01,0x01,0x01, /* 1280x768 (guessed) */ + 0x01,0x01,0x01, /* 1600x1200 */ + 0x01,0x01,0x01, + 0x01,0x01,0x01, + 0x01,0x01,0x01, + 0x01,0x01,0x01 +}; + +const UCHAR SiS310_LCDDelayCompensation5[] = /* 650 LVX */ +{ + 0x01,0x01,0x01, /* 800x600 (guessed) */ + 0x01,0x01,0x01, /* 1024x768 */ + 0x01,0x01,0x01, /* 1280x1024 */ + 0x01,0x01,0x01, /* 640x480 (unknown) */ + 0x01,0x01,0x01, /* 1024x600 (unknown) */ + 0x01,0x01,0x01, /* 1152x864 (unknown) */ + 0x01,0x01,0x01, /* 1280x960 (guessed) */ + 0x01,0x01,0x01, /* 1152x768 (unknown) */ + 0x01,0x01,0x01, /* 1400x1050 */ + 0x01,0x01,0x01, /* 1280x768 (guessed) */ + 0x01,0x01,0x01, /* 1600x1200 */ + 0x01,0x01,0x01, + 0x01,0x01,0x01, + 0x01,0x01,0x01, + 0x01,0x01,0x01 +}; + +const UCHAR SiS310_LCDDelayCompensation6[] = /* M650/651 */ +{ + 0x33,0x33,0x33, /* 800x600 (guessed) */ + 0x33,0x33,0x33, /* 1024x768 */ + 0x33,0x33,0x33, /* 1280x1024 */ + 0x33,0x33,0x33, /* 640x480 (unknown) */ + 0x33,0x33,0x33, /* 1024x600 (unknown) */ + 0x33,0x33,0x33, /* 1152x864 (unknown) */ + 0x33,0x33,0x33, /* 1280x960 (guessed) */ + 0x33,0x33,0x33, /* 1152x768 (unknown) */ + 0x33,0x33,0x33, /* 1400x1050 */ + 0x33,0x33,0x33, /* 1280x768 (guessed) */ + 0x33,0x33,0x33, /* 1600x1200 */ + 0x33,0x33,0x33, + 0x33,0x33,0x33, + 0x33,0x33,0x33, + 0x33,0x33,0x33 +}; + +const UCHAR SiS310_LCDDelayCompensation7[] = /* M650/651 301LVX */ +{ + 0x33,0x33,0x33, /* 800x600 (guessed) */ + 0x33,0x33,0x33, /* 1024x768 */ + 0x33,0x33,0x33, /* 1280x1024 */ + 0x33,0x33,0x33, /* 640x480 (unknown) */ + 0x33,0x33,0x33, /* 1024x600 (unknown) */ + 0x33,0x33,0x33, /* 1152x864 (unknown) */ + 0x33,0x33,0x33, /* 1280x960 (guessed) */ + 0x33,0x33,0x33, /* 1152x768 (unknown) */ + 0x33,0x33,0x33, /* 1400x1050 */ + 0x33,0x33,0x33, /* 1280x768 (guessed) */ + 0x33,0x33,0x33, /* 1600x1200 */ + 0x33,0x33,0x33, + 0x33,0x33,0x33, + 0x33,0x33,0x33, + 0x33,0x33,0x33 +}; + +const UCHAR SiS310_TVDelayCompensation1[] = /* 301 */ +{ + 0x02,0x02, /* NTSC Enhanced, Standard */ + 0x02,0x02, /* PAL */ + 0x08,0x0b /* HiVision */ +}; + +const UCHAR SiS310_TVDelayCompensation2[] = /* 301B;LV */ +{ + 0x03,0x03, + 0x03,0x03, + 0x03,0x03 +}; + +const UCHAR SiS310_TVDelayCompensation3[] = /* LVDS */ +{ + 0x0a,0x0a, + 0x0a,0x0a, + 0x0a,0x0a +}; + +const UCHAR SiS310_TVDelayCompensation4[] = /* 650 */ +{ + 0x03,0x03, + 0x03,0x03, + 0x03,0x03 +}; + +const UCHAR SiS310_TVDelayCompensation5[] = /* 650 LVX */ +{ + 0x03,0x03, + 0x03,0x03, + 0x03,0x03 +}; + +const UCHAR SiS310_TVDelayCompensation6[] = /* M650, 651 */ +{ + 0x33,0x33, + 0x33,0x33, + 0x33,0x33 +}; + +const UCHAR SiS310_TVDelayCompensation7[] = /* M650, 651, LVX */ +{ + 0x33,0x33, + 0x33,0x33, + 0x33,0x33 +}; + +const UCHAR SiS310_TVAntiFlick1[3][2] = +{ + {0x4,0x0}, + {0x4,0x8}, + {0x0,0x0} +}; + +const UCHAR SiS310_TVEdge1[3][2] = +{ + {0x0,0x4}, + {0x0,0x4}, + {0x0,0x0} +}; + +const UCHAR SiS310_TVYFilter1[3][8][4] = +{ + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xf1,0x04,0x1f,0x18}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xee,0x0c,0x22,0x08}, + {0xeb,0x15,0x25,0xf6} + }, + { + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x1f,0x32}, + {0xf3,0x00,0x1d,0x20}, + {0x00,0xf4,0x10,0x38}, + {0xf1,0xf7,0x1f,0x32}, + {0xf3,0x00,0x1d,0x20}, + {0xfc,0xfb,0x14,0x2a} + }, + { + {0x00,0x00,0x00,0x00}, + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xf7,0x06,0x19,0x14}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xee,0x0c,0x22,0x08} + } +}; + +const UCHAR SiS310_TVYFilter2[3][9][7] = +{ + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} + }, + { + {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, + {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, + {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, + {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, + {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, + {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, + {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, + {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22} + } +}; + +const UCHAR SiS310_PALMFilter[16][4] = +{ + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x10,0x18}, + {0xf7,0x06,0x19,0x14}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x15,0x25,0xf6}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18} +}; + +const UCHAR SiS310_PALNFilter[16][4] = +{ + {0x00,0xf4,0x10,0x38}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x10,0x18}, + {0xf7,0x06,0x19,0x14}, + {0x00,0xf4,0x10,0x38}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x15,0x25,0xf6}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18}, + {0xeb,0x04,0x25,0x18} +}; + + +const UCHAR SiS310_PALMFilter2[9][7] = +{ + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} +}; + +const UCHAR SiS310_PALNFilter2[9][7] = +{ + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, + {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, + {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, + {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} +}; + +const UCHAR SiS310_TVPhaseIncr1[3][2][4] = +{ + { + {0x21,0xed,0xba,0x08}, + {0x21,0xed,0xba,0x08} + }, + { + {0x2a,0x05,0xe3,0x00}, + {0x2a,0x05,0xe3,0x00} + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00} + } +}; + +const UCHAR SiS310_TVPhaseIncr2[3][2][4] = +{ + { + {0x21,0xf0,0x7b,0xd6}, /* 1.10.7w; 1.10.6s: {0x1e,0x8b,0xda,0xa7}, old: {0x21,0xF1,0x37,0x56} */ + {0x21,0xf0,0x7b,0xd6} /* 1.10.7w; 1.10.6s: {0x1e,0x8b,0xda,0xa7} old: {0x21,0xF1,0x37,0x56} */ + }, + { + {0x2a,0x0a,0x41,0xe9}, /* 1.10.7w, 1.10.6s. old: {0x2a,0x09,0x86,0xe9}, */ + {0x2a,0x0a,0x41,0xe9} /* 1.10.7w, 1.10.6s. old: {0x2a,0x09,0x86,0xe9} */ + }, + { + {0x2a,0x05,0xd3,0x00}, + {0x2a,0x05,0xd3,0x00} + } +}; + + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h new file mode 100644 index 000000000..039d968b9 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h @@ -0,0 +1,169 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/osdef.h,v 1.2 2003/02/10 01:14:16 tsi Exp $ */ + +/* OS depending defines */ + +/* The choices are: */ +/* #define WINCE_HEADER */ /* Incomplete! */ +/* #define WIN2000 */ /* Incomplete! */ +/* #define TC */ /* Incomplete! */ +/* #define LINUX_KERNEL */ /* Kernel framebuffer */ +#define LINUX_XF86 /* XFree86 */ + +/**********************************************************************/ +#ifdef LINUX_KERNEL /* ----------------------------*/ + +#include <linux/config.h> +#ifdef CONFIG_FB_SIS_300 +#define SIS300 +#endif + +#ifdef CONFIG_FB_SIS_315 +#define SIS315H +#endif + +#else /* if not LINUX_KERNEL --------------------- */ +/* #define SIS300*/ +#define SIS315H + +#endif /* if LINUX_KERNEL ------------------------ */ + +#ifdef LINUX_XF86 /* Linux Xfree86 ---------------- */ + +#define SIS300 +/* #define SIS315H */ /* TW: done above */ +#endif + +/**********************************************************************/ +#ifdef TC +#endif +#ifdef WIN2000 +#endif +#ifdef WINCE_HEADER +#endif +#ifdef LINUX_XF86 +#endif +#ifdef LINUX_KERNEL +#endif +/**********************************************************************/ +#ifdef TC +#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize); +#endif +#ifdef WIN2000 +#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value); +#endif +#ifdef WINCE_HEADER +#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize); +#endif +#ifdef LINUX_XF86 +#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize) +#endif +#ifdef LINUX_KERNEL +#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize) +#endif +/**********************************************************************/ + +/**********************************************************************/ + +#ifdef TC +#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length); +#endif +#ifdef WIN2000 +#define SiS_MemoryCopy(Destination,Soruce,Length) /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/ +#endif +#ifdef WINCE_HEADER +#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length); +#endif +#ifdef LINUX_XF86 +#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length) +#endif +#ifdef LINUX_KERNEL +#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length) +#endif + +/**********************************************************************/ + +#ifdef OutPortByte +#undef OutPortByte +#endif /* OutPortByte */ + +#ifdef OutPortWord +#undef OutPortWord +#endif /* OutPortWord */ + +#ifdef OutPortLong +#undef OutPortLong +#endif /* OutPortLong */ + +#ifdef InPortByte +#undef InPortByte +#endif /* InPortByte */ + +#ifdef InPortWord +#undef InPortWord +#endif /* InPortWord */ + +#ifdef InPortLong +#undef InPortLong +#endif /* InPortLong */ + +/**********************************************************************/ +/* TC */ +/**********************************************************************/ + +#ifdef TC +#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v)) +#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v)) +#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v)) +#define InPortByte(p) inp((unsigned short)(p)) +#define InPortWord(p) inp((unsigned short)(p)) +#define InPortLong(p) ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p))) +#endif + +/**********************************************************************/ +/* LINUX XF86 */ +/**********************************************************************/ + +#ifdef LINUX_XF86 +#define OutPortByte(p,v) outb((CARD16)(p),(CARD8)(v)) +#define OutPortWord(p,v) outw((CARD16)(p),(CARD16)(v)) +#define OutPortLong(p,v) outl((CARD16)(p),(CARD32)(v)) +#define InPortByte(p) inb((CARD16)(p)) +#define InPortWord(p) inw((CARD16)(p)) +#define InPortLong(p) inl((CARD16)(p)) +#endif + +#ifdef LINUX_KERNEL +#define OutPortByte(p,v) outb((u8)(v),(u16)(p)) +#define OutPortWord(p,v) outw((u16)(v),(u16)(p)) +#define OutPortLong(p,v) outl((u32)(v),(u16)(p)) +#define InPortByte(p) inb((u16)(p)) +#define InPortWord(p) inw((u16)(p)) +#define InPortLong(p) inl((u16)(p)) +#endif + +/**********************************************************************/ +/* WIN 2000 */ +/**********************************************************************/ + +#ifdef WIN2000 +#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v)) +#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v)) +#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v)) +#define InPortByte(p) VideoPortReadPortUchar ((PUCHAR) (p)) +#define InPortWord(p) VideoPortReadPortUshort ((PUSHORT) (p)) +#define InPortLong(p) VideoPortReadPortUlong ((PULONG) (p)) +#endif + + +/**********************************************************************/ +/* WIN CE */ +/**********************************************************************/ + +#ifdef WINCE_HEADER +#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v)) +#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v)) +#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v)) +#define InPortByte(p) READ_PORT_UCHAR ((PUCHAR) (p)) +#define InPortWord(p) READ_PORT_USHORT ((PUSHORT) (p)) +#define InPortLong(p) READ_PORT_ULONG ((PULONG) (p)) +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c new file mode 100644 index 000000000..aeee2737d --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c @@ -0,0 +1,894 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c,v 1.2 2003/01/29 15:42:16 eich Exp $ */ +/* + * 2D Acceleration for SiS 310/325 series (315, 550, 650, 740, M650, 651) + * + * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * + * 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 Thomas Winischhofer not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Thomas Winischhofer makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THOMAS WINISCHHOFER 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. + * + * Based on sis300_accel.c + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "compiler.h" +#include "xaa.h" + +#include "sis.h" +#include "sis310_accel.h" + +#ifdef SISDUALHEAD +/* TW: This is the offset to the memory for each head */ +#define HEADOFFSET (pSiS->dhmOffset) +#endif + +#undef TRAP /* TW: Use/Don't use Trapezoid Fills - does not work - XAA provides + * illegal trapezoid data (left and right edges cross each other + * sometimes) which causes drawing errors. + */ + +#define CTSCE /* Use/Don't use CPUToScreenColorExpand. */ + +/* Accelerator functions */ +static void SiSInitializeAccelerator(ScrnInfoPtr pScrn); +static void SiSSync(ScrnInfoPtr pScrn); +static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int trans_color); +static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, + int width, int height); +static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h); +#ifdef TRAP +static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR); +#endif +static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, + int y1, int x2, int y2, int flags); +static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn, + int x, int y, int len, int dir); +static void SiSSetupForDashedLine(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask, + int length, unsigned char *pattern); +static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, + int flags, int phase); +static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn, + int patx, int paty, int fg, int bg, + int rop, unsigned int planemask); +static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h); +#ifdef TRAP +static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, + int patx, int paty, + int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR); +#endif +#ifdef CTSCE +static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask); +static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int skipleft); +static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); +#endif + +#ifdef SISDUALHEAD +static void SiSRestoreAccelState(ScrnInfoPtr pScrn); +#endif + +static void +SiSInitializeAccelerator(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + pSiS->DoColorExpand = FALSE; +} + +Bool +SiS310AccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + int topFB; + int reservedFbSize; + int UsableFbSize; + unsigned char *AvailBufBase; + BoxRec Avail; + int i; + + pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec(); + if (!infoPtr) + return FALSE; + + SiSInitializeAccelerator(pScrn); + + infoPtr->Flags = LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS | + PIXMAP_CACHE; + + /* sync */ + infoPtr->Sync = SiSSync; + + if ((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) && + (pScrn->bitsPerPixel != 32)) + return FALSE; + + /* BitBlt */ + infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; + infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | TRANSPARENCY_GXCOPY_ONLY; + /*| NO_TRANSPARENCY; */ + + /* solid fills */ + infoPtr->SetupForSolidFill = SiSSetupForSolidFill; + infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect; +#ifdef TRAP + infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap; +#endif + infoPtr->SolidFillFlags = NO_PLANEMASK; + + /* solid line */ + infoPtr->SetupForSolidLine = SiSSetupForSolidLine; + infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; + infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine; + infoPtr->SolidLineFlags = NO_PLANEMASK; + + /* dashed line */ + infoPtr->SetupForDashedLine = SiSSetupForDashedLine; + infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine; + infoPtr->DashPatternMaxLength = 64; + infoPtr->DashedLineFlags = NO_PLANEMASK | + LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; + + /* 8x8 mono pattern fill */ + infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill; +#ifdef TRAP + infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap; +#endif + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS | + NO_TRANSPARENCY | + BIT_ORDER_IN_BYTE_MSBFIRST ; + +#if 0 + /* Screen To Screen Color Expand */ + /* TW: The hardware does not seem to support this the way we need it */ + infoPtr->SetupForScreenToScreenColorExpandFill = + SiSSetupForScreenToScreenColorExpand; + infoPtr->SubsequentScreenToScreenColorExpandFill = + SiSSubsequentScreenToScreenColorExpand; + infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST ; +#endif + + /* per-scanline color expansion - indirect method */ + pSiS->ColorExpandBufferNumber = 16; + pSiS->ColorExpandBufferCountMask = 0x0F; + pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4; +#ifdef CTSCE + infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; + infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0]; + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline; + infoPtr->ScanlineCPUToScreenColorExpandFillFlags = + NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING; +#endif + +#ifdef SISDUALHEAD + if (pSiS->DualHeadMode) { + infoPtr->RestoreAccelState = SiSRestoreAccelState; + } +#endif + + /* init Frame Buffer Manager */ + + topFB = pSiS->maxxfbmem; + + reservedFbSize = (pSiS->ColorExpandBufferNumber + * pSiS->PerColorExpandBufferSize); + /* TW: New for MaxXFBmem Option */ + UsableFbSize = topFB - reservedFbSize; + /* Layout: + * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~| + * UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue + * topFB + */ + AvailBufBase = pSiS->FbBase + UsableFbSize; + for (i = 0; i < pSiS->ColorExpandBufferNumber; i++) { + pSiS->ColorExpandBufferAddr[i] = AvailBufBase + + i * pSiS->PerColorExpandBufferSize; + pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize + + i * pSiS->PerColorExpandBufferSize; + } + Avail.x1 = 0; + Avail.y1 = 0; + Avail.x2 = pScrn->displayWidth; + Avail.y2 = UsableFbSize + / (pScrn->displayWidth * pScrn->bitsPerPixel/8) - 1; + if (Avail.y2 < 0) + Avail.y2 = 32767; + if (Avail.y2 < pScrn->currentMode->VDisplay) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Not enough video RAM for accelerator. At least " + "%dKB needed, %dKB available\n", + ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */ + * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8, + pSiS->maxxfbmem/1024); + pSiS->NoAccel = TRUE; + pSiS->NoXvideo = TRUE; + XAADestroyInfoRec(pSiS->AccelInfoPtr); + pSiS->AccelInfoPtr = NULL; + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Frame Buffer From (%d,%d) To (%d,%d)\n", + Avail.x1, Avail.y1, Avail.x2, Avail.y2); + + xf86InitFBManager(pScreen, &Avail); + + return(XAAInit(pScreen, infoPtr)); +} + +static void +SiSSync(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + PDEBUG(ErrorF("SiSSync()\n")); + + pSiS->DoColorExpand = FALSE; + SiSIdle +} + +#ifdef SISDUALHEAD +static void +SiSRestoreAccelState(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + /* TW: We don't need to do anything special here */ + pSiS->DoColorExpand = FALSE; + SiSIdle +} +#endif + +static const int sisALUConv[] = +{ + 0x00, /* dest = 0; 0, GXclear, 0 */ + 0x88, /* dest &= src; DSa, GXand, 0x1 */ + 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */ + 0xCC, /* dest = src; S, GXcopy, 0x3 */ + 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */ + 0xAA, /* dest = dest; D, GXnoop, 0x5 */ + 0x66, /* dest = ^src; DSx, GXxor, 0x6 */ + 0xEE, /* dest |= src; DSo, GXor, 0x7 */ + 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */ + 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */ + 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ + 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */ + 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */ + 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */ + 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */ + 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ +}; +/* same ROP but with Pattern as Source */ +static const int sisPatALUConv[] = +{ + 0x00, /* dest = 0; 0, GXclear, 0 */ + 0xA0, /* dest &= src; DPa, GXand, 0x1 */ + 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */ + 0xF0, /* dest = src; P, GXcopy, 0x3 */ + 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */ + 0xAA, /* dest = dest; D, GXnoop, 0x5 */ + 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */ + 0xFA, /* dest |= src; DPo, GXor, 0x7 */ + 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */ + 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */ + 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ + 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */ + 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */ + 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */ + 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */ + 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ +}; + +static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, int trans_color) +{ + SISPtr pSiS = SISPTR(pScrn); + + PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n", + xdir, ydir, rop, planemask, trans_color)); + + /* "AGP base" - color depth depending value (see sis_vga.c) */ + SiSSetupDSTColorDepth(pSiS->DstColor); + /* SRC pitch */ + SiSSetupSRCPitch(pSiS->scrnOffset) + /* DST pitch and height (-1 for disabling merge-clipping) */ + SiSSetupDSTRect(pSiS->scrnOffset, -1) + /* Init CommandReg and set ROP */ + if (trans_color != -1) { + SiSSetupROP(0x0A) + SiSSetupSRCTrans(trans_color) + SiSSetupCMDFlag(TRANSPARENT_BITBLT) + } else { + SiSSetupROP(sisALUConv[rop]) + /* Set command - not needed, both 0 */ + /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */ + } + /* Set some color depth depending value (see sis_vga.c) */ + SiSSetupCMDFlag(pSiS->SiS310_AccelDepth) + + /* TW: The 310/325 series is smart enough to know the direction */ +} + +static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int src_x, int src_y, int dst_x, int dst_y, + int width, int height) +{ + SISPtr pSiS = SISPTR(pScrn); + long srcbase, dstbase; + + PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n", + src_x, src_y, dst_x, dst_y, width, height)); + + srcbase = dstbase = 0; + if (src_y >= 2048) { + srcbase = pSiS->scrnOffset * src_y; + src_y = 0; + } + if ((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) { + dstbase = pSiS->scrnOffset*dst_y; + dst_y = 0; + } +#ifdef SISDUALHEAD + srcbase += HEADOFFSET; + dstbase += HEADOFFSET; +#endif + SiSSetupSRCBase(srcbase); + SiSSetupDSTBase(dstbase); + SiSSetupRect(width, height) + SiSSetupSRCXY(src_x, src_y) + SiSSetupDSTXY(dst_x, dst_y) + SiSDoCMD +} + +static void +SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + SISPtr pSiS = SISPTR(pScrn); + + PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n", + color, rop, planemask)); + + SiSSetupPATFG(color) + SiSSetupDSTRect(pSiS->scrnOffset, -1) + SiSSetupDSTColorDepth(pSiS->DstColor); + SiSSetupROP(sisPatALUConv[rop]) + SiSSetupCMDFlag(PATFG | pSiS->SiS310_AccelDepth) +} + +static void +SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; + + PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n", + x, y, w, h)); + dstbase = 0; + if (y >= 2048) { + dstbase=pSiS->scrnOffset*y; + y = 0; + } +#ifdef SISDUALHEAD + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + SiSSetupDSTXY(x,y) + SiSSetupRect(w,h) + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + TRAPAZOID_FILL); + SiSSetupCMDFlag(BITBLT) + SiSDoCMD +} + +/* TW: Trapezoid */ +/* This would work better if XAA would provide us with valid trapezoids. + * In fact, with small trapezoids the left and the right edge often cross + * each other which causes drawing errors (filling over whole scanline). + */ +#ifdef TRAP +static void +SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR ) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; +#if 0 + float kL, kR; +#endif + + dstbase = 0; + if (y >= 2048) { + dstbase=pSiS->scrnOffset*y; + y = 0; + } +#ifdef SISDUALHEAD + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + +#if 1 + SiSSetupPATFG(0xff0000) /* FOR TESTING */ +#endif + + /* Clear CommandReg because SetUp can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + T_XISMAJORL | T_XISMAJORR | + BITBLT); + + xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n", + left, right, y, h, dxL, dyL, eL, dxR, dyR, eR); + + /* Unfortunately, we must check if the right and the left edge + * cross each other... INCOMPLETE (equation wrong) + */ +#if 0 + if (dxL == 0) kL = 0; + else kL = (float)dyL / (float)dxL; + if (dxR == 0) kR = 0; + else kR = (float)dyR / (float)dxR; + xf86DrvMsg(0, X_INFO, "kL %f kR %f!\n", kL, kR); + if ( (kR != kL) && + (!(kR == 0 && kL == 0)) && + (!(kR < 0 && kL > 0)) ) { + xf86DrvMsg(0, X_INFO, "Inside if (%f - %d)\n", ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - left) + y), h+y); + if ( ( ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - (float)left) + (float)y) < (h + y) ) ) { + xf86DrvMsg(0, X_INFO, "Cross detected!\n"); + } + } +#endif + + /* Determine egde angles */ + if (dxL < 0) { dxL = -dxL; } + else { SiSSetupCMDFlag(T_L_X_INC) } + if (dxR < 0) { dxR = -dxR; } + else { SiSSetupCMDFlag(T_R_X_INC) } + + /* (Y direction always positive - do this anyway) */ + if (dyL < 0) { dyL = -dyL; } + else { SiSSetupCMDFlag(T_L_Y_INC) } + if (dyR < 0) { dyR = -dyR; } + else { SiSSetupCMDFlag(T_R_Y_INC) } + + /* Determine major axis */ + if (dxL >= dyL) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORL) + } + if (dxR >= dyR) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORR) + } + + /* Set up deltas */ + SiSSetupdL(dxL, dyL) + SiSSetupdR(dxR, dyR) + + /* Set up y, h, left, right */ + SiSSetupYH(y,h) + SiSSetupLR(left,right) + + /* Set up initial error term */ + SiSSetupEL(eL) + SiSSetupER(eR) + + SiSSetupCMDFlag(TRAPAZOID_FILL); + + SiSDoCMD +} +#endif + +static void +SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) +{ + SISPtr pSiS = SISPTR(pScrn); + + PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n", + color, rop, planemask)); + + SiSSetupLineCount(1) + SiSSetupPATFG(color) + SiSSetupDSTRect(pSiS->scrnOffset, -1) + SiSSetupDSTColorDepth(pSiS->DstColor); + SiSSetupROP(sisPatALUConv[rop]) + SiSSetupCMDFlag(PATFG | LINE | pSiS->SiS310_AccelDepth) +} + +static void +SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, int flags) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase,miny,maxy; + + PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n", + x1, y1, x2, y2, flags)); + + dstbase = 0; + miny = (y1 > y2) ? y2 : y1; + maxy = (y1 > y2) ? y1 : y2; + if (maxy >= 2048) { + dstbase = pSiS->scrnOffset*miny; + y1 -= miny; + y2 -= miny; + } +#ifdef SISDUALHEAD + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + + SiSSetupX0Y0(x1,y1) + SiSSetupX1Y1(x2,y2) + if (flags & OMIT_LAST) { + SiSSetupCMDFlag(NO_LAST_PIXEL) + } else { + pSiS->CommandReg &= ~(NO_LAST_PIXEL); + } + SiSDoCMD +} + +static void +SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn, + int x, int y, int len, int dir) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; + + PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n", + x, y, len, dir)); + + len--; /* starting point is included! */ + dstbase = 0; + if ((y >= 2048) || ((y + len) >= 2048)) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + + SiSSetupX0Y0(x,y) + if (dir == DEGREES_0) { + SiSSetupX1Y1(x + len, y); + } else { + SiSSetupX1Y1(x, y + len); + } + SiSDoCMD +} + +static void +SiSSetupForDashedLine(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask, + int length, unsigned char *pattern) +{ + SISPtr pSiS = SISPTR(pScrn); + + PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n", + fg, bg, rop, planemask, length, *(pattern+4), *pattern)); + + SiSSetupLineCount(1) + SiSSetupDSTRect(pSiS->scrnOffset, -1) + SiSSetupDSTColorDepth(pSiS->DstColor); + SiSSetupStyleLow(*pattern) + SiSSetupStyleHigh(*(pattern+4)) + SiSSetupStylePeriod(length-1); /* TW: This was missing!!! */ + SiSSetupROP(sisPatALUConv[rop]) + SiSSetupPATFG(fg) + SiSSetupCMDFlag(LINE | LINE_STYLE) /* TW: This was missing!!! */ + if (bg != -1) { + SiSSetupPATBG(bg) + } else { + SiSSetupCMDFlag(TRANSPARENT) /* TW: This was missing!!! */ + } + SiSSetupCMDFlag(pSiS->SiS310_AccelDepth) +} + +static void +SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, + int x1, int y1, int x2, int y2, + int flags, int phase) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase,miny,maxy; + + PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n", + x1, y1, x2, y2, flags, phase)); + + dstbase = 0; + miny=(y1 > y2) ? y2 : y1; + maxy=(y1 > y2) ? y1 : y2; + if (maxy >= 2048) { + dstbase = pSiS->scrnOffset * miny; + y1 -= miny; + y2 -= miny; + } +#ifdef SISDUALHEAD + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + + SiSSetupX0Y0(x1,y1) + SiSSetupX1Y1(x2,y2) + if (flags & OMIT_LAST) { + SiSSetupCMDFlag(NO_LAST_PIXEL) + } else { + pSiS->CommandReg &= ~(NO_LAST_PIXEL); + } + SiSDoCMD +} + +static void +SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn, + int patx, int paty, int fg, int bg, + int rop, unsigned int planemask) +{ + SISPtr pSiS = SISPTR(pScrn); + + PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n", + patx, paty, fg, bg, rop, planemask)); + SiSSetupDSTRect(pSiS->scrnOffset, -1) + SiSSetupDSTColorDepth(pSiS->DstColor); + SiSSetupMONOPAT(patx,paty) + SiSSetupPATFG(fg) + SiSSetupROP(sisPatALUConv[rop]) + SiSSetupCMDFlag(PATMONO | pSiS->SiS310_AccelDepth) + SiSSetupPATBG(bg) +} + +static void +SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; + + PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n", + patx, paty, x, y, w, h)); + dstbase = 0; + if (y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + SiSSetupDSTXY(x,y) + SiSSetupRect(w,h) + /* Clear commandReg because Setup can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + TRAPAZOID_FILL); + SiSDoCMD +} + +/* TW: Trapezoid */ +#ifdef TRAP +static void +SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, + int patx, int paty, + int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; + + PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n", + y, h, left, right, dxL, dxR, eL, eR)); + + dstbase = 0; + if (y >= 2048) { + dstbase=pSiS->scrnOffset*y; + y = 0; + } +#ifdef SISDUALHEAD + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + + /* Clear CommandReg because SetUp can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + BITBLT); + + if (dxL < 0) { dxL = -dxL; } + else { SiSSetupCMDFlag(T_L_X_INC) } + if (dxR < 0) { dxR = -dxR; } + else { SiSSetupCMDFlag(T_R_X_INC) } + + if (dyL < 0) { dyL = -dyL; } + else { SiSSetupCMDFlag(T_L_Y_INC) } + if (dyR < 0) { dyR = -dyR; } + else { SiSSetupCMDFlag(T_R_Y_INC) } + + /* Determine major axis */ + if (dxL >= dyL) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORL) + } + if (dxR >= dyR) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORR) + } + + SiSSetupYH(y,h) + SiSSetupLR(left,right) + + SiSSetupdL(dxL, dyL) + SiSSetupdR(dxR, dyR) + + SiSSetupEL(eL) + SiSSetupER(eR) + + SiSSetupCMDFlag(TRAPAZOID_FILL); + + SiSDoCMD +} +#endif + +/* ---- CPUToScreen Color Expand */ + +#ifdef CTSCE +/* We use the indirect method */ +static void +SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask) +{ + SISPtr pSiS=SISPTR(pScrn); + + /* TW: FIXME: How do I check the "CPU driven blit stage" on the + * 310/325 series? + * That's the 300 series method but definitely wrong for + * 310/325 series (bit 28 is already used for idle!) + */ + /* while ((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x1F00) != 0) {} */ + + /* TW: Do Idle instead... */ + SiSIdle + + SiSSetupSRCXY(0,0); + SiSSetupROP(sisALUConv[rop]); + SiSSetupSRCFG(fg); + SiSSetupDSTRect(pSiS->scrnOffset, -1); + SiSSetupDSTColorDepth(pSiS->DstColor); + if (bg == -1) { + SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF + | pSiS->SiS310_AccelDepth); + } else { + SiSSetupSRCBG(bg); + SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF + | pSiS->SiS310_AccelDepth); + }; +} + +static void +SiSSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, int y, int w, + int h, int skipleft) +{ + SISPtr pSiS = SISPTR(pScrn); + int _x0, _y0, _x1, _y1; + long dstbase; + + dstbase = 0; + if (y >= 2048) { + dstbase = pSiS->scrnOffset*y; + y = 0; + } +#ifdef SISDUALHEAD + dstbase += HEADOFFSET; +#endif + + if((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) { + SiSIdle; + } + + SiSSetupDSTBase(dstbase) + + if (skipleft > 0) { + _x0 = x+skipleft; + _y0 = y; + _x1 = x+w; + _y1 = y+h; + SiSSetupClipLT(_x0, _y0); + SiSSetupClipRB(_x1, _y1); + SiSSetupCMDFlag(CLIPENABLE); + } else { + pSiS->CommandReg &= (~CLIPENABLE); + } + SiSSetupRect(w, 1); + SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4); + pSiS->ycurrent = y; + pSiS->xcurrent = x; +} + +static void +SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + SISPtr pSiS=SISPTR(pScrn); + long cbo; + + cbo = pSiS->ColorExpandBufferScreenOffset[bufno]; +#ifdef SISDUALHEAD + cbo += HEADOFFSET; +#endif + + if((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) { + SiSIdle; + } + + SiSSetupSRCBase(cbo); + + SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent); + + SiSDoCMD + + pSiS->ycurrent++; + + SiSIdle +} +#endif + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h new file mode 100644 index 000000000..9a6b20a82 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h @@ -0,0 +1,341 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.h,v 1.2 2003/01/29 15:42:16 eich Exp $ */ +/* + * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * + * 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 Thomas Winischhofer not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Thomas Winischhofer makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THOMAS WINISCHHOFER 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. + * + * Based on sis300_accel.h + * + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + */ + +/* Definitions for the SIS engine communication. */ + + +/* SiS310 engine commands */ +#define BITBLT 0x00000000 /* Blit */ +#define COLOREXP 0x00000001 /* Color expand */ +#define ENCOLOREXP 0x00000002 /* Enhanced color expand */ +#define MULTIPLE_SCANLINE 0x00000003 /* ? */ +#define LINE 0x00000004 /* Draw line */ +#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */ +#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */ +#define ALPHA_BLEND 0x00000007 /* Alpha blend ? */ +#define A3D_FUNCTION 0x00000008 /* 3D command ? */ +#define CLEAR_Z_BUFFER 0x00000009 /* ? */ +#define GRADIENT_FILL 0x0000000A /* Gradient fill */ +#define STRETCH_BITBLT 0x0000000B /* Stretched Blit */ + +/* Command bits */ + +/* Source selection */ +#define SRCVIDEO 0x00000000 /* source is video RAM */ +#define SRCSYSTEM 0x00000010 /* source is system memory */ +#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */ +#define SRCAGP 0x00000020 /* source is AGP memory (?) */ + +/* Pattern source selection */ +#define PATFG 0x00000000 /* foreground color */ +#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */ +#define PATMONO 0x00000080 /* mono pattern */ + +/* Clipping flags */ +#define NOCLIP 0x00000000 +#define NOMERGECLIP 0x04000000 +#define CLIPENABLE 0x00040000 +#define CLIPWITHOUTMERGE 0x04040000 + +/* Transparency */ +#define OPAQUE 0x00000000 +#define TRANSPARENT 0x00100000 + +/* ? */ +#define DSTAGP 0x02000000 +#define DSTVIDEO 0x02000000 + +/* Subfunctions for Color/Enhanced Color Expansion */ +#define COLOR_TO_MONO 0x00100000 +#define AA_TEXT 0x00200000 + +/* Line */ +#define LINE_STYLE 0x00800000 +#define NO_RESET_COUNTER 0x00400000 +#define NO_LAST_PIXEL 0x00200000 + +/* Trapezoid */ +#define T_XISMAJORL 0x00800000 /* X axis is driving axis (left) */ +#define T_XISMAJORR 0x08000000 /* X axis is driving axis (right) */ +#define T_L_Y_INC 0x00000020 /* left edge direction Y */ +#define T_L_X_INC 0x00000010 /* left edge direction X */ +#define T_R_Y_INC 0x00400000 /* right edge direction Y */ +#define T_R_X_INC 0x00200000 /* right edge direction X */ + +/* Some general registers */ +#define SRC_ADDR 0x8200 +#define SRC_PITCH 0x8204 +#define AGP_BASE 0x8206 /* color-depth dependent value */ +#define SRC_Y 0x8208 +#define SRC_X 0x820A +#define DST_Y 0x820C +#define DST_X 0x820E +#define DST_ADDR 0x8210 +#define DST_PITCH 0x8214 +#define DST_HEIGHT 0x8216 +#define RECT_WIDTH 0x8218 +#define RECT_HEIGHT 0x821A +#define PAT_FGCOLOR 0x821C +#define PAT_BGCOLOR 0x8220 +#define SRC_FGCOLOR 0x8224 +#define SRC_BGCOLOR 0x8228 +#define MONO_MASK 0x822C +#define LEFT_CLIP 0x8234 +#define TOP_CLIP 0x8236 +#define RIGHT_CLIP 0x8238 +#define BOTTOM_CLIP 0x823A +#define COMMAND_READY 0x823C +#define FIRE_TRIGGER 0x8240 + +#define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */ + +/* Line registers */ +#define LINE_X0 SRC_Y +#define LINE_X1 DST_Y +#define LINE_Y0 SRC_X +#define LINE_Y1 DST_X +#define LINE_COUNT RECT_WIDTH +#define LINE_STYLE_PERIOD RECT_HEIGHT +#define LINE_STYLE_0 MONO_MASK +#define LINE_STYLE_1 0x8230 +#define LINE_XN PATTERN_REG +#define LINE_YN PATTERN_REG+2 + +/* Transparent bitblit registers */ +#define TRANS_DST_KEY_HIGH PAT_FGCOLOR +#define TRANS_DST_KEY_LOW PAT_BGCOLOR +#define TRANS_SRC_KEY_HIGH SRC_FGCOLOR +#define TRANS_SRC_KEY_LOW SRC_BGCOLOR + +/* Trapezoid registers */ +#define TRAP_YH SRC_Y /* 0x8208 */ +#define TRAP_LR DST_Y /* 0x820C */ +#define TRAP_DL 0x8244 +#define TRAP_DR 0x8248 +#define TRAP_EL 0x824C +#define TRAP_ER 0x8250 + +/* Queue */ +#define Q_BASE_ADDR 0x85C0 /* Base address of software queue (?) */ +#define Q_WRITE_PTR 0x85C4 /* Current write pointer (?) */ +#define Q_READ_PTR 0x85C8 /* Current read pointer (?) */ +#define Q_STATUS 0x85CC /* queue status */ + +/* Macros to do useful things with the SIS 310 BitBLT engine */ + +/* Q_STATUS: + bit 31 = 1: All engines idle and all queues empty + bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty + bit 29 = 1: 2D engine is idle + bit 28 = 1: 3D engine is idle + bit 27 = 1: HW command queue empty + bit 26 = 1: 2D queue empty + bit 25 = 1: 3D queue empty + bit 24 = 1: SW command queue empty + bits 23:16: 2D counter 3 + bits 15:8: 2D counter 2 + bits 7:0: 2D counter 1 + + Where is the command queue length (current amount of commands the queue + can accept) on the 310 series? (The current implementation is taken + from 300 series and certainly wrong...) +*/ + +int CmdQueLen; + +/* TW: FIXME: CmdQueLen is... where....? */ +#define SiSIdle \ + { \ + while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ + while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ + CmdQueLen=MMIO_IN16(pSiS->IOBase, Q_STATUS); \ + } + /* TW: (do twice like on 300 series?) */ + +#define SiSSetupSRCBase(base) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, SRC_ADDR, base);\ + CmdQueLen--; + +#define SiSSetupSRCPitch(pitch) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT16(pSiS->IOBase, SRC_PITCH, pitch);\ + CmdQueLen--; + +#define SiSSetupSRCXY(x,y) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, SRC_Y, (x)<<16 | (y) );\ + CmdQueLen--; + +#define SiSSetupDSTBase(base) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, DST_ADDR, base);\ + CmdQueLen--; + +#define SiSSetupDSTXY(x,y) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, DST_Y, (x)<<16 | (y) );\ + CmdQueLen--; + +#define SiSSetupDSTRect(x,y) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, DST_PITCH, (y)<<16 | (x) );\ + CmdQueLen--; + +#define SiSSetupDSTColorDepth(bpp) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT16(pSiS->IOBase, AGP_BASE, bpp);\ + CmdQueLen--; + +#define SiSSetupRect(w,h) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, RECT_WIDTH, (h)<<16 | (w) );\ + CmdQueLen--; + +#define SiSSetupPATFG(color) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, PAT_FGCOLOR, color);\ + CmdQueLen--; + +#define SiSSetupPATBG(color) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, PAT_BGCOLOR, color);\ + CmdQueLen--; + +#define SiSSetupSRCFG(color) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, SRC_FGCOLOR, color);\ + CmdQueLen--; + +#define SiSSetupSRCBG(color) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, SRC_BGCOLOR, color);\ + CmdQueLen--; + +#define SiSSetupSRCTrans(color) \ + if (CmdQueLen <= 1) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, TRANS_SRC_KEY_HIGH, color);\ + MMIO_OUT32(pSiS->IOBase, TRANS_SRC_KEY_LOW, color);\ + CmdQueLen -= 2; + +#define SiSSetupDSTTrans(color) \ + if (CmdQueLen <= 1) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, TRANS_DST_KEY_HIGH, color); \ + MMIO_OUT32(pSiS->IOBase, TRANS_DST_KEY_LOW, color); \ + CmdQueLen -= 2; + +#define SiSSetupMONOPAT(p0,p1) \ + if (CmdQueLen <= 1) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, MONO_MASK, p0);\ + MMIO_OUT32(pSiS->IOBase, MONO_MASK+4, p1);\ + CmdQueLen=CmdQueLen-2; + +#define SiSSetupClipLT(left,top) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\ + CmdQueLen--; + +#define SiSSetupClipRB(right,bottom) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\ + CmdQueLen--; + +#define SiSSetupROP(rop) \ + pSiS->CommandReg = (rop) << 8; + +#define SiSSetupCMDFlag(flags) \ + pSiS->CommandReg |= (flags); + +#define SiSDoCMD \ + if (CmdQueLen <= 1) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, COMMAND_READY, pSiS->CommandReg); \ + MMIO_OUT32(pSiS->IOBase, FIRE_TRIGGER, 0); \ + CmdQueLen=CmdQueLen-2; + +#define SiSSetupX0Y0(x,y) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, LINE_X0, (y)<<16 | (x) );\ + CmdQueLen--; + +#define SiSSetupX1Y1(x,y) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, LINE_X1, (y)<<16 | (x) );\ + CmdQueLen--; + +#define SiSSetupLineCount(c) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT16(pSiS->IOBase, LINE_COUNT, c);\ + CmdQueLen--; + +#define SiSSetupStylePeriod(p) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT16(pSiS->IOBase, LINE_STYLE_PERIOD, p);\ + CmdQueLen--; + +#define SiSSetupStyleLow(ls) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, LINE_STYLE_0, ls);\ + CmdQueLen--; + +#define SiSSetupStyleHigh(ls) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, LINE_STYLE_1, ls);\ + CmdQueLen--; + +/* Trapezoid */ +#define SiSSetupYH(y,h) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, TRAP_YH, (y)<<16 | (h) );\ + CmdQueLen --; + +#define SiSSetupLR(left,right) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, TRAP_LR, (right)<<16 | (left) );\ + CmdQueLen --; + +#define SiSSetupdL(dxL,dyL) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, TRAP_DL, (dyL)<<16 | (dxL) );\ + CmdQueLen --; + +#define SiSSetupdR(dxR,dyR) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, TRAP_DR, (dyR)<<16 | (dxR) );\ + CmdQueLen --; + +#define SiSSetupEL(eL) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, TRAP_EL, eL);\ + CmdQueLen --; + +#define SiSSetupER(eR) \ + if (CmdQueLen <= 0) SiSIdle;\ + MMIO_OUT32(pSiS->IOBase, TRAP_ER, eR);\ + CmdQueLen --; + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c new file mode 100644 index 000000000..f47475526 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c @@ -0,0 +1,1662 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis6326_video.c,v 1.2 2003/01/29 15:42:16 eich Exp $ */ +/* + * Xv driver for SiS 5597/5598, 6236 and 530/620. + * + * Copyright 2002 by Thomas Winischhofer, Vienna, Austria. + * + * Based on sis_video.c which is + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * Parts Copyright 2002 by Thomas Winischhofer, Vienna, Austria. + * All Rights Reserved. + * + * 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 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 INTEL, AND/OR ITS SUPPLIERS 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. + * + * Author: + * Thomas Winischhofer <thomas@winischhofer.net> + */ + +#include "sis.h" +#ifdef USE6326VIDEO + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "xf86xv.h" +#include "Xv.h" +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" + +#include "sis_regs.h" + +#define OFF_DELAY 200 /* milliseconds */ +#define FREE_DELAY 60000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +#define WATCHDOG_DELAY 500000 /* Watchdog counter for Vertical Restrace waiting */ + +static XF86VideoAdaptorPtr SIS6326SetupImageVideo(ScreenPtr); +static void SIS6326StopVideo(ScrnInfoPtr, pointer, Bool); +static int SIS6326SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int SIS6326GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); +static void SIS6326QueryBestSize(ScrnInfoPtr, Bool, short, short, short, + short, unsigned int *,unsigned int *, pointer); +static int SIS6326PutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int SIS6326QueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); +static void SIS6326VideoTimerCallback(ScrnInfoPtr pScrn, Time now); +static void SIS6326InitOffscreenImages(ScreenPtr pScrn); + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static Atom xvBrightness, xvContrast, xvColorKey; +static Atom xvAutopaintColorKey, xvSetDefaults; + +#define IMAGE_MIN_WIDTH 32 /* Minimum and maximum image sizes */ +#define IMAGE_MIN_HEIGHT 24 +#define IMAGE_MAX_WIDTH 720 /* Are these correct for the chips ? */ +#define IMAGE_MAX_HEIGHT 576 +#define IMAGE_MAX_WIDTH_5597 384 +#define IMAGE_MAX_HEIGHT_5597 288 + +#if 0 +static int oldH, oldW; +#endif + +/**************************************************************************** + * Raw register access : These routines directly interact with the sis's + * control aperature. Must not be called until after + * the board's pci memory has been mapped. + ****************************************************************************/ + +#if 0 +static CARD32 _sisread(SISPtr pSiS, CARD32 reg) +{ + return *(pSiS->IOBase + reg); +} + +static void _siswrite(SISPtr pSiS, CARD32 reg, CARD32 data) +{ + *(pSiS->IOBase + reg) = data; +} +#endif + +static CARD8 getvideoreg(SISPtr pSiS, CARD8 reg) +{ + CARD8 ret; + inSISIDXREG(SISCR, reg, ret); + return(ret); +} + +static void setvideoreg(SISPtr pSiS, CARD8 reg, CARD8 data) +{ + outSISIDXREG(SISCR, reg, data); +} + +static void setvideoregmask(SISPtr pSiS, CARD8 reg, CARD8 data, CARD8 mask) +{ + CARD8 old; + + inSISIDXREG(SISCR, reg, old); + data = (data & mask) | (old & (~mask)); + outSISIDXREG(SISCR, reg, data); +} + +/* VBlank */ +static CARD8 vblank_active_CRT1(SISPtr pSiS) +{ + return (inSISREG(SISINPSTAT) & 0x08); +} + +/* Scanline - unused */ +#if 0 +static CARD32 get_scanline_CRT1(SISPtr pSiS) +{ + CARD8 temp; + + temp = getvideoreg(pSiS, 0x20); + temp = getvideoreg(pSiS, 0x1b); + return((getvideoreg(pSiS, 0x1d) << 8) | getvideoreg(pSiS, 0x1c)); +} +#endif + +void SIS6326InitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + + newAdaptor = SIS6326SetupImageVideo(pScreen); + if(newAdaptor) + SIS6326InitOffscreenImages(pScreen); + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + /* need to free this someplace */ + newAdaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); +#if 0 + oldW = 0; oldH = 0; /* DEBUG */ +#endif +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding = +{ + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} +}; + +static XF86VideoEncodingRec DummyEncoding5597 = +{ + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH_5597, IMAGE_MAX_HEIGHT_5597, + {1, 1} +}; + +#define NUM_FORMATS 4 + +static XF86VideoFormatRec SIS6326Formats[NUM_FORMATS] = +{ + { 8, PseudoColor}, + {15, TrueColor}, + {16, TrueColor}, + {24, TrueColor} +}; + +#define NUM_ATTRIBUTES 5 + +static XF86AttributeRec SIS6326Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, + {XvSettable | XvGettable, 0, 7, "XV_CONTRAST"}, + {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, + {XvSettable , 0, 0, "XV_SET_DEFAULTS"} +}; + +#define NUM_IMAGES 6 +#define NUM_IMAGES_NOYV12 4 +#define PIXEL_FMT_YV12 FOURCC_YV12 /* 0x32315659 */ +#define PIXEL_FMT_UYVY FOURCC_UYVY /* 0x59565955 */ +#define PIXEL_FMT_YUY2 FOURCC_YUY2 /* 0x32595559 */ +#define PIXEL_FMT_I420 FOURCC_I420 /* 0x30323449 */ +#define PIXEL_FMT_RGB5 0x35315652 +#define PIXEL_FMT_RGB6 0x36315652 + +static XF86ImageRec SIS6326Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, /* TW: If order is changed, SIS6326OffscreenImages must be adapted */ + XVIMAGE_UYVY, + XVIMAGE_YV12, + XVIMAGE_I420, + { + 0x35315652, + XvRGB, + LSBFirst, + {'R','V','1','5', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 16, + XvPacked, + 1, +/* 15, 0x001F, 0x03E0, 0x7C00, - incorrect! */ + 15, 0x7C00, 0x03E0, 0x001F, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { + 0x36315652, + XvRGB, + LSBFirst, + {'R','V','1','6', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 16, + XvPacked, + 1, +/* 16, 0x001F, 0x07E0, 0xF800, - incorrect! */ + 16, 0xF800, 0x07E0, 0x001F, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + } +}; + +static XF86ImageRec SIS6326ImagesNoYV12[NUM_IMAGES_NOYV12] = +{ + XVIMAGE_YUY2, /* TW: If order is changed, SIS6326OffscreenImages must be adapted */ + XVIMAGE_UYVY, + { + 0x35315652, + XvRGB, + LSBFirst, + {'R','V','1','5', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 16, + XvPacked, + 1, +/* 15, 0x001F, 0x03E0, 0x7C00, */ + 15, 0x7C00, 0x03E0, 0x001F, /* TW: Should be more correct than the other... */ + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + }, + { + 0x36315652, + XvRGB, + LSBFirst, + {'R','V','1','6', + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + 16, + XvPacked, + 1, +/* 16, 0x001F, 0x07E0, 0xF800, */ + 16, 0xF800, 0x07E0, 0x001F, /* TW: Should be more correct than the other... */ + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + {'R', 'V', 'B',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + XvTopToBottom + } +}; + +typedef struct { + int pixelFormat; + + CARD16 pitch; + + CARD8 keyOP; + + CARD8 HUSF; + CARD8 VUSF; + CARD8 HIntBit; + CARD8 wHPre; + CARD8 PitchMult; + + CARD16 srcW; + CARD16 srcH; + + BoxRec dstBox; + + CARD32 PSY; + CARD32 PSV; + CARD32 PSU; + CARD8 YUVEnd; + + CARD8 lineBufSize; + + CARD8 (*VBlankActiveFunc)(SISPtr); +/* CARD32 (*GetScanLineFunc)(SISPtr pSiS); */ + +} SISOverlayRec, *SISOverlayPtr; + +typedef struct { + FBLinearPtr linear; /* TW: We now use Linear, not Area */ + CARD32 bufAddr[2]; + + unsigned char currentBuf; + + short drw_x, drw_y, drw_w, drw_h; + short src_x, src_y, src_w, src_h; + int id; + short srcPitch, height, width; + CARD32 totalSize; + + char brightness; + unsigned char contrast; + + RegionRec clip; + CARD32 colorKey; + Bool autopaintColorKey; + + CARD32 videoStatus; + Time offTime; + Time freeTime; + + short oldx1, oldx2, oldy1, oldy2; + int mustwait; + + Bool grabbedByV4L; /* V4L stuff */ + int pitch; + int offset; + +} SISPortPrivRec, *SISPortPrivPtr; + +#define GET_PORT_PRIVATE(pScrn) \ + (SISPortPrivPtr)((SISPTR(pScrn))->adaptor->pPortPrivates[0].ptr) + +static void +SIS6326SetPortDefaults (ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) +{ + pPriv->colorKey = 0x000101fe; + pPriv->videoStatus = 0; + pPriv->brightness = 0; + pPriv->contrast = 4; + pPriv->autopaintColorKey = TRUE; +} + +static void +SIS6326ResetVideo(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + /* Unlock registers */ +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + if(getvideoreg (pSiS, Index_VI6326_Passwd) != 0xa1) { + setvideoreg (pSiS, Index_VI6326_Passwd, 0x86); + if(getvideoreg (pSiS, Index_VI6326_Passwd) != 0xa1) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Xv: Video password could not unlock video registers\n"); + } + + /* Initialize the overlay ----------------------------------- */ + + switch(pSiS->Chipset) { + case PCI_CHIP_SIS6326: + /* Disable overlay (D[1]) & capture (D[0]) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x03); + + /* What do these do? (Datasheet names these bits "reserved") */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18); + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c); + + /* Select YUV format (D[6]) and "gfx + video" mode (D[4]), odd polarity? (D[7]) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0xD0); + /* No interrupt, no filter, disable dithering */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x7A); + /* Disable VMI (D[4:3]), Brooktree support (D[6]) and system memory framebuffer (D[7]) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0xF8); + /* Disable video decimation */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc6, 0x00, 0x80); + break; + case PCI_CHIP_SIS5597: + /* Disable overlay (D[1]) & capture (D[0]) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x03); + + /* What do these do? (Datasheet names these bits "reserved") */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18); + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c); + + /* Select YUV format (D[6]) and "gfx + video" mode (D[4]), odd polarity? (D[7]) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0xD0); + /* No interrupt, no filter, disable dithering */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x7A); + /* Disable Brooktree support (D[6]) and system memory framebuffer (D[7]) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0xC0); + /* Disable video decimation (has a really strange effect if enabled) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc6, 0x00, 0x80); + break; + case PCI_CHIP_SIS530: + /* What is this? (Bit is "reserved") */ + setvideoregmask (pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40); + /* Disable overlay (D[1]) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x02); + + /* What do these do? (Datasheet names these bits "reserved") */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18); + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c); + + /* Select YUV format (D[6]) and "gfx + video" mode (D[4]) */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x40, 0x50); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: SiS6326ResetVideo() called with invalid chipset (%x)\n", + pSiS->Chipset); + return; + } + + /* Clear format selection */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x04); + setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x00, 0x07); + + /* Select RGB Chromakey format (D[2]=0), CCIR 601 UV data format (D[1]=0) */ + /* D[1]: 1 = 2's complement, 0 = CCIR 601 format */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc3, 0x00, 0x06); + + /* Reset contrast control */ + setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, 0x04, 0x1F); + + /* Set treshold */ + if(pSiS->oldChipset < OC_SIS6326) { + CARD8 temp; + inSISIDXREG(SISSR, 0x33, temp); /* Synchronous DRAM Timing? */ + if(temp & 0x01) temp = 0x50; + else temp = 0; + setvideoreg(pSiS, Index_VI6326_Play_Threshold_Low, temp); + setvideoreg(pSiS, Index_VI6326_Play_Threshold_High, temp); + } else { + CARD8 temp; + setvideoreg(pSiS, Index_VI6326_Play_Threshold_Low, 0x00); + setvideoreg(pSiS, Index_VI6326_Play_Threshold_High, 0x00); + inSISIDXREG(SISSR, 0x33, temp); /* Are we using SGRAM Timing? */ + if(temp & 0x01) temp = 0x10; + else temp = 0; + setvideoregmask(pSiS, Index_VI6326_Control_Misc4, temp, 0x10); + } + + /* set default properties for overlay ------------------------------- */ + + setvideoregmask (pSiS, Index_VI6326_Contrast_Enh_Ctrl, 0x04, 0x07); + setvideoreg (pSiS, Index_VI6326_Brightness, 0x20); + + if(pSiS->oldChipset < OC_SIS6205A || pSiS->oldChipset > OC_SIS82204) { + setvideoregmask(pSiS, Index_VI6326_AlphaGraph, 0x00, 0xF8); + setvideoregmask(pSiS, Index_VI6326_AlphaVideo, 0xF8, 0xF8); + } else { + setvideoregmask(pSiS, Index_VI6326_AlphaGraph, 0x00, 0xE1); + setvideoregmask(pSiS, Index_VI6326_AlphaVideo, 0xE1, 0xE1); + } +} + +static XF86VideoAdaptorPtr +SIS6326SetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + XF86VideoAdaptorPtr adapt; + SISPortPrivPtr pPriv; + + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(SISPortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "SIS 5597/5598/6326/530/620 Video Overlay"; + adapt->nEncodings = 1; + if(pSiS->oldChipset < OC_SIS6326) { + adapt->pEncodings = &DummyEncoding5597; + } else { + adapt->pEncodings = &DummyEncoding; + } + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = SIS6326Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + pPriv = (SISPortPrivPtr)(&adapt->pPortPrivates[1]); + + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = SIS6326Attributes; + adapt->nAttributes = NUM_ATTRIBUTES; + if(pSiS->NoYV12 == 1) { + adapt->nImages = NUM_IMAGES_NOYV12; + adapt->pImages = SIS6326ImagesNoYV12; + } else { + adapt->nImages = NUM_IMAGES; + adapt->pImages = SIS6326Images; + } + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = SIS6326StopVideo; + adapt->SetPortAttribute = SIS6326SetPortAttribute; + adapt->GetPortAttribute = SIS6326GetPortAttribute; + adapt->QueryBestSize = SIS6326QueryBestSize; + adapt->PutImage = SIS6326PutImage; + adapt->QueryImageAttributes = SIS6326QueryImageAttributes; + + pPriv->videoStatus = 0; + pPriv->currentBuf = 0; + pPriv->linear = NULL; + pPriv->grabbedByV4L= FALSE; + + SIS6326SetPortDefaults(pScrn, pPriv); + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + pSiS->adaptor = adapt; + + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); + xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS"); + + SIS6326ResetVideo(pScrn); + + return adapt; +} + +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if(num != REGION_NUM_RECTS(B)) + return FALSE; + + if((A->extents.x1 != B->extents.x1) || + (A->extents.x2 != B->extents.x2) || + (A->extents.y1 != B->extents.y1) || + (A->extents.y2 != B->extents.y2)) + return FALSE; + + dataA = (int*)REGION_RECTS(A); + dataB = (int*)REGION_RECTS(B); + + while(num--) { + if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; +} + +static int +SIS6326SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, + INT32 value, pointer data) +{ + SISPortPrivPtr pPriv = (SISPortPrivPtr)data; + + if(attribute == xvBrightness) { + if((value < -128) || (value > 127)) + return BadValue; + pPriv->brightness = value; + } else if(attribute == xvContrast) { + if((value < 0) || (value > 7)) + return BadValue; + pPriv->contrast = value; + } else if(attribute == xvColorKey) { + pPriv->colorKey = value; + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + } else if (attribute == xvAutopaintColorKey) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->autopaintColorKey = value; + } else if (attribute == xvSetDefaults) { + SIS6326SetPortDefaults(pScrn, pPriv); + } else return BadMatch; + return Success; +} + +static int +SIS6326GetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +){ + SISPortPrivPtr pPriv = (SISPortPrivPtr)data; + + if(attribute == xvBrightness) { + *value = pPriv->brightness; + } else if(attribute == xvContrast) { + *value = pPriv->contrast; + } else if(attribute == xvColorKey) { + *value = pPriv->colorKey; + } else if (attribute == xvAutopaintColorKey) + *value = (pPriv->autopaintColorKey) ? 1 : 0; + else return BadMatch; + return Success; +} + +static void +SIS6326QueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +){ + *p_w = drw_w; + *p_h = drw_h; + + /* TODO: report the HW limitation */ +} + +static void /* V 530/6326 */ +calc_scale_factor(SISPtr pSiS, SISOverlayPtr pOverlay, ScrnInfoPtr pScrn, + SISPortPrivPtr pPriv) +{ + CARD32 temp=0; + + int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1; + int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1; + int srcW = pOverlay->srcW; + int srcH = pOverlay->srcH; + +#if 0 + /* DEBUG */ + if((oldH != dstH) || (oldW != dstW)){ + xf86DrvMsg(0, X_INFO, "Video size %dx%d\n", dstW, dstH); + oldH = dstH; oldW = dstW; + } + /* /DEBUG */ +#endif + + /* TW: For double scan modes, we need to double the height */ + if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) { + dstH <<= 1; + } + /* TW: For interlace modes, we need to half the height */ + if(pSiS->CurrentLayout.mode->Flags & V_INTERLACE) { + dstH >>= 1; + } + + /* Horizontal */ + if(dstW < IMAGE_MIN_WIDTH) dstW = IMAGE_MIN_WIDTH; + if(dstW == srcW) { + pOverlay->HUSF = 0x00; + pOverlay->HIntBit = 0x01; + } else if(dstW > srcW) { + pOverlay->HIntBit = 0x00; + temp = srcW * 64 / (dstW + 1); + if(temp > 63) temp = 63; + pOverlay->HUSF = temp; + } else { + /* TW: 6326 can't scale below factor .440 - to check with 530/620 */ + if(((dstW * 1000) / srcW) < 440) dstW = ((srcW * 440) / 1000) + 1; + temp = srcW / dstW; + if(temp > 15) temp = 15; + pOverlay->HIntBit = temp; + temp = srcW * 64 / dstW; + pOverlay->HUSF = temp - (pOverlay->HIntBit * 64); + } + + /* Vertical */ + if(dstH < IMAGE_MIN_HEIGHT) dstH = IMAGE_MIN_HEIGHT; + if(dstH == srcH) { + pOverlay->VUSF = 0x00; + pOverlay->PitchMult = 1; + } else if(dstH > srcH) { + temp = srcH * 64 / (dstH + 1); + if (temp > 63) temp = 63; + pOverlay->VUSF = temp; + pOverlay->PitchMult = 1; + } else { + /* TW: 6326 can't scale below factor .440 - to check with 530/620 */ + if(((dstH * 1000) / srcH) < 440) dstH = ((srcH * 440) / 1000) + 1; + temp = srcH / dstH; + if(srcH % dstH) { + temp++; + pOverlay->VUSF = (srcH * 64) / (temp * dstH); + } else { + pOverlay->VUSF = 0x00; + } + pOverlay->PitchMult = temp; + } +} + +static void /* V 530/6326 */ +calc_line_buf_size(SISOverlayPtr pOverlay) +{ + CARD32 I; + CARD32 line = pOverlay->srcW; + + if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) || + (pOverlay->pixelFormat == PIXEL_FMT_I420) ) + { + I = (line >> 5) + (((line >> 6) * 2)) + 3; + I <<= 5; + } else { /* YUV2, UYVY, RGB */ + I = line << 1; + if(I & 7) I += 8; + } + I += 8; + I >>= 3; + pOverlay->lineBufSize = (CARD8)I; +} + +static void /* V 530/6326 */ +merge_line_buf(SISPtr pSiS, SISPortPrivPtr pPriv, Bool enable) +{ + if(enable) { + setvideoregmask(pSiS, Index_VI6326_Control_Misc5, 0x10, 0x10); + } else { + setvideoregmask(pSiS, Index_VI6326_Control_Misc5, 0x00, 0x10); + } +} + +static void /* V 530/6326 */ +set_format(SISPtr pSiS, SISOverlayPtr pOverlay) +{ + CARD8 fmt, misc0, misc1, misc4; + + switch (pOverlay->pixelFormat){ + case PIXEL_FMT_YV12: + case PIXEL_FMT_I420: /* V/530 V/6326 */ + fmt = 0x80; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ + misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */ + misc4 = 0x05; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */ + misc1 = 0xff; + break; + case PIXEL_FMT_UYVY: + fmt = 0x00; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ + misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */ + misc4 = 0x00; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */ + misc1 = 0xff; + break; + case PIXEL_FMT_YUY2: /* V/530 V/6326 */ + fmt = 0x80; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ + misc0 = 0x40; /* D[6]: 1 = YUV, 0 = RGB */ + misc4 = 0x00; /* D[1:0] 00 RGB 555, 01 YUV 422, 10 RGB 565; D[2] 1 = YUV420 mode */ + misc1 = 0xff; + break; + case PIXEL_FMT_RGB6: /* V/530 V/6326 */ + fmt = 0x40; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ + misc0 = 0x00; /* D[6]: 1 = YUV, 0 = RGB */ + misc4 = 0xff; + misc1 = 0x00; /* D[2] = Capture format selection (DS5597) - WDR sets this */ + break; + case PIXEL_FMT_RGB5: /* V/530 V/6326 */ + default: + fmt = 0x00; /* D[7:6] 10 YUV2(=YUYV), 01 VYUY, 00 UYVY, 11 YVYU / 00 RGB 555, 01 RGB 565 */ + misc0 = 0x00; /* D[6]: 1 = YUV, 0 = RGB */ + misc4 = 0xff; + misc1 = 0x04; /* D[2] = Capture format selection (DS5597) - WDR sets this */ + break; + } + + setvideoregmask(pSiS, Index_VI6326_VideoFormatSelect, fmt, 0xC0); + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, misc0, 0x40); + if(misc4 == 0xff) { + setvideoregmask(pSiS, Index_VI6326_Control_Misc1, misc1, 0x04); + if(pSiS->oldChipset >= OC_SIS5597) { + setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x00, 0x05); + } + } else { + if(pSiS->oldChipset >= OC_SIS5597) { + setvideoregmask(pSiS, Index_VI6326_Control_Misc4, misc4, 0x05); + } + setvideoregmask(pSiS, Index_VI6326_Control_Misc1, 0x00, 0x04); + } +} + +static void /* V 6326/530 */ +set_colorkey(SISPtr pSiS, CARD32 colorkey) +{ + CARD8 r, g, b, s; + + b = (CARD8)(colorkey & 0xFF); + g = (CARD8)((colorkey>>8) & 0xFF); + r = (CARD8)((colorkey>>16) & 0xFF); + + if(pSiS->CurrentLayout.bitsPerPixel >= 24) { + s = b; + b = r; + r = s; + } + + setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Blue_Min ,(CARD8)b); + setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Green_Min ,(CARD8)g); + setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Red_Min ,(CARD8)r); + + setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Blue_Max ,(CARD8)b); + setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Green_Max ,(CARD8)g); + setvideoreg(pSiS, Index_VI6326_Overlay_ColorKey_Red_Max ,(CARD8)r); +} + +static void +set_brightness(SISPtr pSiS, CARD8 brightness) +{ + setvideoreg(pSiS, Index_VI6326_Brightness, brightness); +} + +static void +set_contrast(SISPtr pSiS, CARD8 contrast) +{ + setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, contrast, 0x07); +} + +static void +set_contrast_data(SISPtr pSiS, int value) +{ + unsigned long temp; + + if(value < 10000) temp = 0; + else temp = (value - 10000) / 20000; + if(temp > 3) temp = 3; + setvideoregmask(pSiS, Index_VI6326_Contrast_Enh_Ctrl, (temp << 6), 0xC0); + switch(temp) { + case 0: temp = 2048; break; + case 1: temp = 4096; break; + case 2: temp = 8192; break; + case 3: temp = 16384; break; + } + temp <<= 10; + temp /= value; + setvideoreg(pSiS, Index_VI6326_Contrast_Factor, temp); +} + +static void +set_overlay(SISPtr pSiS, SISOverlayPtr pOverlay, SISPortPrivPtr pPriv, int index) +{ + ScrnInfoPtr pScrn = pSiS->pScrn; + + CARD16 pitch=0; + CARD8 h_over=0, v_over=0; + CARD16 top, bottom, left, right; + CARD16 screenX = pSiS->CurrentLayout.mode->HDisplay; + CARD16 screenY = pSiS->CurrentLayout.mode->VDisplay; + CARD32 watchdog; + + top = pOverlay->dstBox.y1; + bottom = pOverlay->dstBox.y2; + if(bottom > screenY) { + bottom = screenY; + } + + left = pOverlay->dstBox.x1; + right = pOverlay->dstBox.x2; + if(right > screenX) { + right = screenX; + } + + /* TW: DoubleScan modes require Y coordinates * 2 */ + if(pSiS->CurrentLayout.mode->Flags & V_DBLSCAN) { + top <<= 1; + bottom <<= 1; + } + /* TW: Interlace modes require Y coordinates / 2 */ + if(pSiS->CurrentLayout.mode->Flags & V_INTERLACE) { + top >>= 1; + bottom >>= 1; + } + + h_over = (((left>>8) & 0x07) | ((right>>4) & 0x70)); + v_over = (((top>>8) & 0x07) | ((bottom>>4) & 0x70)); + + pitch = pOverlay->pitch * pOverlay->PitchMult; + pitch >>= 2; /* Datasheet: Unit = double word - verified */ + if(pitch > 0xfff) { + pitch = pOverlay->pitch * (0xFFF * 2 / pOverlay->pitch); + pOverlay->VUSF = 0x3F; + } + + /* set color key */ + set_colorkey(pSiS, pPriv->colorKey); + + /* set color key mode */ + setvideoregmask(pSiS, Index_VI6326_Key_Overlay_OP, pOverlay->keyOP, 0x0f); + + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x0c); + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x18); + + /* Set Y buf pitch */ /* Datasheet: Unit = double word - verified */ + setvideoreg(pSiS, Index_VI6326_Disp_Y_Buf_Pitch_Low, (CARD8)(pitch)); + setvideoregmask(pSiS, Index_VI6326_Disp_Y_Buf_Pitch_High, (CARD8)(pitch>>8), 0x0f); + /* Set U/V pitch if using planar formats */ + if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) || + (pOverlay->pixelFormat == PIXEL_FMT_I420) ) { + /* Set U/V pitch */ /* Datasheet: Unit = double word - verified */ + setvideoreg(pSiS, Index_VI6326_Disp_UV_Buf_Pitch_Low, (CARD8)pitch >> 1); + setvideoregmask(pSiS, Index_VI6326_Disp_UV_Buf_Pitch_High, (CARD8)(pitch >> 9), 0x0f); + } + + /* set line buffer size */ + setvideoreg(pSiS, Index_VI6326_Line_Buffer_Size, pOverlay->lineBufSize); + + /* set scale factor */ + setvideoreg(pSiS, Index_VI6326_Hor_Scale, (CARD8)((pOverlay->HUSF) | 0xC0)); + setvideoregmask(pSiS, Index_VI6326_Hor_Scale_Integer, (CARD8)(pOverlay->HIntBit), 0x0F); + setvideoregmask(pSiS, Index_VI6326_Ver_Scale, (CARD8)(pOverlay->VUSF), 0x3F); + + /* TW: We don't have to wait for vertical retrace in all cases */ + if(pPriv->mustwait) { + watchdog = WATCHDOG_DELAY; + while ((!pOverlay->VBlankActiveFunc(pSiS)) && --watchdog); + if(!watchdog) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Xv: Waiting for vertical retrace timed-out\n"); + } + + /* set destination window position */ + setvideoreg(pSiS, Index_VI6326_Win_Hor_Disp_Start_Low, (CARD8)left); + setvideoreg(pSiS, Index_VI6326_Win_Hor_Disp_End_Low, (CARD8)right); + setvideoreg(pSiS, Index_VI6326_Win_Hor_Over, (CARD8)h_over); + + setvideoreg(pSiS, Index_VI6326_Win_Ver_Disp_Start_Low, (CARD8)top); + setvideoreg(pSiS, Index_VI6326_Win_Ver_Disp_End_Low, (CARD8)bottom); + setvideoreg(pSiS, Index_VI6326_Win_Ver_Over, (CARD8)v_over); + + /* Set Y start address */ + setvideoreg (pSiS, Index_VI6326_Disp_Y_Buf_Start_Low, (CARD8)(pOverlay->PSY)); + setvideoreg (pSiS, Index_VI6326_Disp_Y_Buf_Start_Middle, (CARD8)((pOverlay->PSY)>>8)); + if(pSiS->oldChipset <= OC_SIS6326) { /* all old chipsets incl 6326 */ + /* Set overflow bits */ + setvideoregmask (pSiS, Index_VI6326_Disp_Capt_Y_Buf_Start_High, + (CARD8)(((pOverlay->PSY)>>12) & 0xF0), 0xF0); + /* Set framebuffer end address */ + setvideoreg (pSiS, Index_VI6326_Disp_Y_End, (CARD8)(pOverlay->YUVEnd)); + } else { /* 530/620 */ + /* Set overflow bits */ + setvideoregmask (pSiS, Index_VI6326_Disp_Capt_Y_Buf_Start_High, + (CARD8)(((pOverlay->PSY)>>13) & 0xF8), 0xF8); + } + + /* Set U/V start addresses if using plane formats */ + if( (pOverlay->pixelFormat == PIXEL_FMT_YV12) || + (pOverlay->pixelFormat == PIXEL_FMT_I420) ) { + + CARD32 PSU = pOverlay->PSU; + CARD32 PSV = pOverlay->PSV; + + /* set U/V start address */ + setvideoreg (pSiS, Index_VI6326_U_Buf_Start_Low, (CARD8)PSU); + setvideoreg (pSiS, Index_VI6326_U_Buf_Start_Middle,(CARD8)(PSU >> 8)); + + setvideoreg (pSiS, Index_VI6326_V_Buf_Start_Low, (CARD8)PSV); + setvideoreg (pSiS, Index_VI6326_V_Buf_Start_Middle,(CARD8)(PSV >> 8)); + + setvideoreg (pSiS, Index_VI6326_UV_Buf_Start_High, + (CARD8)(((PSU >> 16) & 0x0F) | ((PSV >> 12) & 0xF0)) ); + + if(pSiS->oldChipset > OC_SIS6326) { + /* Set bit 20 of the addresses in Misc5 (530/620 only) */ + setvideoreg (pSiS, Index_VI6326_Control_Misc5, + (CARD8)(((PSU >> (20-1)) & 0x02) | ((PSV >> (20-2)) & 0x04)) ); + } + } + + /* set brightness and contrast */ + set_brightness(pSiS, pPriv->brightness); + if(pSiS->oldChipset > OC_SIS6205C) { + set_contrast_data(pSiS, (pOverlay->dstBox.x2 - pOverlay->dstBox.x1) * + (pOverlay->dstBox.y2 - pOverlay->dstBox.y1)); + set_contrast(pSiS, pPriv->contrast); + } + + /* set format */ + set_format(pSiS, pOverlay); +} + +/* TW: Overlay MUST NOT be switched off while beam is over it */ +static void +close_overlay(SISPtr pSiS, SISPortPrivPtr pPriv) +{ + CARD32 watchdog; + + watchdog = WATCHDOG_DELAY; + while((!vblank_active_CRT1(pSiS)) && --watchdog); + if(pSiS->oldChipset > OC_SIS6326) { + /* what is this? */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40); + } + /* disable overlay */ + setvideoregmask(pSiS, Index_VI6326_Control_Misc0, 0x00, 0x02); +} + +static void +SIS6326DisplayVideo(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv) +{ + SISPtr pSiS = SISPTR(pScrn); + + short srcPitch = pPriv->srcPitch; + short height = pPriv->height; + short width = pPriv->width; + SISOverlayRec overlay; + int srcOffsetX=0, srcOffsetY=0; + int sx, sy; + int index = 0; + int pitch; + + memset(&overlay, 0, sizeof(overlay)); + overlay.pixelFormat = pPriv->id; + overlay.pitch = srcPitch; + overlay.keyOP = VI6326_ROP_DestKey; /* DestKey mode */ + + overlay.dstBox.x1 = pPriv->drw_x - pScrn->frameX0; + overlay.dstBox.x2 = pPriv->drw_x + pPriv->drw_w - pScrn->frameX0; + overlay.dstBox.y1 = pPriv->drw_y - pScrn->frameY0; + overlay.dstBox.y2 = pPriv->drw_y + pPriv->drw_h - pScrn->frameY0; + + if((overlay.dstBox.x1 > overlay.dstBox.x2) || + (overlay.dstBox.y1 > overlay.dstBox.y2)) + return; + + if((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0)) + return; + + if(overlay.dstBox.x1 < 0) { + srcOffsetX = pPriv->src_w * (-overlay.dstBox.x1) / pPriv->drw_w; + overlay.dstBox.x1 = 0; + } + if(overlay.dstBox.y1 < 0) { + srcOffsetY = pPriv->src_h * (-overlay.dstBox.y1) / pPriv->drw_h; + overlay.dstBox.y1 = 0; + } + + switch(pPriv->id){ + case PIXEL_FMT_YV12: + sx = (pPriv->src_x + srcOffsetX) & ~7; + sy = (pPriv->src_y + srcOffsetY) & ~1; + pitch = (width + 3) & ~3; + overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy * pitch; + overlay.PSV = overlay.PSY + pitch * height; + overlay.PSU = overlay.PSV + ((((width >> 1) + 3) & ~3) * (height >> 1)); + overlay.PSY >>= 2; + overlay.PSV >>= 2; + overlay.PSU >>= 2; + break; + case PIXEL_FMT_I420: + sx = (pPriv->src_x + srcOffsetX) & ~7; + sy = (pPriv->src_y + srcOffsetY) & ~1; + pitch = (width + 3) & ~3; + overlay.PSY = pPriv->bufAddr[pPriv->currentBuf] + sx + sy * pitch; + overlay.PSU = overlay.PSY + pitch * height; + overlay.PSV = overlay.PSU + ((((width >> 1) + 3) & ~3) * (height >> 1)); + overlay.PSY >>= 2; + overlay.PSV >>= 2; + overlay.PSU >>= 2; + break; + case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_RGB6: + case PIXEL_FMT_RGB5: + default: + sx = (pPriv->src_x + srcOffsetX) & ~1; + sy = (pPriv->src_y + srcOffsetY); + overlay.PSY = (pPriv->bufAddr[pPriv->currentBuf] + sx*2 + sy*srcPitch); + overlay.PSY >>= 2; + break; + } + + /* FIXME: Is this correct? (Is it required to set the end address? + * Datasheet is not clear) - (reg does not exist on 530/620) + */ + overlay.YUVEnd = (pPriv->bufAddr[pPriv->currentBuf] + pPriv->totalSize) >> 14; + + /* FIXME: is it possible that srcW < 0 */ + overlay.srcW = pPriv->src_w - (sx - pPriv->src_x); + overlay.srcH = pPriv->src_h - (sy - pPriv->src_y); + + if ( (pPriv->oldx1 != overlay.dstBox.x1) || + (pPriv->oldx2 != overlay.dstBox.x2) || + (pPriv->oldy1 != overlay.dstBox.y1) || + (pPriv->oldy2 != overlay.dstBox.y2) ) { + pPriv->mustwait = 1; + pPriv->oldx1 = overlay.dstBox.x1; pPriv->oldx2 = overlay.dstBox.x2; + pPriv->oldy1 = overlay.dstBox.y1; pPriv->oldy2 = overlay.dstBox.y2; + } + + /* calculate line buffer length */ + calc_line_buf_size(&overlay); + + overlay.VBlankActiveFunc = vblank_active_CRT1; +/* overlay.GetScanLineFunc = get_scanline_CRT1; */ + + /* calculate scale factor */ + calc_scale_factor(pSiS, &overlay, pScrn, pPriv); + + /* set (not only determine) if line buffer is to be merged */ + if(pSiS->oldChipset > OC_SIS5597) { + int temp; + if(pSiS->oldChipset <= OC_SIS6326) temp = 352; + else temp = 384; + merge_line_buf(pSiS, pPriv, (overlay.srcW > temp)); + } + + /* set overlay */ + set_overlay(pSiS, &overlay, pPriv, index); + + /* enable overlay */ + if(pSiS->oldChipset > OC_SIS6326) { + setvideoregmask (pSiS, Index_VI6326_Control_Misc4, 0x40, 0x40); + } + setvideoregmask (pSiS, Index_VI6326_Control_Misc0, 0x02, 0x02); + + pPriv->mustwait = 0; +} + +static FBLinearPtr +SIS6326AllocateOverlayMemory( + ScrnInfoPtr pScrn, + FBLinearPtr linear, + int size +){ + ScreenPtr pScreen; + FBLinearPtr new_linear; + + if(linear) { + if(linear->size >= size) + return linear; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear; + + xf86FreeOffscreenLinear(linear); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 32, + NULL, NULL, NULL); + + if(!new_linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 32, + PRIORITY_EXTREME); + + if(max_size < size) return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 32, + NULL, NULL, NULL); + } + if (!new_linear) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Xv: Failed to allocate %dK of video memory\n", size/1024); + + return new_linear; +} + +static void +SIS6326FreeOverlayMemory(ScrnInfoPtr pScrn) +{ + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + + if(pPriv->linear) { + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } +} + +static void +SIS6326StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) +{ + SISPortPrivPtr pPriv = (SISPortPrivPtr)data; + SISPtr pSiS = SISPTR(pScrn); + + if(pPriv->grabbedByV4L) + return; + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if(shutdown) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + close_overlay(pSiS, pPriv); + pPriv->mustwait = 1; + } + SIS6326FreeOverlayMemory(pScrn); + pPriv->videoStatus = 0; + pSiS->VideoTimerCallback = NULL; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; + pSiS->VideoTimerCallback = SIS6326VideoTimerCallback; + } + } +} + +static int +SIS6326PutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool sync, + RegionPtr clipBoxes, pointer data +){ + SISPtr pSiS = SISPTR(pScrn); + SISPortPrivPtr pPriv = (SISPortPrivPtr)data; + + int totalSize=0; + int depth = pSiS->CurrentLayout.bitsPerPixel >> 3; + + if(pPriv->grabbedByV4L) + return Success; + + pPriv->drw_x = drw_x; + pPriv->drw_y = drw_y; + pPriv->drw_w = drw_w; + pPriv->drw_h = drw_h; + pPriv->src_x = src_x; + pPriv->src_y = src_y; + pPriv->src_w = src_w; + pPriv->src_h = src_h; + pPriv->id = id; + pPriv->height = height; + pPriv->width = width; + + /* TW: Pixel formats: + 1. YU12: 3 planes: H V + Y sample period 1 1 (8 bit per pixel) + V sample period 2 2 (8 bit per pixel, subsampled) + U sample period 2 2 (8 bit per pixel, subsampled) + + Y plane is fully sampled (width*height), U and V planes + are sampled in 2x2 blocks, hence a group of 4 pixels requires + 4 + 1 + 1 = 6 bytes. The data is planar, ie in single planes + for Y, U and V. + 2. UYVY: 3 planes: H V + Y sample period 1 1 (8 bit per pixel) + V sample period 2 1 (8 bit per pixel, subsampled) + U sample period 2 1 (8 bit per pixel, subsampled) + Y plane is fully sampled (width*height), U and V planes + are sampled in 2x1 blocks, hence a group of 4 pixels requires + 4 + 2 + 2 = 8 bytes. The data is bit packed, there are no separate + Y, U or V planes. + Bit order: U0 Y0 V0 Y1 U2 Y2 V2 Y3 ... + 3. I420: Like YU12, but planes U and V are in reverse order. + 4. YUY2: Like UYVY, but order is + Y0 U0 Y1 V0 Y2 U2 Y3 V2 ... + */ + + switch(id){ + case PIXEL_FMT_YV12: + case PIXEL_FMT_I420: + pPriv->srcPitch = (width + 7) & ~7; + /* Size = width * height * 3 / 2 */ + totalSize = (pPriv->srcPitch * height * 3) >> 1; + break; + case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_RGB5: + case PIXEL_FMT_RGB6: + default: + pPriv->srcPitch = ((width << 1) + 3) & ~3; + /* Size = width * 2 * height */ + totalSize = pPriv->srcPitch * height; + } + + pPriv->totalSize = totalSize; + + /* allocate memory (we do doublebuffering) */ + if(!(pPriv->linear = SIS6326AllocateOverlayMemory(pScrn, pPriv->linear, + totalSize<<1))) + return BadAlloc; + + /* fixup pointers */ + pPriv->bufAddr[0] = (pPriv->linear->offset * depth); + pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize; + + /* copy data */ + memcpy(pSiS->FbBase + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); + + SIS6326DisplayVideo(pScrn, pPriv); + + /* update cliplist */ + if( pPriv->autopaintColorKey && + (pPriv->grabbedByV4L || !RegionsEqual(&pPriv->clip, clipBoxes))) { + /* We always paint colorkey for V4L */ + if (!pPriv->grabbedByV4L) + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + /* draw these */ + /* xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); - for X4.2 */ + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); + } + + pPriv->currentBuf ^= 1; + + pPriv->videoStatus = CLIENT_VIDEO_ON; + + pSiS->VideoTimerCallback = SIS6326VideoTimerCallback; + + return Success; +} + +static int +SIS6326QueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +){ + SISPtr pSiS = SISPTR(pScrn); + int pitchY, pitchUV; + int size, sizeY, sizeUV; + + if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH; + if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT; + + if(pSiS->oldChipset < OC_SIS6326) { + if(*w > IMAGE_MAX_WIDTH_5597) *w = IMAGE_MAX_WIDTH_5597; + if(*h > IMAGE_MAX_HEIGHT_5597) *h = IMAGE_MAX_HEIGHT_5597; + } else { + if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; + if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; + } + + switch(id) { + case PIXEL_FMT_YV12: + case PIXEL_FMT_I420: + *w = (*w + 7) & ~7; + *h = (*h + 1) & ~1; + pitchY = *w; + pitchUV = *w >> 1; + if(pitches) { + pitches[0] = pitchY; + pitches[1] = pitches[2] = pitchUV; + } + sizeY = pitchY * (*h); + sizeUV = pitchUV * ((*h) >> 1); + if(offsets) { + offsets[0] = 0; + offsets[1] = sizeY; + offsets[2] = sizeY + sizeUV; + } + size = sizeY + (sizeUV << 1); + break; + case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_RGB5: + case PIXEL_FMT_RGB6: + default: + *w = (*w + 1) & ~1; + pitchY = *w << 1; + if(pitches) pitches[0] = pitchY; + if(offsets) offsets[0] = 0; + size = pitchY * (*h); + break; + } + + return size; +} + +static void +SIS6326VideoTimerCallback (ScrnInfoPtr pScrn, Time now) +{ + SISPtr pSiS = SISPTR(pScrn); + SISPortPrivPtr pPriv = NULL; + unsigned char sridx, cridx; + + pSiS->VideoTimerCallback = NULL; + + if(!pScrn->vtSema) return; + + if(pSiS->adaptor) { + pPriv = GET_PORT_PRIVATE(pScrn); + if(!pPriv->videoStatus) + pPriv = NULL; + } + + if(pPriv) { + if(pPriv->videoStatus & TIMER_MASK) { + UpdateCurrentTime(); + if(pPriv->offTime < currentTime.milliseconds) { + if(pPriv->videoStatus & OFF_TIMER) { + /* Turn off the overlay */ + sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); + close_overlay(pSiS, pPriv); + outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); + pPriv->mustwait = 1; + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + pSiS->VideoTimerCallback = SIS6326VideoTimerCallback; + } else + if(pPriv->videoStatus & FREE_TIMER) { + SIS6326FreeOverlayMemory(pScrn); + pPriv->mustwait = 1; + pPriv->videoStatus = 0; + } + } else + pSiS->VideoTimerCallback = SIS6326VideoTimerCallback; + } + } +} + +/* TW: Offscreen surface stuff for v4l */ + +static int +SIS6326AllocSurface ( + ScrnInfoPtr pScrn, + int id, + unsigned short w, + unsigned short h, + XF86SurfacePtr surface +) +{ + SISPtr pSiS = SISPTR(pScrn); + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + int size, depth; + + if((w < IMAGE_MIN_WIDTH) || (h < IMAGE_MIN_HEIGHT)) + return BadValue; + + if(pSiS->oldChipset < OC_SIS6326) { + if((w > IMAGE_MAX_WIDTH_5597) || (h > IMAGE_MAX_HEIGHT_5597)) + return BadValue; + } else { + if((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT)) + return BadValue; + } + + if(pPriv->grabbedByV4L) + return BadAlloc; + + depth = pSiS->CurrentLayout.bitsPerPixel >> 3; + + w = (w + 1) & ~1; + pPriv->pitch = ((w << 1) + 63) & ~63; /* Only packed pixel modes supported */ + size = h * pPriv->pitch; + pPriv->linear = SIS6326AllocateOverlayMemory(pScrn, pPriv->linear, size); + if(!pPriv->linear) + return BadAlloc; + + pPriv->totalSize = size; + + pPriv->offset = pPriv->linear->offset * depth; + + surface->width = w; + surface->height = h; + surface->pScrn = pScrn; + surface->id = id; + surface->pitches = &pPriv->pitch; + surface->offsets = &pPriv->offset; + surface->devPrivate.ptr = (pointer)pPriv; + + close_overlay(pSiS, pPriv); + pPriv->videoStatus = 0; + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + pSiS->VideoTimerCallback = NULL; + pPriv->grabbedByV4L = TRUE; + return Success; +} + +static int +SIS6326StopSurface (XF86SurfacePtr surface) +{ + SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); + SISPtr pSiS = SISPTR(surface->pScrn); + + if(pPriv->grabbedByV4L && pPriv->videoStatus) { + close_overlay(pSiS, pPriv); + pPriv->mustwait = 1; + pPriv->videoStatus = 0; + } + return Success; +} + +static int +SIS6326FreeSurface (XF86SurfacePtr surface) +{ + SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); + + if(pPriv->grabbedByV4L) { + SIS6326StopSurface(surface); + SIS6326FreeOverlayMemory(surface->pScrn); + pPriv->grabbedByV4L = FALSE; + } + return Success; +} + +static int +SIS6326GetSurfaceAttribute ( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value +) +{ + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); + + return SIS6326GetPortAttribute(pScrn, attribute, value, (pointer)pPriv); +} + +static int +SIS6326SetSurfaceAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value +) +{ + SISPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);; + + return SIS6326SetPortAttribute(pScrn, attribute, value, (pointer)pPriv); +} + +static int +SIS6326DisplaySurface ( + XF86SurfacePtr surface, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + RegionPtr clipBoxes +) +{ + ScrnInfoPtr pScrn = surface->pScrn; + SISPortPrivPtr pPriv = (SISPortPrivPtr)(surface->devPrivate.ptr); + + if(!pPriv->grabbedByV4L) + return Success; + + pPriv->drw_x = drw_x; + pPriv->drw_y = drw_y; + pPriv->drw_w = drw_w; + pPriv->drw_h = drw_h; + pPriv->src_x = src_x; + pPriv->src_y = src_y; + pPriv->src_w = src_w; + pPriv->src_h = src_h; + pPriv->id = surface->id; + pPriv->height = surface->height; + pPriv->bufAddr[0] = surface->offsets[0]; + pPriv->currentBuf = 0; + pPriv->srcPitch = surface->pitches[0]; + + SIS6326DisplayVideo(pScrn, pPriv); + + if(pPriv->autopaintColorKey) { + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + + return Success; +} + +XF86OffscreenImageRec SIS6326OffscreenImages[2] = +{ + { + &SIS6326Images[0], /* YUV2 */ + VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, + SIS6326AllocSurface, + SIS6326FreeSurface, + SIS6326DisplaySurface, + SIS6326StopSurface, + SIS6326GetSurfaceAttribute, + SIS6326SetSurfaceAttribute, + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + NUM_ATTRIBUTES, + &SIS6326Attributes[0] /* Support all attributes */ + }, + { + &SIS6326Images[1], /* UYVY */ + VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, + SIS6326AllocSurface, + SIS6326FreeSurface, + SIS6326DisplaySurface, + SIS6326StopSurface, + SIS6326GetSurfaceAttribute, + SIS6326SetSurfaceAttribute, + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + NUM_ATTRIBUTES, + &SIS6326Attributes[0] /* Support all attributes */ + }, +}; + +static void +SIS6326InitOffscreenImages(ScreenPtr pScrn) +{ + xf86XVRegisterOffscreenImages(pScrn, SIS6326OffscreenImages, 2); +} +#else +int sis_foo; +#endif + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h new file mode 100644 index 000000000..e0d2d3f33 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h @@ -0,0 +1,237 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.h,v 1.2 2003/01/29 15:42:16 eich Exp $ */ +/* + * Copyright 1998,1999 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 + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk> + * Thomas Winischhofer <thomas@winischhofer.net> + */ + +/* Definitions for the SIS engine communication. ------------------------------------ */ + +/* For pre-530 chipsets only!!! */ + +/* Engine Registers for 1st generation engines (5597/5598/6326) */ +const int sisReg32MMIO[] = { + 0x8280,0x8284,0x8288,0x828C,0x8290,0x8294, + 0x8298,0x829C,0x82A0,0x82A4,0x82A8,0x82AC +}; + +#define BR(x) sisReg32MMIO[x] + +/* These are done using Memory Mapped IO, of the registers */ +/* + * Modified for Sis by Xavier Ducoin (xavier@rd.lectra.fr) + * + */ + +/* Command Reg 0 (0x82aa, [15:0]) */ +#define sisSRCBG 0x0000 /* source select */ +#define sisSRCFG 0x0001 +#define sisSRCVIDEO 0x0002 +#define sisSRCSYSTEM 0x0003 + +#define sisPATFG 0x0004 /* pattern select */ +#define sisPATREG 0x0008 +#define sisPATBG 0x0000 + +#define sisLEFT2RIGHT 0x0010 /* Direction select */ +#define sisRIGHT2LEFT 0x0000 +#define sisTOP2BOTTOM 0x0020 +#define sisBOTTOM2TOP 0x0000 +#define sisXINCREASE sisLEFT2RIGHT +#define sisYINCREASE sisTOP2BOTTOM + +#define sisCLIPENABL 0x0040 /* Clipping select */ +#define sisCLIPINTRN 0x0080 +#define sisCLIPEXTRN 0x0000 + +#define sisCMDBLT 0x0000 /* Command select */ +#define sisCMDBLTMSK 0x0100 +#define sisCMDCOLEXP 0x0200 +#define sisCMDLINE 0x0300 +#define sisFLGECOLEXP 0x2000 +#define sisCMDECOLEXP (sisCMDCOLEXP | sisFLGECOLEXP) + +#define sisLASTPIX 0x0800 /* Line parameters */ +#define sisXMAJOR 0x0400 + + +/* Macros to do useful things with the SIS BitBLT engine */ + +#define sisBLTSync \ + while(MMIO_IN16(pSiS->IOBase, BR(10) + 2) & 0x4000) {} + +/* According to SiS 6326 2D programming guide, 16 bits position at */ +/* 0x82A8 returns queue free. But this don't work, so don't wait */ +/* anything when turbo-queue is enabled. If there are frequent syncs */ +/* this should work. But not for xaa_benchmark :-( */ + +/* TW: Bit 16 only applies to the hardware queue, not the software + * (=turbo) queue. + */ + +#define sisBLTWAIT \ + if(!pSiS->TurboQueue) { \ + while(MMIO_IN16(pSiS->IOBase, BR(10) + 2) & 0x4000) {} \ + } else { \ + sisBLTSync \ + } + +#define sisSETPATREG() \ + ((unsigned char *)(pSiS->IOBase + BR(11))) + +#define sisSETPATREGL() \ + ((unsigned long *)(pSiS->IOBase + BR(11))) + +/* trigger command */ +#define sisSETCMD(op) \ + { \ + unsigned long temp; \ + MMIO_OUT16(pSiS->IOBase, BR(10) + 2, op); \ + temp = MMIO_IN32(pSiS->IOBase, BR(10)); \ + } + +/* set foreground color and fg ROP */ +#define sisSETFGROPCOL(rop, color) \ + MMIO_OUT32(pSiS->IOBase, BR(4), ((rop << 24) | (color & 0xFFFFFF))); + +/* set background color and bg ROP */ +#define sisSETBGROPCOL(rop, color) \ + MMIO_OUT32(pSiS->IOBase, BR(5), ((rop << 24) | (color & 0xFFFFFF))); + +/* background color */ +#define sisSETBGCOLOR(bgColor) \ + MMIO_OUT32(pSiS->IOBase, BR(5), (bgColor)); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor) +#endif + +/* foreground color */ +#define sisSETFGCOLOR(fgColor) \ + MMIO_OUT32(pSiS->IOBase, BR(4), (fgcolor)); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor) +#endif + +/* ROP */ +#define sisSETROPFG(op) \ + MMIO_OUT8(pSiS->IOBase, BR(4) + 3, op); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = ((*(volatile unsigned int *)(pSiS->IOBase + BR(4)))&0xffffff) | (op<<24) +#endif + +#define sisSETROPBG(op) \ + MMIO_OUT8(pSiS->IOBase, BR(5) + 3, op); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = ((*(volatile unsigned int *)(pSiS->IOBase + BR(5)))&0xffffff) | (op<<24) +#endif + +#define sisSETROP(op) \ + sisSETROPFG(op); sisSETROPBG(op); + +/* source and dest address */ +#define sisSETSRCADDR(srcAddr) \ + MMIO_OUT32(pSiS->IOBase, BR(0), (srcAddr & 0x3FFFFFL)); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(0)) = srcAddr & 0x3FFFFFL +#endif + +#define sisSETDSTADDR(dstAddr) \ + MMIO_OUT32(pSiS->IOBase, BR(1), (dstAddr & 0x3FFFFFL)); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(1)) = dstAddr & 0x3FFFFFL +#endif + +/* pitch */ +#define sisSETPITCH(srcPitch,dstPitch) \ + MMIO_OUT32(pSiS->IOBase, BR(2), ((((dstPitch) & 0xFFFF) << 16) | ((srcPitch) & 0xFFFF))); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(2)) = ((dstPitch&0xFFFF)<<16)| \ + (srcPitch&0xFFFF) +#endif + +#define sisSETSRCPITCH(srcPitch) \ + MMIO_OUT16(pSiS->IOBase, BR(2), ((srcPitch) & 0xFFFF)); + +#define sisSETDSTPITCH(dstPitch) \ + MMIO_OUT16(pSiS->IOBase, BR(2) + 2, ((dstPitch) & 0xFFFF)); + +/* Height and width + * According to SIS 2D Engine Programming Guide + * height -1, width - 1 independant of Bpp + */ +#define sisSETHEIGHTWIDTH(Height, Width) \ + MMIO_OUT32(pSiS->IOBase, BR(3), ((((Height) & 0xFFFF) << 16) | ((Width) & 0xFFFF))); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = (((Height)&0xFFFF)<<16)| \ + ((Width)&0xFFFF) +#endif + +/* Clipping */ +#define sisSETCLIPTOP(x, y) \ + MMIO_OUT32(pSiS->IOBase, BR(8), ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(8)) = (((y)&0xFFFF)<<16)| \ + ((x)&0xFFFF) +#endif + +#define sisSETCLIPBOTTOM(x, y) \ + MMIO_OUT32(pSiS->IOBase, BR(9), ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(9)) = (((y)&0xFFFF)<<16)| \ + ((x)&0xFFFF) +#endif + +/* Line drawing */ +#define sisSETXStart(XStart) \ + MMIO_OUT32(pSiS->IOBase, BR(0), ((XStart) & 0xFFFF)); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(0)) = XStart&0xFFFF +#endif + +#define sisSETYStart(YStart) \ + MMIO_OUT32(pSiS->IOBase, BR(1), ((YStart) & 0xFFFF)); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(1)) = YStart&0xFFFF +#endif + +#define sisSETLineMajorCount(MajorAxisCount) \ + MMIO_OUT32(pSiS->IOBase, BR(3), ((MajorAxisCount) & 0xFFFF)); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = MajorAxisCount&0xFFFF +#endif + +#define sisSETLineSteps(K1,K2) \ + MMIO_OUT32(pSiS->IOBase, BR(6), ((((K1) & 0xFFFF) << 16) | ((K2) & 0xFFFF))); +#if 0 + *(volatile unsigned int *)(pSiS->IOBase + BR(6)) = (((K1)&0xFFFF)<<16)| \ + ((K2)&0xFFFF) +#endif + +#define sisSETLineErrorTerm(ErrorTerm) \ + MMIO_OUT16(pSiS->IOBase, BR(7), (ErrorTerm)); +#if 0 + *(volatile unsigned short *)(pSiS->IOBase + BR(7)) = ErrorTerm +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c index 2476e6f43..5eb43f55a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c @@ -1,6 +1,11 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c,v 1.22 2002/04/06 18:16:06 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c,v 1.25 2003/01/29 15:42:17 eich Exp $ */ -/* modified from tdfx_dri.c, mga_dri.c */ +/* + * DRI wrapper for 300, 540, 630, 730 + * (310/325 series experimental and incomplete) + * + * taken and modified from tdfx_dri.c, mga_dri.c + */ #include "xf86.h" #include "xf86_OSproc.h" @@ -15,14 +20,28 @@ #include "sis.h" #include "sis_dri.h" -#include "xf86drmSiS.h" +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) +#include "xf86drmCompat.h" +#endif +/* TW: Idle function for 300 series */ #define BR(x) (0x8200 | (x) << 2) #define SiSIdle \ while((MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \ while((MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \ MMIO_IN16(pSiS->IOBase, 0x8240); +/* TW: Idle function for 310/325 series */ +#define Q_STATUS 0x85CC +#define SiS310Idle \ + { \ + while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ + while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ + while( (MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ + MMIO_IN16(pSiS->IOBase, Q_STATUS); \ + } + + extern void GlxSetVisualConfigs( int nconfigs, __GLXvisualConfig *configs, @@ -53,6 +72,10 @@ static void SISDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); static void SISDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index); +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) +extern Bool drmSiSAgpInit(int driSubFD, int offset, int size); +#endif + static Bool SISInitVisualConfigs(ScreenPtr pScreen) { @@ -222,11 +245,22 @@ Bool SISDRIScreenInit(ScreenPtr pScreen) pDRIInfo->ddxDriverMajorVersion = 0; pDRIInfo->ddxDriverMinorVersion = 1; pDRIInfo->ddxDriverPatchVersion = 0; + pDRIInfo->frameBufferPhysicalAddress = pSIS->FbAddress; - pDRIInfo->frameBufferSize = pSIS->FbMapSize; + + /* TW: This was FbMapSize which is wrong as we must not + * ever overwrite HWCursor and TQ area. On the other + * hand, using availMem here causes MTRR allocation + * to fail ("base is not aligned to size"). Since + * DRI memory management is done via framebuffer + * device, I assume that the size given here + * is NOT used for eventual memory management. + */ + pDRIInfo->frameBufferSize = pSIS->FbMapSize; /* availMem; */ - /* ?? */ + /* TW: scrnOffset is being calulated in sis_vga.c */ pDRIInfo->frameBufferStride = pSIS->scrnOffset; + pDRIInfo->ddxDrawableTableEntry = SIS_MAX_DRAWABLES; if (SAREA_MAX_DRAWABLES < SIS_MAX_DRAWABLES) @@ -235,11 +269,12 @@ Bool SISDRIScreenInit(ScreenPtr pScreen) pDRIInfo->maxDrawableTableEntry = SIS_MAX_DRAWABLES; #ifdef NOT_DONE - /* FIXME need to extend DRI protocol to pass this size back to client + /* FIXME need to extend DRI protocol to pass this size back to client * for SAREA mapping that includes a device private record */ - pDRIInfo->SAREASize = - ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ + pDRIInfo->SAREASize = + ((sizeof(XF86DRISAREARec) + getpagesize() - 1) & getpagesize()); /* round to page */ + /* ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); */ /* round to page */ /* + shared memory device private rec */ #else /* For now the mapping works by using a fixed size defined @@ -492,8 +527,15 @@ SISDRIFinishScreenInit(ScreenPtr pScreen) /* frame control */ saPriv->FrameCount = 0; - *(unsigned long *)(pSiS->IOBase+0x8a2c) = 0; - SiSIdle + if (pSiS->VGAEngine == SIS_315_VGA) { /* 310/325 series */ +#if 0 + *(unsigned long *)(pSiS->IOBase+0x8a2c) = 0; /* FIXME: Where is this on the 310 series ? */ +#endif + SiS310Idle + } else { /* 300 series (and below) */ + *(unsigned long *)(pSiS->IOBase+0x8a2c) = 0; + SiSIdle + } } return DRIFinishScreenInit(pScreen); @@ -505,7 +547,7 @@ SISDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, DRIContextType newContextType, void *newContext) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - SISPtr pSIS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); #if 0 if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && @@ -522,10 +564,16 @@ SISDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, /* * TODO: do this only if X-Server get lock. If kernel supports delayed * signal, needless to do this - */ - *(pSIS->IOBase + 0X8B50) = 0xff; - *(unsigned int *)(pSIS->IOBase + 0x8B60) = -1; - + */ + if (pSiS->VGAEngine == SIS_315_VGA) { +#if 0 + *(pSiS->IOBase + 0x8B50) = 0xff; /* FIXME: Where is this on 310 series */ + *(unsigned int *)(pSiS->IOBase + 0x8B60) = -1; /* FIXME: Where is this on 310 series */ +#endif + } else { + *(pSiS->IOBase + 0x8B50) = 0xff; + *(unsigned int *)(pSiS->IOBase + 0x8B60) = -1; + } } static void @@ -535,7 +583,11 @@ SISDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; SISPtr pSiS = SISPTR(pScrn); - SiSIdle + if (pSiS->VGAEngine == SIS_315_VGA) { + SiS310Idle /* 310/325 series */ + } else { + SiSIdle /* 300 series */ + } } static void @@ -546,7 +598,11 @@ SISDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; SISPtr pSiS = SISPTR(pScrn); - SiSIdle + if (pSiS->VGAEngine == SIS_315_VGA) { + SiS310Idle /* 310/325 series */ + } else { + SiSIdle /* 300 series and below */ + } } #if 0 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c index a58fcb4c2..eb89fe24b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c @@ -1,33 +1,49 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.86 2003/02/04 02:44:29 dawes Exp $ */ /* * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * Parts Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. * * 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 + * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations + * specific, written prior permission. The copyright holder 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, + * THE COPYRIGHT HOLDER 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 + * EVENT SHALL THE COPYRIGHT HOLDER 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 - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. * - * Fixes for 630 chipsets: Thomas Winischhofer. + * Thomas Winischhofer <thomas@winischhofer.net>: + * - 310/325 series (315/550/650/651/740/M650) support + * - (possibly incomplete) Xabre (SiS330) support + * - new mode switching code for 300, 310/325 and 330 series + * - many fixes for 300/540/630/730 chipsets, + * - many fixes for 5597/5598, 6326 and 530/620 chipsets, + * - VESA mode switching (deprecated), + * - extended CRT2/video bridge handling support, + * - dual head support on 300, 310/325 and 330 series + * - 650/LVDS (up to 1400x1050), 650/Chrontel 701x support + * - 30xB/30xLV/30xLVX video bridge support (300, 310/325, 330 series) + * - Xv support for 5597/5598, 6326, 530/620 and 310/325 series + * - video overlay enhancements for 300 series + * - TV and hi-res support for the 6326 + * - Color HW cursor support for 300(emulated), 310/325 and 330 series + * - etc. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.81 2002/07/24 01:47:32 tsi Exp $ */ #include "fb.h" #include "xf1bpp.h" @@ -38,6 +54,7 @@ #include "xf86_OSproc.h" #include "xf86Resources.h" #include "xf86_ansic.h" +#include "dixstruct.h" #include "xf86Version.h" #include "xf86PciInfo.h" #include "xf86Pci.h" @@ -54,10 +71,11 @@ #include "sis.h" #include "sis_regs.h" -#include "sis_bios.h" #include "sis_vb.h" #include "sis_dac.h" +#include "sis_driver.h" + #define _XF86DGA_SERVER_ #include "extensions/xf86dgastr.h" @@ -74,19 +92,20 @@ #include "dri.h" #endif - -/* mandatory functions */ +/* Mandatory functions */ static void SISIdentify(int flags); static Bool SISProbe(DriverPtr drv, int flags); static Bool SISPreInit(ScrnInfoPtr pScrn, int flags); -static Bool SISScreenInit(int Index, ScreenPtr pScreen, int argc, - char **argv); +static Bool SISScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); static Bool SISEnterVT(int scrnIndex, int flags); static void SISLeaveVT(int scrnIndex, int flags); static Bool SISCloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool SISSaveScreen(ScreenPtr pScreen, int mode); static Bool SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); static void SISAdjustFrame(int scrnIndex, int x, int y, int flags); +#ifdef SISDUALHEAD +static Bool SISSaveScreenDH(ScreenPtr pScreen, int mode); +#endif /* Optional functions */ static void SISFreeScreen(int scrnIndex, int flags); @@ -94,47 +113,68 @@ static int SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); /* Internally used functions */ -static Bool SISMapMem(ScrnInfoPtr pScrn); -static Bool SISUnmapMem(ScrnInfoPtr pScrn); -static void SISSave(ScrnInfoPtr pScrn); -static void SISRestore(ScrnInfoPtr pScrn); -static void SISVESARestore(ScrnInfoPtr pScrn); -static Bool SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); -static void SISModifyModeInfo(DisplayModePtr mode); -static void SiSPreSetMode(ScrnInfoPtr pScrn); -static void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg, int LockAfterwards); -static Bool SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); -static void SiSBuildVesaModeList(int scrnIndex, vbeInfoPtr pVbe, - VbeInfoBlock *vbe); -static void SISSaveUnlockExtRegisterLock(SISRegPtr sisReg); -static void SISRestoreExtRegisterLock(SISRegPtr sisReg); -static UShort CalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode); -static void SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function); -static void SISBridgeRestore(ScrnInfoPtr pScrn); -unsigned char SISSearchCRT1Rate(DisplayModePtr mode); - -void SiSOptions(ScrnInfoPtr pScrn); -const OptionInfoRec * SISAvailableOptions(int chipid, int busid); -void SiSSetup(ScrnInfoPtr pScrn); -void SISVGAPreInit(ScrnInfoPtr pScrn); -Bool SiSAccelInit(ScreenPtr pScreen); -Bool SiS300AccelInit(ScreenPtr pScreen); -Bool SiS530AccelInit(ScreenPtr pScreen); -Bool SiSHWCursorInit(ScreenPtr pScreen); -Bool SISDGAInit(ScreenPtr pScreen); -void SISInitVideo(ScreenPtr pScreen); - - -#ifdef DEBUG +static Bool SISMapMem(ScrnInfoPtr pScrn); +static Bool SISUnmapMem(ScrnInfoPtr pScrn); +static void SISSave(ScrnInfoPtr pScrn); +static void SISRestore(ScrnInfoPtr pScrn); +static void SISVESARestore(ScrnInfoPtr pScrn); +static Bool SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void SISModifyModeInfo(DisplayModePtr mode); +static void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static Bool SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); +static void SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe); +static UShort SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function); +static void SISBridgeRestore(ScrnInfoPtr pScrn); +static void SiSEnableTurboQueue(ScrnInfoPtr pScrn); +unsigned char SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void SISWaitVBRetrace(ScrnInfoPtr pScrn); + +void SISWaitRetraceCRT1(ScrnInfoPtr pScrn); +void SISWaitRetraceCRT2(ScrnInfoPtr pScrn); + +BOOLEAN SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn); +#ifdef CYCLECRT2 +Bool SISCycleCRT2Type(int scrnIndex, DisplayModePtr mode); +#endif + +#ifdef DEBUG static void SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode); #endif +/* TW: New mode switching functions */ +extern BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); +extern BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch); +extern USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode); +extern USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags); +extern void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr); +extern DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn); +#ifdef SISDUALHEAD +extern BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom); +extern BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, + ScrnInfoPtr pScrn, DisplayModePtr mode); +#endif + +/* TW: For power management for 310/325 series */ +extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr); +extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr); +extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); +extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); + +#ifdef SISDUALHEAD +static int SISEntityIndex = -1; +#endif + /* * This is intentionally screen-independent. It indicates the binding * choice made in the first PreInit. */ static int pix24bpp = 0; - /* * This contains the functions needed by the server after loading the driver @@ -155,82 +195,40 @@ DriverRec SIS = { }; static SymTabRec SISChipsets[] = { -#if 0 - { PCI_CHIP_SG86C201, "SIS86c201" }, - { PCI_CHIP_SG86C202, "SIS86c202" }, - { PCI_CHIP_SG86C205, "SIS86c205" }, - { PCI_CHIP_SG86C215, "SIS86c215" }, - { PCI_CHIP_SG86C225, "SIS86c225" }, -#endif - { PCI_CHIP_SIS5597, "SIS5597" }, - { PCI_CHIP_SIS530, "SIS530" }, - { PCI_CHIP_SIS6326, "SIS6326" }, - { PCI_CHIP_SIS300, "SIS300" }, - { PCI_CHIP_SIS630, "SIS630" }, + { PCI_CHIP_SIS5597, "SIS5597/5598" }, + { PCI_CHIP_SIS530, "SIS530/620" }, + { PCI_CHIP_SIS6326, "SIS6326/AGP/DVD" }, + { PCI_CHIP_SIS300, "SIS300/305" }, + { PCI_CHIP_SIS630, "SIS630/730" }, { PCI_CHIP_SIS540, "SIS540" }, + { PCI_CHIP_SIS315, "SIS315" }, + { PCI_CHIP_SIS315H, "SIS315H" }, + { PCI_CHIP_SIS315PRO, "SIS315PRO" }, + { PCI_CHIP_SIS550, "SIS550" }, + { PCI_CHIP_SIS650, "SIS650/M650/651/740" }, +#ifdef INCL_SIS330 /* TW: New for SiS330 (untested) */ + { PCI_CHIP_SIS330, "SIS330(Xabre)" }, +#endif { -1, NULL } }; static PciChipsets SISPciChipsets[] = { -#if 0 - { PCI_CHIP_SG86C201, PCI_CHIP_SG86C201, RES_SHARED_VGA }, - { PCI_CHIP_SG86C202, PCI_CHIP_SG86C202, RES_SHARED_VGA }, - { PCI_CHIP_SG86C205, PCI_CHIP_SG86C205, RES_SHARED_VGA }, - { PCI_CHIP_SG86C205, PCI_CHIP_SG86C205, RES_SHARED_VGA }, -#endif { PCI_CHIP_SIS5597, PCI_CHIP_SIS5597, RES_SHARED_VGA }, { PCI_CHIP_SIS530, PCI_CHIP_SIS530, RES_SHARED_VGA }, { PCI_CHIP_SIS6326, PCI_CHIP_SIS6326, RES_SHARED_VGA }, { PCI_CHIP_SIS300, PCI_CHIP_SIS300, RES_SHARED_VGA }, { PCI_CHIP_SIS630, PCI_CHIP_SIS630, RES_SHARED_VGA }, { PCI_CHIP_SIS540, PCI_CHIP_SIS540, RES_SHARED_VGA }, + { PCI_CHIP_SIS550, PCI_CHIP_SIS550, RES_SHARED_VGA }, + { PCI_CHIP_SIS315, PCI_CHIP_SIS315, RES_SHARED_VGA }, + { PCI_CHIP_SIS315H, PCI_CHIP_SIS315H, RES_SHARED_VGA }, + { PCI_CHIP_SIS315PRO, PCI_CHIP_SIS315PRO, RES_SHARED_VGA }, + { PCI_CHIP_SIS650, PCI_CHIP_SIS650, RES_SHARED_VGA }, +#ifdef INCL_SIS330 /* TW: New for SiS330 */ + { PCI_CHIP_SIS330, PCI_CHIP_SIS330, RES_SHARED_VGA }, +#endif { -1, -1, RES_UNDEFINED } }; - - -int sisReg32MMIO[]={0x8280,0x8284,0x8288,0x828C,0x8290,0x8294,0x8298,0x829C, - 0x82A0,0x82A4,0x82A8,0x82AC}; -/* Engine Register for the 2nd Generation Graphics Engine */ -int sis2Reg32MMIO[]={0x8200,0x8204,0x8208,0x820C,0x8210,0x8214,0x8218,0x821C, - 0x8220,0x8224,0x8228,0x822C,0x8230,0x8234,0x8238,0x823C, - 0x8240, 0x8300}; - -/* TW: The following was re-included because there are BIOSes out there that - * report incomplete mode lists. These are BIOS versions <2.01.2x - */ -/* TW: VBE 3.0 on SiS630 does not support 24 fpp modes (only 32fpp when depth = 24); - * NOTE: Mode numbers for 1280, 1600 and 1920 are unofficial but they work here! - */ - /* 8 16 24 32 */ -static UShort VESAModeIndex_640x480[] = {0x100, 0x111, 0x112, 0x13a}; -static UShort VESAModeIndex_720x480[] = {0x000, 0x000, 0x000, 0x000}; -static UShort VESAModeIndex_720x576[] = {0x000, 0x000, 0x000, 0x000}; -static UShort VESAModeIndex_800x600[] = {0x103, 0x114, 0x115, 0x13b}; -static UShort VESAModeIndex_1024x768[] = {0x105, 0x117, 0x118, 0x13c}; -static UShort VESAModeIndex_1280x1024[] = {0x107, 0x11a, 0x11b, 0x13d}; -static UShort VESAModeIndex_1600x1200[] = {0x13e, 0x13f, 0x000, 0x140}; -static UShort VESAModeIndex_1920x1440[] = {0x141, 0x142, 0x000, 0x143}; - -static struct _sis_vrate { - CARD16 idx; - CARD16 xres; - CARD16 yres; - CARD16 refresh; -} sisx_vrate[] = { - {1, 640, 480, 60}, {2, 640, 480, 72}, {3, 640, 480, 75}, {4, 640, 480, 85}, - {5, 640, 480, 100}, {6, 640, 480, 120}, {7, 640, 480, 160}, {8, 640, 480, 200}, - {1, 720, 480, 60}, {1, 720, 576, 50}, - {1, 800, 600, 56}, {2, 800, 600, 60}, {3, 800, 600, 72}, {4, 800, 600, 75}, - {5, 800, 600, 85}, {6, 800, 600, 100}, {7, 800, 600, 120}, {8, 800, 600, 160}, - {1, 1024, 768, 43}, {2, 1024, 768, 60}, {3, 1024, 768, 70}, {4, 1024, 768, 75}, - {5, 1024, 768, 85}, {6, 1024, 768, 100}, {7, 1024, 768, 120}, - {1, 1280, 1024, 43}, {2, 1280, 1024, 60}, {3, 1280, 1024, 75}, {4, 1280, 1024, 85}, - {1, 1600, 1200, 60}, {2, 1600, 1200, 65}, {3, 1600, 1200, 70}, {4, 1600, 1200, 75}, - {5, 1600, 1200, 85}, - {1, 1920, 1440, 60}, - {0, 0, 0, 0} -}; - static const char *xaaSymbols[] = { "XAACopyROP", @@ -285,6 +283,11 @@ static const char *ramdacSymbols[] = { static const char *ddcSymbols[] = { "xf86PrintEDID", "xf86SetDDCproperties", + "xf86InterpretEDID", + "xf86DoEDID_DDC1", +#ifdef SISI2C + "xf86DoEDID_DDC2", +#endif NULL }; @@ -294,13 +297,29 @@ static const char *i2cSymbols[] = { NULL }; +static const char *int10Symbols[] = { + "xf86FreeInt10", + "xf86InitInt10", + NULL +}; + static const char *vbeSymbols[] = { +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + "VBEInit", +#else "VBEExtendedInit", +#endif "vbeDoEDID", "vbeFree", - "VBEFreeVBEInfo", "VBEGetVBEInfo", + "VBEFreeVBEInfo", + "VBEGetModeInfo", + "VBEFreeModeInfo", "VBESaveRestore", + "VBESetVBEMode", + "VBEGetVBEMode", + "VBESetDisplayStart", + "VBESetGetLogicalScanlineLength", NULL }; @@ -336,7 +355,6 @@ static const char *driSymbols[] = { }; #endif - #ifdef XFree86LOADER static MODULESETUPPROTO(sisSetup); @@ -367,7 +385,7 @@ sisSetup(pointer module, pointer opts, int *errmaj, int *errmin) xf86AddDriver(&SIS, module, 0); LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols, xaaSymbols, miscfbSymbols, shadowSymbols, ramdacSymbols, - vbeSymbols, + vbeSymbols, int10Symbols, #ifdef XF86DRI drmSymbols, driSymbols, #endif @@ -393,7 +411,9 @@ SISGetRec(ScrnInfoPtr pScrn) return TRUE; pScrn->driverPrivate = xnfcalloc(sizeof(SISRec), 1); - /* Initialise it */ + + /* Initialise it to 0 */ + memset(pScrn->driverPrivate, 0, sizeof(SISRec)); return TRUE; } @@ -402,9 +422,44 @@ static void SISFreeRec(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - - if (pSiS->pstate) xfree(pSiS->pstate); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = NULL; +#endif + + /* TW: Just to make sure... */ + if(!pSiS) return; + + pSiSEnt = pSiS->entityPrivate; + + if(pSiS->pstate) xfree(pSiS->pstate); pSiS->pstate = NULL; + if(pSiS->fonts) xfree(pSiS->fonts); + pSiS->fonts = NULL; +#ifdef SISDUALHEAD + if(pSiSEnt) { + if(!pSiS->SecondHead) { + /* TW: Free memory only if we are first head; in case of an error + * during init of the second head, the server will continue - + * and we need the BIOS image and SiS_Private for the first + * head. + */ + if(pSiSEnt->BIOS) xfree(pSiSEnt->BIOS); + pSiSEnt->BIOS = pSiS->BIOS = NULL; + if(pSiSEnt->SiS_Pr) xfree(pSiSEnt->SiS_Pr); + pSiSEnt->SiS_Pr = pSiS->SiS_Pr = NULL; + } else { + pSiS->BIOS = NULL; + pSiS->SiS_Pr = NULL; + } + } else { +#endif + if(pSiS->BIOS) xfree(pSiS->BIOS); + pSiS->BIOS = NULL; + if(pSiS->SiS_Pr) xfree(pSiS->SiS_Pr); + pSiS->SiS_Pr = NULL; +#ifdef SISDUALHEAD + } +#endif if (pSiS->pVbe) vbeFree(pSiS->pVbe); pSiS->pVbe = NULL; if (pScrn->driverPrivate == NULL) @@ -413,72 +468,294 @@ SISFreeRec(ScrnInfoPtr pScrn) pScrn->driverPrivate = NULL; } -static void +static void SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) { SISPtr pSiS = SISPTR(pScrn); - unsigned char extDDC_PCR; + unsigned char extDDC_PCR=0; + unsigned char crtc17, seq1; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "SISDisplayPowerManagementSet(%d)\n",PowerManagementMode); + + /* unlock registers */ +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + /* Read CR17 */ + inSISIDXREG(SISCR, 0x17, crtc17); + + /* Read SR1 */ + inSISIDXREG(SISSR, 0x01, seq1); + + if(pSiS->VBFlags & CRT2_LCD) { + if(((pSiS->VGAEngine == SIS_300_VGA) && + (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) || + ((pSiS->VGAEngine == SIS_315_VGA) && + ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { + /* Read Power Control Register (SR11) */ + inSISIDXREG(SISSR, 0x11, extDDC_PCR); + /* if not blanked, obtain state of LCD blank flags set by BIOS */ + if(!pSiS->Blank) { + pSiS->LCDon = extDDC_PCR; + } + /* erase LCD blank flags */ + extDDC_PCR &= ~0x0C; + } + } + + switch (PowerManagementMode) { + + case DPMSModeOn: /* HSync: On, VSync: On */ + + pSiS->Blank = FALSE; + seq1 &= ~0x20; + crtc17 |= 0x80; + if(pSiS->VBFlags & CRT2_LCD) { + if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & VB_CHRONTEL) { + SiS_Chrontel701xBLOn(pSiS->SiS_Pr); + } else if(pSiS->VBFlags & VB_LVDS) { + extDDC_PCR |= (pSiS->LCDon & 0x0C); + } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + extDDC_PCR |= (pSiS->LCDon & 0x0C); + } + } + } + break; + + case DPMSModeStandby: /* HSync: Off, VSync: On */ + case DPMSModeSuspend: /* HSync: On, VSync: Off */ + + pSiS->Blank = TRUE; + seq1 |= 0x20 ; + if(pSiS->VBFlags & CRT2_LCD) { + if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & VB_CHRONTEL) { + SiS_Chrontel701xBLOff(pSiS->SiS_Pr); + } else if(pSiS->VBFlags & VB_LVDS) { + extDDC_PCR |= 0x08; + } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + extDDC_PCR |= 0x08; + } + } + } + break; + + case DPMSModeOff: /* HSync: Off, VSync: Off */ + + pSiS->Blank = TRUE; + seq1 |= 0x20; + if(pSiS->VGAEngine == SIS_300_VGA || + pSiS->VGAEngine == SIS_315_VGA) { + /* TW: We can't switch off CRT1 if bridge is in slavemode */ + if(pSiS->VBFlags & CRT2_ENABLE) { + if(!(SiSBridgeIsInSlaveMode(pScrn))) crtc17 &= ~0x80; + } else crtc17 &= ~0x80; + } else { + crtc17 &= ~0x80; + } + if(pSiS->VBFlags & CRT2_LCD) { + if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & VB_CHRONTEL) { + SiS_Chrontel701xBLOff(pSiS->SiS_Pr); + } else if(pSiS->VBFlags & VB_LVDS) { + extDDC_PCR |= 0x0C; + } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + extDDC_PCR |= 0x0C; + } + } + } + break; + + } + + outSISIDXREG(SISSR, 0x01, seq1); /* Set/Clear "Display On" bit */ + + outSISIDXREG(SISCR, 0x17, crtc17); + + if(pSiS->VBFlags & CRT2_LCD) { + if(((pSiS->VGAEngine == SIS_300_VGA) && + (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) || + ((pSiS->VGAEngine == SIS_315_VGA) && + ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { + outSISIDXREG(SISSR, 0x11, extDDC_PCR); + } + } + + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + usleep(10000); + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ + +} + +#ifdef SISDUALHEAD +/* TW: DPMS for dual head mode */ +static void +SISDisplayPowerManagementSetDH(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) +{ + SISPtr pSiS = SISPTR(pScrn); unsigned char crtc17 = 0; + unsigned char extDDC_PCR=0; unsigned char seq1 = 0; - int vgaIOBase = VGAHWPTR(pScrn)->IOBase; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "SISDisplayPowerManagementSet(%d)\n",PowerManagementMode); - - outb(vgaIOBase + 4, 0x17); - crtc17 = inb(vgaIOBase + 5); - outb(VGA_SEQ_INDEX, 0x11); - extDDC_PCR = inb(VGA_SEQ_DATA); - /* if not blanked obtain state of LCD blank flags set by BIOS */ - if (!pSiS->Blank) - pSiS->LCDon = extDDC_PCR; - /* erase LCD blank flags */ - extDDC_PCR &= ~0xC; - - switch (PowerManagementMode) + "SISDisplayPowerManagementSetDH(%d)\n",PowerManagementMode); + + /* unlock registers */ +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if (pSiS->SecondHead) { + + /* TW: Second (slave) head is always CRT1 */ + + /* Read CR17 and SR01 */ + inSISIDXREG(SISCR, 0x17, crtc17); + inSISIDXREG(SISSR, 0x01, seq1); + + switch (PowerManagementMode) { - case DPMSModeOn: - /* HSync: On, VSync: On */ - seq1 = 0x00 ; - /* don't just unblanking; use LCD state set by BIOS */ - extDDC_PCR |= (pSiS->LCDon & 0x0C); - pSiS->Blank = FALSE; + case DPMSModeOn: /* HSync: On, VSync: On */ + seq1 &= ~0x20 ; crtc17 |= 0x80; + pSiS->BlankCRT1 = FALSE; break; - case DPMSModeStandby: - /* HSync: Off, VSync: On */ - seq1 = 0x20 ; - extDDC_PCR |= 0x8; - pSiS->Blank = TRUE; + + case DPMSModeStandby: /* HSync: Off, VSync: On */ + case DPMSModeSuspend: /* HSync: On, VSync: Off */ + seq1 |= 0x20; + pSiS->BlankCRT1 = TRUE; + break; + + case DPMSModeOff: /* HSync: Off, VSync: Off */ + seq1 |= 0x20 ; + pSiS->BlankCRT1 = TRUE; + crtc17 &= ~0x80; break; - case DPMSModeSuspend: - /* HSync: On, VSync: Off */ - seq1 = 0x20 ; - extDDC_PCR |= 0x8; - pSiS->Blank = TRUE; + } + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + + outSISIDXREG(SISSR, 0x01, seq1); /* Set/Clear "Display On" bit */ + + usleep(10000); + + outSISIDXREG(SISCR, 0x17, crtc17); + + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ + + } else { + + /* TW: Master head is always CRT2 */ + + /* TV can not be managed */ + if(!(pSiS->VBFlags & CRT2_LCD)) return; + + if(((pSiS->VGAEngine == SIS_300_VGA) && + (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) || + ((pSiS->VGAEngine == SIS_315_VGA) && + ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { + /* Read Power Control Register (SR11) */ + inSISIDXREG(SISSR, 0x11, extDDC_PCR); + /* if not blanked obtain state of LCD blank flags set by BIOS */ + if(!pSiS->BlankCRT2) { + pSiS->LCDon = extDDC_PCR; + } + /* erase LCD blank flags */ + extDDC_PCR &= ~0xC; + } + + switch (PowerManagementMode) { + + case DPMSModeOn: + pSiS->BlankCRT2 = FALSE; + if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & VB_CHRONTEL) { + SiS_Chrontel701xBLOn(pSiS->SiS_Pr); + } else if(pSiS->VBFlags & VB_LVDS) { + extDDC_PCR |= (pSiS->LCDon & 0x0C); + } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOn(pSiS->SiS_Pr, &pSiS->sishw_ext); + } + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOn(pSiS->SiS_Pr, &pSiS->sishw_ext); + } else { + extDDC_PCR |= (pSiS->LCDon & 0x0C); + } + } break; + + case DPMSModeStandby: + case DPMSModeSuspend: + pSiS->BlankCRT2 = TRUE; + if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & VB_CHRONTEL) { + SiS_Chrontel701xBLOff(pSiS->SiS_Pr); + } else if(pSiS->VBFlags & VB_LVDS) { + extDDC_PCR |= 0x08; + } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext); + } + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext); + } else { + extDDC_PCR |= 0x08; + } + } + break; + case DPMSModeOff: - /* HSync: Off, VSync: Off */ - seq1 = 0x20 ; - extDDC_PCR |= 0xC; - pSiS->Blank = TRUE; - /* DPMSModeOff is not supported with ModeStandby | ModeSuspend */ - /* need same as the generic VGA function */ - crtc17 &= ~0x80; + pSiS->BlankCRT2 = TRUE; + if(pSiS->VGAEngine == SIS_315_VGA) { + if(pSiS->VBFlags & VB_CHRONTEL) { + SiS_Chrontel701xBLOff(pSiS->SiS_Pr); + } else if(pSiS->VBFlags & VB_LVDS) { + extDDC_PCR |= 0x0C; + } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext); + } + } else if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext); + } else { + extDDC_PCR |= 0x0C; + } + } break; + } + + if(((pSiS->VGAEngine == SIS_300_VGA) && + (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) || + ((pSiS->VGAEngine == SIS_315_VGA) && + ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { + outSISIDXREG(SISSR, 0x11, extDDC_PCR); + } + } - outw(VGA_SEQ_INDEX, 0x0100); /* Synchronous Reset */ - outb(VGA_SEQ_INDEX, 0x01); /* Select SEQ1 */ - seq1 |= inb(VGA_SEQ_DATA) & ~0x20; - outb(VGA_SEQ_DATA, seq1); - usleep(10000); - outb(vgaIOBase + 4, 0x17); - outb(vgaIOBase + 5, crtc17); - outb(VGA_SEQ_INDEX, 0x11); - outb(VGA_SEQ_DATA, extDDC_PCR); - outw(VGA_SEQ_INDEX, 0x0300); /* End Reset */ } - +#endif /* Mandatory */ static void @@ -492,27 +769,27 @@ SIS1bppColorMap(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - outb(pSiS->RelIO+0x48, 0x00); - outb(pSiS->RelIO+0x49, 0x00); - outb(pSiS->RelIO+0x49, 0x00); - outb(pSiS->RelIO+0x49, 0x00); + outSISREG(SISCOLIDX, 0x00); + outSISREG(SISCOLDATA, 0x00); + outSISREG(SISCOLDATA, 0x00); + outSISREG(SISCOLDATA, 0x00); - outb(pSiS->RelIO+0x48, 0x3F); - outb(pSiS->RelIO+0x49, 0x3F); - outb(pSiS->RelIO+0x49, 0x3F); - outb(pSiS->RelIO+0x49, 0x3F); + outSISREG(SISCOLIDX, 0x3f); + outSISREG(SISCOLDATA, 0x3f); + outSISREG(SISCOLDATA, 0x3f); + outSISREG(SISCOLDATA, 0x3f); } /* Mandatory */ static Bool SISProbe(DriverPtr drv, int flags) { - int i; + int i; GDevPtr *devSections; - int *usedChips; - int numDevSections; - int numUsed; - Bool foundScreen = FALSE; + int *usedChips; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; /* * The aim here is to find all cards that this driver can handle, @@ -525,8 +802,6 @@ SISProbe(DriverPtr drv, int flags) * the required ScrnInfoRec initialisations. Don't allocate any new * data structures. * - * Since this test version still uses vgaHW, we'll only actually claim - * one for now, and just print a message about the others. */ /* @@ -546,11 +821,6 @@ SISProbe(DriverPtr drv, int flags) } /* - * While we're VGA-dependent, can really only have one such instance, but - * we'll ignore that. - */ - - /* * 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. @@ -581,13 +851,16 @@ SISProbe(DriverPtr drv, int flags) foundScreen = TRUE; else for (i = 0; i < numUsed; i++) { ScrnInfoPtr pScrn; +#ifdef SISDUALHEAD + EntityInfoPtr pEnt; +#endif /* Allocate a ScrnInfoRec and claim the slot */ pScrn = NULL; if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], - SISPciChipsets, NULL, NULL, - NULL, NULL, NULL))) { + SISPciChipsets, NULL, NULL, + NULL, NULL, NULL))) { /* Fill in what we can of the ScrnInfoRec */ pScrn->driverVersion = SIS_CURRENT_VERSION; pScrn->driverName = SIS_DRIVER_NAME; @@ -603,25 +876,255 @@ SISProbe(DriverPtr drv, int flags) pScrn->ValidMode = SISValidMode; foundScreen = TRUE; } +#ifdef SISDUALHEAD + pEnt = xf86GetEntityInfo(usedChips[i]); + + /* TW: I assume these chipsets as - basically - dual head capable. */ + if (pEnt->chipset == PCI_CHIP_SIS630 || pEnt->chipset == PCI_CHIP_SIS540 || + pEnt->chipset == PCI_CHIP_SIS650 || pEnt->chipset == PCI_CHIP_SIS550 || + pEnt->chipset == PCI_CHIP_SIS315 || pEnt->chipset == PCI_CHIP_SIS315H || + pEnt->chipset == PCI_CHIP_SIS315PRO || pEnt->chipset == PCI_CHIP_SIS330 || + pEnt->chipset == PCI_CHIP_SIS300) { + + SISEntPtr pSiSEnt = NULL; + DevUnion *pPriv; + + xf86SetEntitySharable(usedChips[i]); + if (SISEntityIndex < 0) + SISEntityIndex = xf86AllocateEntityPrivateIndex(); + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], SISEntityIndex); + if (!pPriv->ptr) { + pPriv->ptr = xnfcalloc(sizeof(SISEntRec), 1); + pSiSEnt = pPriv->ptr; + pSiSEnt->lastInstance = -1; + pSiSEnt->DisableDual = FALSE; + pSiSEnt->ErrorAfterFirst = FALSE; + pSiSEnt->MapCountIOBase = pSiSEnt->MapCountFbBase = 0; + pSiSEnt->FbBase = pSiSEnt->IOBase = NULL; + pSiSEnt->forceUnmapIOBase = FALSE; + pSiSEnt->forceUnmapFbBase = FALSE; +#ifdef __alpha__ + pSiSEnt->MapCountIOBaseDense = 0; + pSiSEnt->IOBaseDense = NULL; + pSiSEnt->forceUnmapIOBaseDense = FALSE; +#endif + } else { + pSiSEnt = pPriv->ptr; + } + pSiSEnt->lastInstance++; + xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0], + pSiSEnt->lastInstance); + } +#endif } xfree(usedChips); return foundScreen; } -#if 0 /* xf86ValidateModes() takes care of this */ -/* - * GetAccelPitchValues - - * - * This function returns a list of display width (pitch) values that can - * be used in accelerated mode. + +/* TW: If monitor section has no HSync/VRefresh data, + * derive it from DDC data. */ -static int -GetAccelPitchValues(ScrnInfoPtr pScrn) +static void +SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag) { - return ((pScrn->displayWidth + 7) & ~7); + MonPtr mon = pScrn->monitor; + xf86MonPtr ddc = mon->DDC; + int i,j; + float myhhigh, myhlow; + int myvhigh, myvlow; + unsigned char temp; + const myhddctiming myhtiming[11] = { + { 1, 0x20, 31.6 }, /* rounded up by .1 */ + { 1, 0x02, 35.3 }, + { 1, 0x04, 37.6 }, + { 1, 0x08, 38.0 }, + { 1, 0x01, 38.0 }, + { 2, 0x40, 47.0 }, + { 2, 0x80, 48.2 }, + { 2, 0x08, 48.5 }, + { 2, 0x04, 56.6 }, + { 2, 0x02, 60.1 }, + { 2, 0x01, 80.1 } + }; + const myvddctiming myvtiming[10] = { + { 1, 0x02, 56 }, + { 1, 0x01, 60 }, + { 2, 0x08, 60 }, + { 2, 0x04, 70 }, + { 1, 0x08, 72 }, + { 2, 0x80, 72 }, + { 1, 0x04, 75 }, + { 2, 0x40, 75 }, + { 2, 0x02, 75 }, + { 2, 0x01, 75 } + }; + /* "Future modes"; we only check the really high ones */ + const myddcstdmodes mystdmodes[8] = { + { 1280, 1024, 85, 91.1 }, + { 1600, 1200, 60, 75.0 }, + { 1600, 1200, 65, 81.3 }, + { 1600, 1200, 70, 87.5 }, + { 1600, 1200, 75, 93.8 }, + { 1600, 1200, 85, 106.3 }, + { 1920, 1440, 60, 90.0 }, + { 1920, 1440, 75, 112.5 } + }; + + if(flag) { /* HSync */ + for (i = 0; i < 4; i++) { + if (ddc->det_mon[i].type == DS_RANGES) { + mon->nHsync = 1; + mon->hsync[0].lo = ddc->det_mon[i].section.ranges.min_h; + mon->hsync[0].hi = ddc->det_mon[i].section.ranges.max_h; + return; + } + } + /* If no sync ranges detected in detailed timing table, we + * derive them from supported VESA modes. */ + myhlow = myhhigh = 0.0; + for(i=0; i<11; i++) { + if(myhtiming[i].whichone == 1) temp = ddc->timings1.t1; + else temp = ddc->timings1.t2; + if(temp & myhtiming[i].mask) { + if((i==0) || (myhlow > myhtiming[i].rate)) + myhlow = myhtiming[i].rate; + } + if(myhtiming[10-i].whichone == 1) temp = ddc->timings1.t1; + else temp = ddc->timings1.t2; + if(temp & myhtiming[10-i].mask) { + if((i==0) || (myhhigh < myhtiming[10-i].rate)) + myhhigh = myhtiming[10-i].rate; + } + } + for(i=0;i<STD_TIMINGS;i++) { + if(ddc->timings2[i].hsize > 256) { + for(j=0; j<8; j++) { + if((ddc->timings2[i].hsize == mystdmodes[j].hsize) && + (ddc->timings2[i].vsize == mystdmodes[j].vsize) && + (ddc->timings2[i].refresh == mystdmodes[j].refresh)) { + if(mystdmodes[j].hsync > myhhigh) + myhhigh = mystdmodes[j].hsync; + } + } + } + } + if((myhhigh) && (myhlow)) { + mon->nHsync = 1; + mon->hsync[0].lo = myhlow - 0.1; + mon->hsync[0].hi = myhhigh; + } + + + } else { /* Vrefresh */ + + for (i = 0; i < 4; i++) { + if (ddc->det_mon[i].type == DS_RANGES) { + mon->nVrefresh = 1; + mon->vrefresh[0].lo = ddc->det_mon[i].section.ranges.min_v; + mon->vrefresh[0].hi = ddc->det_mon[i].section.ranges.max_v; + return; + } + } + + myvlow = myvhigh = 0; + for(i=0; i<10; i++) { + if(myvtiming[i].whichone == 1) temp = ddc->timings1.t1; + else temp = ddc->timings1.t2; + if(temp & myvtiming[i].mask) { + if((i==0) || (myvlow > myvtiming[i].rate)) + myvlow = myvtiming[i].rate; + } + if(myvtiming[9-i].whichone == 1) temp = ddc->timings1.t1; + else temp = ddc->timings1.t2; + if(temp & myvtiming[9-i].mask) { + if((i==0) || (myvhigh < myvtiming[9-i].rate)) + myvhigh = myvtiming[9-i].rate; + } + } + for(i=0;i<STD_TIMINGS;i++) { + if(ddc->timings2[i].hsize > 256) { + for(j=0; j<8; j++) { + if((ddc->timings2[i].hsize == mystdmodes[j].hsize) && + (ddc->timings2[i].vsize == mystdmodes[j].vsize) && + (ddc->timings2[i].refresh == mystdmodes[j].refresh)) { + if(mystdmodes[j].refresh > myvhigh) + myvhigh = mystdmodes[j].refresh; + } + } + } + } + if((myvhigh) && (myvlow)) { + mon->nVrefresh = 1; + mon->vrefresh[0].lo = myvlow; + mon->vrefresh[0].hi = myvhigh; + } + + } } -#endif +static xf86MonPtr +SiSInternalDDC(ScrnInfoPtr pScrn, int crtno) +{ + SISPtr pSiS = SISPTR(pScrn); + USHORT temp, i; + unsigned char buffer[256]; + xf86MonPtr pMonitor = NULL; + + /* TW: If CRT1 is off, skip DDC */ + if((pSiS->CRT1off) && (!crtno)) return NULL; + + temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS, crtno, 0, &buffer[0]); + if((!temp) || (temp == 0xffff)) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "CRT%d DDC probing failed, now trying via VBE\n", crtno + 1); + return(NULL); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT%d DDC supported\n", crtno + 1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT%d DDC level: %s%s%s%s\n", + crtno + 1, + (temp & 0x1a) ? "" : "[none of the supported]", + (temp & 0x02) ? "2 " : "", + (temp & 0x08) ? "3 " : "", + (temp & 0x10) ? "4" : ""); + if(temp & 0x02) { + i = 3; /* Number of retrys */ + do { + temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS, crtno, 1, &buffer[0]); + } while((temp) && i--); + if(!temp) { + if((pMonitor = xf86InterpretEDID(pScrn->scrnIndex, &buffer[0]))) { + return(pMonitor); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "CRT%d DDC EDID corrupt\n", crtno + 1); + return(NULL); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "CRT%d DDC reading failed\n", crtno + 1); + return(NULL); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "DDC levels 3 and 4 not supported by this driver yet.\n"); + return(NULL); + } + } +} + +static xf86MonPtr +SiSDoPrivateDDC(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + +#ifdef SISDUALHEAD + if((pSiS->DualHeadMode) && (!pSiS->SecondHead)) + return(SiSInternalDDC(pScrn, 1)); + else +#endif + return(SiSInternalDDC(pScrn, 0)); +} /* Mandatory */ static Bool @@ -629,13 +1132,23 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) { SISPtr pSiS; MessageType from; - int vgaIOBase; - unsigned char unlock; + unsigned char usScratchCR17, CR5F; + unsigned char usScratchCR32; unsigned long int i; + int temp; ClockRangePtr clockRanges; char *mod = NULL; const char *Sym = NULL; int pix24flags; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = NULL; +#endif + DisplayModePtr first, p, n; + DisplayModePtr tempmode, delmode, mymodes; + unsigned char srlockReg,crlockReg; + unsigned char tempreg; + xf86MonPtr pMonitor = NULL; + Bool didddc2; vbeInfoPtr pVbe; VbeInfoBlock *vbe; @@ -643,9 +1156,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if (flags & PROBE_DETECT) { if (xf86LoadSubModule(pScrn, "vbe")) { int index = xf86GetEntityInfo(pScrn->entityList[0])->index; - if ((pVbe = VBEExtendedInit(NULL,index,SET_BIOS_SCRATCH - | RESTORE_BIOS_SCRATCH ))) { - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + if((pVbe = VBEInit(NULL,index))) { +#else + if((pVbe = VBEExtendedInit(NULL,index,0))) { +#endif + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); vbeFree(pVbe); } } @@ -656,78 +1173,166 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) * 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. + * be initialised here. xf86Screens[] is the array of all screens, + * (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. */ /* Check the number of entities, and fail if it isn't one. */ - if (pScrn->numEntities != 1) + if(pScrn->numEntities != 1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Number of entities is not 1\n"); return FALSE; + } /* The vgahw module should be loaded here when needed */ - if (!xf86LoadSubModule(pScrn, "vgahw")) + if(!xf86LoadSubModule(pScrn, "vgahw")) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not load vgahw module\n"); return FALSE; + } xf86LoaderReqSymLists(vgahwSymbols, NULL); - /* - * Allocate a vgaHWRec - */ - if (!vgaHWGetHWRec(pScrn)) - return FALSE; - - VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiS driver (31/01/03-1) by " + "Thomas Winischhofer <thomas@winischhofer.net>\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "See http://www.winischhofer.net/linuxsisvga.shtml " + "for documentation and updates\n"); - if (!vgaHWMapMem(pScrn)) + /* Allocate a vgaHWRec */ + if(!vgaHWGetHWRec(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not allocate VGA private\n"); return FALSE; - vgaHWGetIOBase(VGAHWPTR(pScrn)); - vgaIOBase = VGAHWPTR(pScrn)->IOBase; + } /* Allocate the SISRec driverPrivate */ - if (!SISGetRec(pScrn)) { + if(!SISGetRec(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not allocate memory for pSiS private\n"); return FALSE; } pSiS = SISPTR(pScrn); pSiS->pScrn = pScrn; +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + pSiS->IODBase = 0; +#else + pSiS->IODBase = pScrn->domainIOBase; +#endif + /* Get the entity, and make sure it is PCI. */ pSiS->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (pSiS->pEnt->location.type != BUS_PCI) + if(pSiS->pEnt->location.type != BUS_PCI) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Entity's bus type is not PCI\n"); + SISFreeRec(pScrn); return FALSE; + } + +#ifdef SISDUALHEAD + /* TW: Allocate an entity private if necessary */ + if(xf86IsEntityShared(pScrn->entityList[0])) { + pSiSEnt = xf86GetEntityPrivate(pScrn->entityList[0], + SISEntityIndex)->ptr; + pSiS->entityPrivate = pSiSEnt; + + /* TW: If something went wrong, quit here */ + if ((pSiSEnt->DisableDual) || (pSiSEnt->ErrorAfterFirst)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "First head encountered fatal error, can't continue\n"); + SISFreeRec(pScrn); + return FALSE; + } + } +#endif /* Find the PCI info for this screen */ pSiS->PciInfo = xf86GetPciInfoForEntity(pSiS->pEnt->index); - pSiS->PciTag = pciTag(pSiS->PciInfo->bus, pSiS->PciInfo->device, - pSiS->PciInfo->func); + pSiS->PciTag = pSiS->sishw_ext.PciTag = pciTag(pSiS->PciInfo->bus, + pSiS->PciInfo->device, pSiS->PciInfo->func); - /* - * XXX This could be refined if some VGA memory resources are not - * decoded in operating mode. + pSiS->Primary = xf86IsPrimaryPci(pSiS->PciInfo); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "This adapter is %s display adapter\n", + (pSiS->Primary ? "primary" : "secondary")); + + if(pSiS->Primary) { + VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */ + if(!vgaHWMapMem(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not map VGA memory\n"); + SISFreeRec(pScrn); + return FALSE; + } + } + vgaHWGetIOBase(VGAHWPTR(pScrn)); + + /* TW: We "patch" the PIOOffset inside vgaHW in order to force + * the vgaHW module to use our relocated i/o ports. */ + VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380; + + pSiS->pInt = NULL; + if(!pSiS->Primary) { +#if !defined(__alpha__) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Initializing display adapter through int10\n"); +#endif + if(xf86LoadSubModule(pScrn, "int10")) { + xf86LoaderReqSymLists(int10Symbols, NULL); +#if !defined(__alpha__) + pSiS->pInt = xf86InitInt10(pSiS->pEnt->index); +#endif + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not load int10 module\n"); + } + } + +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + { + resRange vgamem[] = { {ResShrMemBlock,0xA0000,0xAFFFF}, + {ResShrMemBlock,0xB0000,0xB7FFF}, + {ResShrMemBlock,0xB8000,0xBFFFF}, + _END }; + xf86SetOperatingState(vgamem, pSiS->pEnt->index, ResUnusedOpr); + } +#else xf86SetOperatingState(resVgaMem, pSiS->pEnt->index, ResUnusedOpr); +#endif /* Operations for which memory access is required */ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; - /* Operations for which I/O access is required (XXX check this) */ + /* Operations for which I/O access is required */ pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; /* The ramdac module should be loaded here when needed */ - if (!xf86LoadSubModule(pScrn, "ramdac")) + if(!xf86LoadSubModule(pScrn, "ramdac")) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not load ramdac module\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; + } xf86LoaderReqSymLists(ramdacSymbols, NULL); - /* sisSet pScrn->monitor */ + /* Set pScrn->monitor */ pScrn->monitor = pScrn->confScreen->monitor; /* * Set the Chipset and ChipRev, allowing config file entries to - * override. + * override. DANGEROUS! */ if (pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) { pScrn->chipset = pSiS->pEnt->device->chipset; @@ -752,6 +1357,34 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } else { pSiS->ChipRev = pSiS->PciInfo->chipRev; } + pSiS->sishw_ext.jChipRevision = pSiS->ChipRev; + + /* TW: Determine SiS6326 chiprevision. This is not yet used for + * anything, but it will as soon as I found out on which revisions + * the hardware video overlay really works. + * According to SiS the only differences are: + * Chip name Chip type TV-Out MPEG II decoder + * 6326 AGP Rev. G0/H0 no no + * 6326 DVD Rev. D2 yes yes + * 6326 Rev. Cx yes yes + */ + pSiS->SiS6326Flags = 0; + if(pSiS->Chipset == PCI_CHIP_SIS6326) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Chipset is SiS6326 %s (revision 0x%02x)\n", + (pSiS->ChipRev == 0xaf) ? "(Ax)" : + ((pSiS->ChipRev == 0x0a) ? "AGP (G0)" : + ((pSiS->ChipRev == 0x0b) ? "AGP (H0)" : + (((pSiS->ChipRev & 0xf0) == 0xd0) ? "DVD (Dx)" : + (((pSiS->ChipRev & 0xf0) == 0x90) ? "(9x)" : + (((pSiS->ChipRev & 0xf0) == 0xc0) ? "(Cx)" : + "(unknown)"))))), + pSiS->ChipRev); + if((pSiS->ChipRev != 0x0a) && (pSiS->ChipRev != 0x0b)) { + pSiS->SiS6326Flags |= SIS6326_HASTV; + } + } + /* * This shouldn't happen because such problems should be caught in @@ -760,96 +1393,453 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if (pScrn->chipset == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04X is not recognised\n", pSiS->Chipset); +#ifdef SISDUALHEAD + if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; } if (pSiS->Chipset < 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Chipset \"%s\" is not recognised\n", pScrn->chipset); +#ifdef SISDUALHEAD + if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; } + /* TW: Determine chipset and VGA engine type for new mode switching code */ + switch(pSiS->Chipset) { + case PCI_CHIP_SIS300: + pSiS->sishw_ext.jChipType = SIS_300; + pSiS->VGAEngine = SIS_300_VGA; + break; + case PCI_CHIP_SIS630: /* 630 + 730 */ + pSiS->sishw_ext.jChipType = SIS_630; + if(pciReadLong(0x00000000, 0x00) == 0x07301039) { + pSiS->sishw_ext.jChipType = SIS_730; + } + pSiS->VGAEngine = SIS_300_VGA; + break; + case PCI_CHIP_SIS540: + pSiS->sishw_ext.jChipType = SIS_540; + pSiS->VGAEngine = SIS_300_VGA; + break; + case PCI_CHIP_SIS315H: + pSiS->sishw_ext.jChipType = SIS_315H; + pSiS->VGAEngine = SIS_315_VGA; + break; + case PCI_CHIP_SIS315: + /* TW: Override for simplicity */ + pSiS->Chipset = PCI_CHIP_SIS315H; + pSiS->sishw_ext.jChipType = SIS_315; + pSiS->VGAEngine = SIS_315_VGA; + break; + case PCI_CHIP_SIS315PRO: + /* TW: Override for simplicity */ + pSiS->Chipset = PCI_CHIP_SIS315H; + pSiS->sishw_ext.jChipType = SIS_315PRO; + pSiS->VGAEngine = SIS_315_VGA; + break; + case PCI_CHIP_SIS550: + pSiS->sishw_ext.jChipType = SIS_550; + pSiS->VGAEngine = SIS_315_VGA; + break; + case PCI_CHIP_SIS650: /* 650 + 740 */ + pSiS->sishw_ext.jChipType = SIS_650; + pSiS->VGAEngine = SIS_315_VGA; + break; + case PCI_CHIP_SIS330: + pSiS->sishw_ext.jChipType = SIS_330; + pSiS->VGAEngine = SIS_315_VGA; + break; + case PCI_CHIP_SIS530: + pSiS->sishw_ext.jChipType = SIS_530; + pSiS->VGAEngine = SIS_530_VGA; + break; + default: + pSiS->sishw_ext.jChipType = SIS_OLD; + pSiS->VGAEngine = SIS_OLD_VGA; + break; + } + + /* TW: Now check if sisfb is loaded. Since sisfb only supports + * the 300 and 310/325 series, we only do this for these chips. + * We use this for checking where sisfb starts its memory + * heap in order to automatically detect the correct MaxXFBMem + * setting (which normally is given by the option of the same name). + * That only works if sisfb is completely running, ie with + * a video mode (because the fbdev will not be installed otherwise.) + */ + + pSiS->donttrustpdc = FALSE; + pSiS->sisfbpdc = 0; + + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + + int fd, i; + sisfb_info mysisfbinfo; + BOOL found = FALSE; + char name[10]; + + i=0; + do { + sprintf(name, "/dev/fb%1d", i); + if((fd = open(name, 'r'))) { + + if(!ioctl(fd, SISFB_GET_INFO, &mysisfbinfo)) { + + if(mysisfbinfo.sisfb_id == SISFB_ID) { + + if((mysisfbinfo.sisfb_version >= 1) && + (mysisfbinfo.sisfb_revision >=5) && + (mysisfbinfo.sisfb_patchlevel >= 8)) { + /* TW: Added PCI bus/slot/func into in sisfb Version 1.5.08. + Check this to make sure we run on the same card as sisfb + */ + if((mysisfbinfo.sisfb_pcibus == pSiS->PciInfo->bus) && + (mysisfbinfo.sisfb_pcislot == pSiS->PciInfo->device) && + (mysisfbinfo.sisfb_pcifunc == pSiS->PciInfo->func) ) { + found = TRUE; + } + } else found = TRUE; + + if(found) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "%s: SiS kernel fb driver (sisfb) %d.%d.%d detected (PCI: %02d:%02d.%d)\n", + &name[5], + mysisfbinfo.sisfb_version, + mysisfbinfo.sisfb_revision, + mysisfbinfo.sisfb_patchlevel, + pSiS->PciInfo->bus, + pSiS->PciInfo->device, + pSiS->PciInfo->func); + /* TW: Added version/rev/pl in sisfb 1.4.0 */ + if(mysisfbinfo.sisfb_version == 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Old version of sisfb found. Please update\n"); + } + pSiS->sisfbMem = mysisfbinfo.heapstart; + /* TW: Basically, we can't trust the pdc register if sisfb is loaded */ + pSiS->donttrustpdc = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "sisfb: memory heap starts at %dKB\n", pSiS->sisfbMem); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "sisfb: using video mode 0x%02x\n", mysisfbinfo.fbvidmode); + if((mysisfbinfo.sisfb_version >= 1) && + (mysisfbinfo.sisfb_revision >=5) && + (mysisfbinfo.sisfb_patchlevel >= 6)) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "sisfb: %sreserved hardware cursor, using %s command queue\n", + (mysisfbinfo.sisfb_caps & 0x80) ? "" : "not ", + (mysisfbinfo.sisfb_caps & 0x40) ? "SiS300 series Turbo" : + (mysisfbinfo.sisfb_caps & 0x20) ? "SiS310/325 series AGP" : + (mysisfbinfo.sisfb_caps & 0x10) ? "SiS310/325 series VRAM" : + (mysisfbinfo.sisfb_caps & 0x08) ? "SiS310/325 series MMIO" : + "no"); + } + if((mysisfbinfo.sisfb_version >= 1) && + (mysisfbinfo.sisfb_revision >=5) && + (mysisfbinfo.sisfb_patchlevel >= 10)) { + /* TW: We can trust the pdc value if sisfb is of recent version */ + pSiS->donttrustpdc = FALSE; + if(mysisfbinfo.sisfb_patchlevel >= 11) { + pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc; + } + } + } + } + } + close (fd); + } + i++; + + } while((i <= 7) && (!found)); + } /* * The first thing we should figure out is the depth, bpp, etc. - * Our default depth is 8, so pass it to the helper function. - * Our preference for depth 24 is 24bpp, so tell it that too. + * TW: Additionally, determine the size of the HWCursor memory + * area. */ - switch (pSiS->Chipset) { - case PCI_CHIP_SIS530: - pix24flags = Support32bppFb | Support24bppFb | - SupportConvert24to32 | SupportConvert32to24; - break; - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - pix24flags = Support32bppFb | SupportConvert24to32; - break; - default: - pix24flags = Support24bppFb | - SupportConvert32to24 | PreferConvert32to24; - break; + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + pSiS->CursorSize = 4096; + pix24flags = Support32bppFb | + SupportConvert24to32; + break; + case SIS_315_VGA: + pSiS->CursorSize = 16384; + pix24flags = Support32bppFb | + SupportConvert24to32; + break; + case SIS_530_VGA: + pSiS->CursorSize = 2048; + pix24flags = Support32bppFb | + Support24bppFb | + SupportConvert24to32 | + SupportConvert32to24; + break; + default: + pSiS->CursorSize = 2048; + pix24flags = Support24bppFb | + SupportConvert32to24 | + PreferConvert32to24; + break; } - if (!xf86SetDepthBpp(pScrn, 8, 8, 8, pix24flags)) +#ifdef SISDUALHEAD + /* TW: In case of Dual Head, we need to determine if we are the "master" head or + * the "slave" head. In order to do that, we set PrimInit to DONE in the + * shared entity at the end of the first initialization. The second + * initialization then knows that some things have already been done. THIS + * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER! + */ + + if(xf86IsEntityShared(pScrn->entityList[0])) { + if(pSiSEnt->lastInstance > 0) { + if(!xf86IsPrimInitDone(pScrn->entityList[0])) { + /* First Head (always CRT2) */ + pSiS->SecondHead = FALSE; + pSiSEnt->pScrn_1 = pScrn; + pSiSEnt->CRT1ModeNo = pSiSEnt->CRT2ModeNo = -1; + pSiS->DualHeadMode = TRUE; + pSiSEnt->DisableDual = FALSE; + pSiSEnt->BIOS = NULL; + pSiSEnt->SiS_Pr = NULL; + } else { + /* Second Head (always CRT1) */ + pSiS->SecondHead = TRUE; + pSiSEnt->pScrn_2 = pScrn; + pSiS->DualHeadMode = TRUE; + } + } else { + /* TW: Only one screen in config file - disable dual head mode */ + pSiS->SecondHead = FALSE; + pSiS->DualHeadMode = FALSE; + pSiSEnt->DisableDual = TRUE; + } + } else { + /* TW: Entity is not shared - disable dual head mode */ + pSiS->SecondHead = FALSE; + pSiS->DualHeadMode = FALSE; + } +#endif + + pSiS->ForceCursorOff = FALSE; + + /* TW: Allocate SiS_Private (for mode switching code) and initialize it */ + pSiS->SiS_Pr = NULL; +#ifdef SISDUALHEAD + if(pSiSEnt) { + if(pSiSEnt->SiS_Pr) pSiS->SiS_Pr = pSiSEnt->SiS_Pr; + } +#endif + if(!pSiS->SiS_Pr) { + if(!(pSiS->SiS_Pr = xnfcalloc(sizeof(SiS_Private), 1))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not allocate memory for SiS_Pr private\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); + return FALSE; + } +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->SiS_Pr = pSiS->SiS_Pr; +#endif + memset(pSiS->SiS_Pr, 0, sizeof(SiS_Private)); + } + pSiS->SiS_Pr->SiS_Backup70xx = 0xff; + pSiS->SiS_Pr->SiS_CHOverScan = -1; + pSiS->SiS_Pr->SiS_ChSW = FALSE; + pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE; + + /* TW: Get our relocated IO registers */ + pSiS->RelIO = (pSiS->PciInfo->ioBase[2] & 0xFFFC) + pSiS->IODBase; + pSiS->sishw_ext.ulIOAddress = pSiS->RelIO + 0x30; + xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n", + (unsigned long)pSiS->RelIO); + + /* TW: Initialize SiS Port Reg definitions for externally used + * BIOS emulation (init.c/init301.c) functions. + */ + SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO + 0x30); + + /* TW: The following identifies the old chipsets. This is only + * partly used since the really old chips are not supported, + * but I keep it here for future use. + */ + if(pSiS->VGAEngine == SIS_OLD_VGA || pSiS->VGAEngine == SIS_530_VGA) { + switch(pSiS->Chipset) { + case PCI_CHIP_SG86C205: /* Just for making it complete */ + { + unsigned char temp; + sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg); + inSISIDXREG(SISSR, 0x10, temp); + if(temp & 0x80) pSiS->oldChipset = OC_SIS6205B; + else pSiS->oldChipset = (pSiS->ChipRev == 0x11) ? + OC_SIS6205C : OC_SIS6205A; + break; + } + case PCI_CHIP_SIS82C204: /* Just for making it complete */ + pSiS->oldChipset = OC_SIS82204; break; + case 0x6225: /* Just for making it complete */ + pSiS->oldChipset = OC_SIS6225; break; + case PCI_CHIP_SIS5597: + pSiS->oldChipset = OC_SIS5597; break; + case PCI_CHIP_SIS6326: + pSiS->oldChipset = OC_SIS6326; break; + case PCI_CHIP_SIS530: + if((pSiS->ChipRev & 0x0f) < 0x0a) + pSiS->oldChipset = OC_SIS530A; + else pSiS->oldChipset = OC_SIS530B; + break; + default: + pSiS->oldChipset = OC_UNKNOWN; + } + } + + if(!xf86SetDepthBpp(pScrn, 8, 8, 8, pix24flags)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86SetDepthBpp() error\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; + } /* Check that the returned depth is one we support */ - switch (pScrn->depth) { - case 8: - case 15: - case 16: - case 24: - /* OK */ + temp = 0; + switch(pScrn->depth) { + case 8: + case 16: + case 24: break; - default: + case 15: + if((pSiS->VGAEngine == SIS_300_VGA) || + (pSiS->VGAEngine == SIS_315_VGA)) + temp = 1; + break; + default: + temp = 1; + } + + if(temp) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Given depth (%d) is not supported by this driver\n", + "Given depth (%d) is not supported by this driver/chipset\n", pScrn->depth); + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; } xf86PrintDepthBpp(pScrn); /* Get the depth24 pixmap format */ - if (pScrn->depth == 24 && pix24bpp == 0) + if(pScrn->depth == 24 && pix24bpp == 0) pix24bpp = xf86GetBppFromDepth(pScrn, 24); /* * This must happen after pScrn->display has been set because * xf86SetWeight references it. */ - if (pScrn->depth > 8) { + if(pScrn->depth > 8) { /* The defaults are OK for us */ rgb zeros = {0, 0, 0}; - if (!xf86SetWeight(pScrn, zeros, zeros)) { + if(!xf86SetWeight(pScrn, zeros, zeros)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86SetWeight() error\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; } else { - /* XXX check that weight returned is supported */ - ; + Bool ret = FALSE; + switch(pScrn->depth) { + case 15: + if((pScrn->weight.red != 5) || + (pScrn->weight.green != 5) || + (pScrn->weight.blue != 5)) ret = TRUE; + break; + case 16: + if((pScrn->weight.red != 5) || + (pScrn->weight.green != 6) || + (pScrn->weight.blue != 5)) ret = TRUE; + break; + case 24: + if((pScrn->weight.red != 8) || + (pScrn->weight.green != 8) || + (pScrn->weight.blue != 8)) ret = TRUE; + break; + } + if(ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "RGB Weight %d%d%d at depth %d not supported by hardware\n", + pScrn->weight.red, pScrn->weight.green, + pScrn->weight.blue, pScrn->depth); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); + return FALSE; + } } } - if (!xf86SetDefaultVisual(pScrn, -1)) { + /* TW: Set the current layout parameters */ + pSiS->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; + pSiS->CurrentLayout.depth = pScrn->depth; + /* (Inside this function, we can use pScrn's contents anyway) */ + + if(!xf86SetDefaultVisual(pScrn, -1)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86SetDefaultVisual() error\n"); +#ifdef SISDUALHEAD + if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; } else { - /* We don't currently support DirectColor at > 8bpp */ + /* We don't 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", + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual " + "(%s) is not supported at depth %d\n", xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); +#ifdef SISDUALHEAD + if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; } } /* - * The new cmap layer needs this to be initialised. + * The cmap layer needs this to be initialised. */ - { Gamma zeros = {0.0, 0.0, 0.0}; - if (!xf86SetGamma(pScrn, zeros)) { + if(!xf86SetGamma(pScrn, zeros)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86SetGamma() error\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + SISFreeRec(pScrn); return FALSE; } } @@ -858,29 +1848,422 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pScrn->progClock = TRUE; /* Set the bits per RGB for 8bpp mode */ - if (pScrn->depth == 8) { + if(pScrn->depth == 8) { pScrn->rgbBits = 6; } - pSiS->ddc1Read = SiSddc1Read; /* this cap will be modified */ + pSiS->ddc1Read = SiSddc1Read; from = X_DEFAULT; - outb(VGA_SEQ_INDEX, 0x05); unlock = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); /* Unlock registers */ + /* Unlock registers */ + sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg); + + /* TW: We need no backup area (300/310/325 new mode switching code) */ + pSiS->sishw_ext.pSR = NULL; + pSiS->sishw_ext.pCR = NULL; + + /* TW: Read BIOS for 300 and 310/325 series customization */ + pSiS->sishw_ext.pjVirtualRomBase = NULL; + pSiS->BIOS = NULL; + pSiS->sishw_ext.UseROM = FALSE; + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { +#ifdef SISDUALHEAD + if(pSiSEnt) { + if(pSiSEnt->BIOS) { + pSiS->BIOS = pSiSEnt->BIOS; + pSiS->sishw_ext.pjVirtualRomBase = pSiS->BIOS; + } + } +#endif + if(!pSiS->BIOS) { + if(!(pSiS->BIOS = xcalloc(1, BIOS_SIZE))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not allocate memory for video BIOS image\n"); + } else { + unsigned long segstart; + unsigned short romptr; + BOOLEAN found; + int i; + static const char sis_rom_sig[] = "Silicon Integrated Systems"; + static const char *sis_sig[10] = { + "300", "540", "630", "730", + "315", "315", "315", "5315", "6325", + "Xabre" + }; + static const unsigned short sis_nums[10] = { + SIS_300, SIS_540, SIS_630, SIS_730, + SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, + SIS_330 + }; + + found = FALSE; + for(segstart=BIOS_BASE; segstart<0x000f0000; segstart+=0x00001000) { + +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + if(xf86ReadBIOS(segstart, 0, pSiS->BIOS, BIOS_SIZE) != BIOS_SIZE) continue; +#else + if(xf86ReadDomainMemory(pSiS->PciTag, segstart, BIOS_SIZE, pSiS->BIOS) != BIOS_SIZE) continue; +#endif - /* get VBIOS image */ - if (!(pSiS->BIOS=xcalloc(1, BIOS_SIZE))) { - ErrorF("Allocate memory fail !!\n"); - return FALSE; - } - if (xf86ReadDomainMemory(pSiS->PciTag, BIOS_BASE, BIOS_SIZE, pSiS->BIOS) != BIOS_SIZE) { - xfree(pSiS->BIOS); - ErrorF("Read VBIOS image fail !!\n"); - return FALSE; + if((pSiS->BIOS[0] != 0x55) || (pSiS->BIOS[1] != 0xaa)) continue; + + romptr = pSiS->BIOS[0x12] | (pSiS->BIOS[0x13] << 8); + if(romptr > (BIOS_SIZE - strlen(sis_rom_sig))) continue; + if(strncmp(sis_rom_sig, (char *)&pSiS->BIOS[romptr], strlen(sis_rom_sig)) != 0) continue; + + romptr = pSiS->BIOS[0x14] | (pSiS->BIOS[0x15] << 8); + if(romptr > (BIOS_SIZE - 5)) continue; + for(i = 0; (i < 10) && (!found); i++) { + if(strncmp(sis_sig[i], (char *)&pSiS->BIOS[romptr], strlen(sis_sig[i])) == 0) { + if(sis_nums[i] == pSiS->sishw_ext.jChipType) { + found = TRUE; + break; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Ignoring BIOS for SiS %s at %p\n", sis_sig[i], segstart); + } + } + } + if(found) break; + } + + if(!found) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not find/read video BIOS\n"); + xfree(pSiS->BIOS); + pSiS->BIOS = NULL; + } else { +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->BIOS = pSiS->BIOS; +#endif + pSiS->sishw_ext.pjVirtualRomBase = pSiS->BIOS; + romptr = pSiS->BIOS[0x16] | (pSiS->BIOS[0x17] << 8); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Video BIOS version \"%7s\" found at %p\n", + &pSiS->BIOS[romptr], segstart); + } + + } + } + if(pSiS->BIOS) pSiS->sishw_ext.UseROM = TRUE; + else pSiS->sishw_ext.UseROM = FALSE; } + /* Evaluate options */ SiSOptions(pScrn); + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!pSiS->SecondHead) { + /* TW: Copy some option settings to entity private */ + pSiSEnt->HWCursor = pSiS->HWCursor; + pSiSEnt->ForceCRT2Type = pSiS->ForceCRT2Type; + pSiSEnt->ForceTVType = pSiS->ForceTVType; + pSiSEnt->TurboQueue = pSiS->TurboQueue; + pSiSEnt->PDC = pSiS->PDC; + pSiSEnt->OptTVStand = pSiS->OptTVStand; + pSiSEnt->NonDefaultPAL = pSiS->NonDefaultPAL; + pSiSEnt->OptTVOver = pSiS->OptTVOver; + pSiSEnt->OptTVSOver = pSiS->OptTVSOver; + pSiSEnt->OptROMUsage = pSiS->OptROMUsage; + pSiSEnt->DSTN = pSiS->DSTN; + pSiSEnt->XvOnCRT2 = pSiS->XvOnCRT2; + pSiSEnt->NoAccel = pSiS->NoAccel; + pSiSEnt->NoXvideo = pSiS->NoXvideo; + pSiSEnt->forceCRT1 = pSiS->forceCRT1; + pSiSEnt->chtvlumabandwidthcvbs = pSiS->chtvlumabandwidthcvbs; + pSiSEnt->chtvlumabandwidthsvideo = pSiS->chtvlumabandwidthsvideo; + pSiSEnt->chtvlumaflickerfilter = pSiS->chtvlumaflickerfilter; + pSiSEnt->chtvchromabandwidth = pSiS->chtvchromabandwidth; + pSiSEnt->chtvchromaflickerfilter = pSiS->chtvchromaflickerfilter; + pSiSEnt->chtvtextenhance = pSiS->chtvtextenhance; + pSiSEnt->chtvcontrast = pSiS->chtvcontrast; + pSiSEnt->chtvcvbscolor = pSiS->chtvcvbscolor; + pSiSEnt->sistvedgeenhance = pSiS->sistvedgeenhance; + pSiSEnt->sistvantiflicker = pSiS->sistvantiflicker; + pSiSEnt->sistvsaturation = pSiS->sistvsaturation; + pSiSEnt->tvxpos = pSiS->tvxpos; + pSiSEnt->tvypos = pSiS->tvypos; + pSiSEnt->restorebyset = pSiS->restorebyset; + } else { + /* We always use same cursor type on both screens */ + if(pSiS->HWCursor != pSiSEnt->HWCursor) { + pSiS->HWCursor = pSiSEnt->HWCursor; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent HWCursor setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: HWCursor shall be %s\n", + pSiS->HWCursor ? "enabled" : "disabled"); + } + /* We need to use identical CRT2 Type setting */ + if(pSiS->ForceCRT2Type != pSiSEnt->ForceCRT2Type) { + if(pSiS->ForceCRT2Type != CRT2_DEFAULT) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Ignoring inconsistent ForceCRT2Type setting. Master head rules\n"); + } + pSiS->ForceCRT2Type = pSiSEnt->ForceCRT2Type; + } + if(pSiS->ForceTVType != pSiSEnt->ForceTVType) { + if(pSiS->ForceTVType != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Ignoring inconsistent ForceTVType setting. Master head rules\n"); + } + pSiS->ForceTVType = pSiSEnt->ForceTVType; + } + /* We need identical TurboQueue setting */ + if(pSiS->TurboQueue != pSiSEnt->TurboQueue) { + pSiS->TurboQueue = pSiSEnt->TurboQueue; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent TurboQueue setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: Turboqueue shall be %s\n", + pSiS->TurboQueue ? "enabled" : "disabled"); + } + /* We need identical PDC setting */ + if(pSiS->PDC != pSiSEnt->PDC) { + pSiS->PDC = pSiSEnt->PDC; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent PanelDelayCompensation setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: PanelDelayCompensation shall be %d%s\n", + pSiS->PDC, + (pSiS->PDC == -1) ? " (autodetected)" : ""); + } + /* We need identical TVStandard setting */ + if( (pSiS->OptTVStand != pSiSEnt->OptTVStand) || + (pSiS->NonDefaultPAL != pSiSEnt->NonDefaultPAL) ) { + if(pSiS->OptTVStand != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent TVStandard setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: TVStandard shall be %s\n", + (pSiSEnt->OptTVStand ? + ( (pSiSEnt->NonDefaultPAL == -1) ? "PAL" : + ((pSiSEnt->NonDefaultPAL) ? "PALM" : "PALN") ) + : "NTSC")); + } + pSiS->OptTVStand = pSiSEnt->OptTVStand; + pSiS->NonDefaultPAL = pSiSEnt->NonDefaultPAL; + } + /* We need identical UseROMData setting */ + if(pSiS->OptROMUsage != pSiSEnt->OptROMUsage) { + if(pSiS->OptROMUsage != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent UseROMData setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: Video ROM data usage shall be %s\n", + pSiSEnt->OptROMUsage ? "enabled" : "disabled"); + } + pSiS->OptROMUsage = pSiSEnt->OptROMUsage; + } + /* We need identical DSTN setting */ + if(pSiS->DSTN != pSiSEnt->DSTN) { + pSiS->DSTN = pSiSEnt->DSTN; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent DSTN setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: DSTN shall be %s\n", + pSiS->DSTN ? "enabled" : "disabled"); + } + /* We need identical XvOnCRT2 setting */ + if(pSiS->XvOnCRT2 != pSiSEnt->XvOnCRT2) { + pSiS->XvOnCRT2 = pSiSEnt->XvOnCRT2; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent XvOnCRT2 setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: Xv shall be used on CRT%d\n", + pSiS->XvOnCRT2 ? 2 : 1); + } + /* We need identical NoAccel setting */ + if(pSiS->NoAccel != pSiSEnt->NoAccel) { + pSiS->NoAccel = pSiSEnt->NoAccel; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent NoAccel setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: Acceleration shall be %s\n", + pSiS->NoAccel ? "disabled" : "enabled"); + } + /* We need identical ForceCRT1 setting */ + if(pSiS->forceCRT1 != pSiSEnt->forceCRT1) { + if(pSiS->forceCRT1 != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent ForceCRT1 setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: CRT1 shall be %s\n", + pSiSEnt->forceCRT1 ? "enabled" : "disabled"); + } + pSiS->forceCRT1 = pSiSEnt->forceCRT1; + } + /* We need identical TVOverscan setting */ + if(pSiS->OptTVOver != pSiSEnt->OptTVOver) { + if(pSiS->OptTVOver != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVOverscan setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: CHTVOverscan shall be %s\n", + pSiSEnt->OptTVOver ? "true (=overscan)" : "false (=underscan)"); + } + pSiS->OptTVOver = pSiSEnt->OptTVOver; + } + /* We need identical TVSOverscan setting */ + if(pSiS->OptTVSOver != pSiSEnt->OptTVSOver) { + if(pSiS->OptTVSOver != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVSuperOverscan setting\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Master head ruled: CHTVSuperOverscan shall be %s\n", + pSiSEnt->OptTVSOver ? "true" : "false"); + } + pSiS->OptTVSOver = pSiSEnt->OptTVSOver; + } + /* We need identical TV settings */ + if(pSiS->chtvtype != pSiSEnt->chtvtype) { + if(pSiS->chtvtype != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVType setting; set to %s\n", + (pSiSEnt->chtvtype) ? "SCART" : "HDTV"); + } + pSiS->chtvtype = pSiSEnt->chtvtype; + } + if(pSiS->chtvlumabandwidthcvbs != pSiSEnt->chtvlumabandwidthcvbs) { + if(pSiS->chtvlumabandwidthcvbs != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVLumaBandWidthCVBS setting; set to %d\n", + pSiSEnt->chtvlumabandwidthcvbs); + } + pSiS->chtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs; + } + if(pSiS->chtvlumabandwidthsvideo != pSiSEnt->chtvlumabandwidthsvideo) { + if(pSiS->chtvlumabandwidthsvideo != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVLumaBandWidthSVIDEO setting; set to %d\n", + pSiSEnt->chtvlumabandwidthsvideo); + } + pSiS->chtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo; + } + if(pSiS->chtvlumaflickerfilter != pSiSEnt->chtvlumaflickerfilter) { + if(pSiS->chtvlumaflickerfilter != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVLumaFlickerFilter setting; set to %d\n", + pSiSEnt->chtvlumaflickerfilter); + } + pSiS->chtvlumaflickerfilter = pSiSEnt->chtvlumaflickerfilter; + } + if(pSiS->chtvchromabandwidth != pSiSEnt->chtvchromabandwidth) { + if(pSiS->chtvchromabandwidth != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVChromaBandWidth setting; set to %d\n", + pSiSEnt->chtvchromabandwidth); + } + pSiS->chtvchromabandwidth = pSiSEnt->chtvchromabandwidth; + } + if(pSiS->chtvchromaflickerfilter != pSiSEnt->chtvchromaflickerfilter) { + if(pSiS->chtvchromaflickerfilter != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVChromaFlickerFilter setting; set to %d\n", + pSiSEnt->chtvchromaflickerfilter); + } + pSiS->chtvchromaflickerfilter = pSiSEnt->chtvchromaflickerfilter; + } + if(pSiS->chtvcvbscolor != pSiSEnt->chtvcvbscolor) { + if(pSiS->chtvcvbscolor != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVCVBSColor setting; set to %s\n", + pSiSEnt->chtvcvbscolor ? "true" : "false"); + } + pSiS->chtvcvbscolor = pSiSEnt->chtvcvbscolor; + } + if(pSiS->chtvtextenhance != pSiSEnt->chtvtextenhance) { + if(pSiS->chtvtextenhance != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVTextEnhance setting; set to %d\n", + pSiSEnt->chtvtextenhance); + } + pSiS->chtvtextenhance = pSiSEnt->chtvtextenhance; + } + if(pSiS->chtvcontrast != pSiSEnt->chtvcontrast) { + if(pSiS->chtvcontrast != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent CHTVContrast setting; set to %d\n", + pSiSEnt->chtvcontrast); + } + pSiS->chtvcontrast = pSiSEnt->chtvcontrast; + } + if(pSiS->sistvedgeenhance != pSiSEnt->sistvedgeenhance) { + if(pSiS->sistvedgeenhance != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent SISTVEdgeEnhance setting; set to %d\n", + pSiSEnt->sistvedgeenhance); + } + pSiS->sistvedgeenhance = pSiSEnt->sistvedgeenhance; + } + if(pSiS->sistvantiflicker != pSiSEnt->sistvantiflicker) { + if(pSiS->sistvantiflicker != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent SISTVAntiFlicker setting; set to %d\n", + pSiSEnt->sistvantiflicker); + } + pSiS->sistvantiflicker = pSiSEnt->sistvantiflicker; + } + if(pSiS->sistvsaturation != pSiSEnt->sistvsaturation) { + if(pSiS->sistvsaturation != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent SISTVSaturation setting; set to %d\n", + pSiSEnt->sistvsaturation); + } + pSiS->sistvsaturation = pSiSEnt->sistvsaturation; + } + if(pSiS->tvxpos != pSiSEnt->tvxpos) { + if(pSiS->tvxpos != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent TVXPosOffset setting; set to %d\n", + pSiSEnt->tvxpos); + } + pSiS->tvxpos = pSiSEnt->tvxpos; + } + if(pSiS->tvypos != pSiSEnt->tvypos) { + if(pSiS->tvypos != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Ignoring inconsistent TVYPosOffset setting; set to %d\n", + pSiSEnt->tvypos); + } + pSiS->tvypos = pSiSEnt->tvypos; + } + if(pSiS->restorebyset != pSiSEnt->restorebyset) { + pSiS->restorebyset = pSiSEnt->restorebyset; + } + } + } +#endif + /* TW: Handle UseROMData and NoOEM options */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + from = X_PROBED; + if(pSiS->OptROMUsage == 0) { + pSiS->sishw_ext.UseROM = FALSE; + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Video ROM data usage is %s\n", + pSiS->sishw_ext.UseROM ? "enabled" : "disabled"); + + if(!pSiS->OptUseOEM) + xf86DrvMsg(pScrn->scrnIndex, from, "Internal OEM LCD/TV data usage is disabled\n"); + + if(pSiS->sbiosn) { + if(pSiS->BIOS) { + FILE *fd = NULL; + int i; + if((fd = fopen(pSiS->sbiosn, "w" ))) { + i = fwrite(pSiS->BIOS, 65536, 1, fd); + fclose(fd); + } + } + xfree(pSiS->sbiosn); + } + } + + /* Do basic configuration */ SiSSetup(pScrn); from = X_PROBED; @@ -895,7 +2278,15 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->FbAddress = pSiS->PciInfo->memBase[0] & 0xFFFFFFF0; } - xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + pSiS->realFbAddress = pSiS->FbAddress; + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) + xf86DrvMsg(pScrn->scrnIndex, from, "Global linear framebuffer at 0x%lX\n", + (unsigned long)pSiS->FbAddress); + else +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", (unsigned long)pSiS->FbAddress); if (pSiS->pEnt->device->IOBase != 0) { @@ -909,18 +2300,20 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->IOAddress = pSiS->PciInfo->memBase[1] & 0xFFFFFFF0; } - from = X_PROBED; xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", (unsigned long)pSiS->IOAddress); - - pSiS->RelIO = pSiS->PciInfo->ioBase[2] & 0xFFFC; - xf86DrvMsg(pScrn->scrnIndex, from, "Relocate IO registers at 0x%lX\n", - (unsigned long)pSiS->RelIO); + pSiS->sishw_ext.bIntegratedMMEnabled = TRUE; /* Register the PCI-assigned resources. */ - if (xf86RegisterResources(pSiS->pEnt->index, NULL, ResExclusive)) { + if(xf86RegisterResources(pSiS->pEnt->index, NULL, ResExclusive)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86RegisterResources() found resource conflicts\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); + SISFreeRec(pScrn); return FALSE; } @@ -930,78 +2323,299 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) from = X_CONFIG; } - if ((pSiS->Chipset == PCI_CHIP_SIS6326) - && (pScrn->videoRam >= 8192) + pSiS->RealVideoRam = pScrn->videoRam; + if((pSiS->Chipset == PCI_CHIP_SIS6326) + && (pScrn->videoRam > 4096) && (from != X_CONFIG)) { pScrn->videoRam = 4096; - xf86DrvMsg(pScrn->scrnIndex, from, "Limiting VideoRAM to %d KB\n", - pScrn->videoRam); + xf86DrvMsg(pScrn->scrnIndex, from, + "SiS6326: Detected %d KB VideoRAM, limiting to %d KB\n", + pSiS->RealVideoRam, pScrn->videoRam); } else xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n", pScrn->videoRam); - /* - * TW: New option: limit size of framebuffer memory for avoiding - * clash with DRI: - * Kernel framebuffer driver (sisfb) starts its memory heap - * at 8MB if it detects more VideoRAM than that(otherwise at 4MB). - * Therefore a setting of 8192 is recommended if DRI is - * to be used when there's more than 8MB video RAM available. - * This option can be left out if DRI is not to be used. - * Attention: TurboQueue and HWCursor should use videoRam value, - * not FbMapSize; these two are always located at the very top - * of the videoRAM. Both are already initialized by framebuffer - * driver, so they should not wander around while starting X. + if((pSiS->Chipset == PCI_CHIP_SIS6326) && + (pScrn->videoRam > 4096)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiS6326 engines do not support more than 4096KB RAM, therefore\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "TurboQueue, HWCursor, 2D acceleration and XVideo are disabled.\n"); + pSiS->TurboQueue = FALSE; + pSiS->HWCursor = FALSE; + pSiS->NoXvideo = TRUE; + pSiS->NoAccel = TRUE; + } + + pSiS->FbMapSize = pSiS->availMem = pScrn->videoRam * 1024; + pSiS->sishw_ext.ulVideoMemorySize = pScrn->videoRam * 1024; + pSiS->sishw_ext.bSkipDramSizing = TRUE; + + /* TW: Calculate real availMem according to Accel/TurboQueue and + * HWCursur setting. Also, initialize some variables used + * in other modules. */ + pSiS->cursorOffset = 0; + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + pSiS->TurboQueueLen = 512; + if(pSiS->TurboQueue) { + pSiS->availMem -= (pSiS->TurboQueueLen*1024); + pSiS->cursorOffset = 512; + } + if(pSiS->HWCursor) { + pSiS->availMem -= pSiS->CursorSize; + if(pSiS->OptUseColorCursor) pSiS->availMem -= pSiS->CursorSize; + } + pSiS->CmdQueLenMask = 0xFFFF; + pSiS->CmdQueLenFix = 0; + pSiS->cursorBufferNum = 0; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->cursorBufferNum = 0; +#endif + break; + case SIS_315_VGA: + if(pSiS->TurboQueue) { + pSiS->availMem -= (512*1024); /* Command Queue is 512k */ + pSiS->cursorOffset = 512; + } + if(pSiS->HWCursor) { + pSiS->availMem -= pSiS->CursorSize; + if(pSiS->OptUseColorCursor) pSiS->availMem -= pSiS->CursorSize; + } + pSiS->cursorBufferNum = 0; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->cursorBufferNum = 0; +#endif + break; + default: + /* TW: cursorOffset not used in cursor functions for 530 and + * older chips, because the cursor is *above* the TQ. + * On 5597 and older revisions of the 6326, the TQ is + * max 32K, on newer 6326 revisions and the 530 either 30 + * (or 32?) or 62K (or 64?). However, to make sure, we + * use only 30K (or 32?), but reduce the available memory + * by 64, and locate the TQ at the beginning of this last + * 64K block. (We do this that way even when using the + * HWCursor, because the cursor only takes 2K, and the queue + * does not seem to last that far anyway.) + * The TQ must be located at 32KB boundaries. + */ + if(pSiS->RealVideoRam < 3072) { + if(pSiS->TurboQueue) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not enough video RAM for TurboQueue. TurboQueue disabled\n"); + } + pSiS->TurboQueue = FALSE; + } + pSiS->CmdQueMaxLen = 32; + if(pSiS->TurboQueue) { + pSiS->availMem -= (64*1024); + pSiS->CmdQueMaxLen = 900; /* TW: To make sure; should be 992 */ + } else if (pSiS->HWCursor) { + pSiS->availMem -= pSiS->CursorSize; + } + if(pSiS->Chipset == PCI_CHIP_SIS530) { + /* TW: Check if Flat Panel is enabled */ + inSISIDXREG(SISSR, 0x0e, tempreg); + if(!tempreg & 0x04) pSiS->availMem -= pSiS->CursorSize; - pSiS->FbMapSize = pScrn->videoRam * 1024; - /* TW: Touching FbMapSize doesn't work; now use maxxfbmem in accel*.c */ + /* TW: Set up mask for MMIO register */ + pSiS->CmdQueLenMask = (pSiS->TurboQueue) ? 0x1FFF : 0x00FF; + } else { + /* TW: TQ is never used on 6326/5597, because the accelerator + * always Syncs. So this is just cosmentic work. (And I + * am not even sure that 0x7fff is correct. MMIO 0x83a8 + * holds 0xec0 if (30k) TQ is enabled, 0x20 if TQ disabled. + * The datasheet has no real explanation on the queue length + * if the TQ is enabled. Not syncing and waiting for a + * suitable queue length instead does not work. + */ + pSiS->CmdQueLenMask = (pSiS->TurboQueue) ? 0x7FFF : 0x003F; + } - if (pSiS->maxxfbmem) { - if (pSiS->maxxfbmem > pSiS->FbMapSize) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n"); - pSiS->maxxfbmem = pSiS->FbMapSize; + /* TW: This is to be subtracted from MMIO queue length register contents + * for getting the real Queue length. + */ + pSiS->CmdQueLenFix = (pSiS->TurboQueue) ? 32 : 0; + } + +#ifdef SISDUALHEAD + /* TW: In dual head mode, we share availMem equally - so align it + * to 8KB; this way, the address of the FB of the second + * head is aligned to 4KB for mapping. + */ + if (pSiS->DualHeadMode) + pSiS->availMem &= 0xFFFFE000; +#endif + + /* TW: Check MaxXFBMem setting */ +#ifdef SISDUALHEAD + /* TW: Since DRI is not supported in dual head mode, we + don't need MaxXFBMem setting. */ + if (pSiS->DualHeadMode) { + if(pSiS->maxxfbmem) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n"); + } + pSiS->maxxfbmem = pSiS->availMem; + } else +#endif + if (pSiS->maxxfbmem) { + if (pSiS->maxxfbmem > pSiS->availMem) { + if (pSiS->sisfbMem) { + pSiS->maxxfbmem = pSiS->sisfbMem * 1024; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Invalid MaxXFBMem setting. Using sisfb heap start information\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n"); + pSiS->maxxfbmem = pSiS->availMem; + } + } else if (pSiS->sisfbMem) { + if (pSiS->maxxfbmem > pSiS->sisfbMem * 1024) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MaxXFBMem beyond sisfb heap start. Using sisfb heap start information\n"); + pSiS->maxxfbmem = pSiS->sisfbMem * 1024; + } } - } else pSiS->maxxfbmem = pSiS->FbMapSize; + } else if (pSiS->sisfbMem) { + pSiS->maxxfbmem = pSiS->sisfbMem * 1024; + } + else pSiS->maxxfbmem = pSiS->availMem; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %dK of framebuffer memory\n", + pSiS->maxxfbmem / 1024); + + /* TW: Check if the chipset supports two video overlays */ + pSiS->Flags650 = 0; + if ( (!pSiS->NoXvideo) && + ( pSiS->VGAEngine == SIS_300_VGA || + pSiS->VGAEngine == SIS_315_VGA || + pSiS->Chipset == PCI_CHIP_SIS530 || + pSiS->Chipset == PCI_CHIP_SIS6326 || + pSiS->Chipset == PCI_CHIP_SIS5597 ) ) { + pSiS->hasTwoOverlays = FALSE; + switch (pSiS->Chipset) { + case PCI_CHIP_SIS300: + case PCI_CHIP_SIS630: + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS330: /* ? */ + pSiS->hasTwoOverlays = TRUE; + break; + case PCI_CHIP_SIS650: + { + static const char *id650str[] = { + "0", "0", "0", "0", + "0 A0 AA", "0 A2 CA", "0", "0", + "0M A0", "0M A1 AA", "1 A0 AA", "1 A1 AA" + "0", "0", "0", "0" + }; + inSISIDXREG(SISCR, 0x5F, CR5F); + CR5F &= 0xf0; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "SiS650 revision ID %x (SiS65%s)\n", CR5F, id650str[CR5F >> 4]); + if((CR5F == 0x80) || (CR5F == 0x90) || (CR5F == 0xa0) || (CR5F == 0xb0)) { + pSiS->hasTwoOverlays = TRUE; /* TW: This is an M650 or 651 */ + pSiS->Flags650 |= SiS650_LARGEOVERLAY; + } + break; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Hardware supports %s video overlay%s\n", + pSiS->hasTwoOverlays ? "two" : "one", + pSiS->hasTwoOverlays ? "s" : ""); + } + + /* TW: Backup VB connection and CRT1 on/off register */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + inSISIDXREG(SISCR, 0x32, pSiS->oldCR32); + inSISIDXREG(SISCR, 0x17, pSiS->oldCR17); + pSiS->postVBCR32 = pSiS->oldCR32; + } - /* TW: Detect video bridge */ + if(pSiS->forceCRT1 != -1) { + if(pSiS->forceCRT1) pSiS->CRT1off = 0; + else pSiS->CRT1off = 1; + } else pSiS->CRT1off = -1; + + /* TW: There are some strange machines out there which require a special + * manupulation of ISA bridge registers in order to make the Chrontel + * work. Try to find out if we're running on such a machine. + */ + pSiS->SiS_Pr->SiS_ChSW = FALSE; + if(pSiS->Chipset == PCI_CHIP_SIS630) { + int i=0; + do { + if(mychswtable[i].subsysVendor == pSiS->PciInfo->subsysVendor && + mychswtable[i].subsysCard == pSiS->PciInfo->subsysCard) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI card/vendor found in list for Chrontel/ISA bridge poking\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Vendor: %s (ID %04x)\n", + mychswtable[i].vendorName, pSiS->PciInfo->subsysCard); + pSiS->SiS_Pr->SiS_ChSW = TRUE; + } + i++; + } while(mychswtable[i].subsysVendor != 0); + } + + /* TW: Detect video bridge and sense connected devices */ SISVGAPreInit(pScrn); + /* TW: Detect CRT1 */ + SISCRT1PreInit(pScrn); /* TW: Detect CRT2-LCD and LCD size */ SISLCDPreInit(pScrn); /* TW: Detect CRT2-TV and PAL/NTSC mode */ SISTVPreInit(pScrn); /* TW: Detect CRT2-VGA */ SISCRT2PreInit(pScrn); + + /* TW: Backup detected CRT2 devices */ + pSiS->detectedCRT2Devices = pSiS->VBFlags & (CRT2_LCD | CRT2_TV | CRT2_VGA); + /* TW: Eventually overrule detected CRT2 type */ - if (pSiS->ForceCRT2Type == CRT2_DEFAULT) - { - if (pSiS->VBFlags & CRT2_VGA) + if(pSiS->ForceCRT2Type == CRT2_DEFAULT) { + if(pSiS->VBFlags & CRT2_VGA) pSiS->ForceCRT2Type = CRT2_VGA; - else if (pSiS->VBFlags & CRT2_LCD) + else if(pSiS->VBFlags & CRT2_LCD) pSiS->ForceCRT2Type = CRT2_LCD; - else if (pSiS->VBFlags & CRT2_TV) + else if(pSiS->VBFlags & CRT2_TV) pSiS->ForceCRT2Type = CRT2_TV; } - switch (pSiS->ForceCRT2Type) - { - case CRT2_TV: + + switch(pSiS->ForceCRT2Type) { + case CRT2_TV: pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_LCD | CRT2_VGA); - if (pSiS->VBFlags & VB_VIDEOBRIDGE) + if(pSiS->VBFlags & VB_VIDEOBRIDGE) pSiS->VBFlags = pSiS->VBFlags | CRT2_TV; else pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV); break; - case CRT2_LCD: + case CRT2_LCD: pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV | CRT2_VGA); - if (pSiS->VBFlags & VB_VIDEOBRIDGE) + if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (pSiS->VBLCDFlags)) pSiS->VBFlags = pSiS->VBFlags | CRT2_LCD; - else + else { pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_LCD); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Can't force CRT2 to LCD, no panel detected\n"); + } break; - case CRT2_VGA: + case CRT2_VGA: + if(pSiS->VBFlags & VB_LVDS) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "LVDS does not support secondary VGA\n"); + break; + } + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiS30xLV bridge does not support secondary VGA\n"); + break; + } pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV | CRT2_LCD); - if (pSiS->VBFlags & VB_VIDEOBRIDGE) + if(pSiS->VBFlags & VB_VIDEOBRIDGE) pSiS->VBFlags = pSiS->VBFlags | CRT2_VGA; else pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_VGA); @@ -1010,30 +2624,428 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->VBFlags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA); } - /* TW: Check if CRT1 used (or needed; this if no CRT2 detected) */ + /* TW: Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART) */ + if(pSiS->ForceTVType != -1) { + if(pSiS->VBFlags & VB_SISBRIDGE) { + pSiS->VBFlags &= ~(TV_INTERFACE); + pSiS->VBFlags |= pSiS->ForceTVType; + } + } + + /* TW: Handle ForceCRT1 option */ + pSiS->CRT1changed = FALSE; + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + usScratchCR17 = pSiS->oldCR17; + usScratchCR32 = pSiS->postVBCR32; + if(pSiS->VESA != 1) { + /* TW: Copy forceCRT1 option to CRT1off if option is given */ +#ifdef SISDUALHEAD + /* TW: In DHM, handle this option only for master head, not the slave */ + if( (pSiS->forceCRT1 != -1) && + (!(pSiS->DualHeadMode && pSiS->SecondHead)) ) { +#else + if(pSiS->forceCRT1 != -1) { +#endif + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "CRT1 detection overruled by ForceCRT1 option\n"); + if(pSiS->forceCRT1) { + pSiS->CRT1off = 0; + if (!(usScratchCR17 & 0x80)) pSiS->CRT1changed = TRUE; + usScratchCR17 |= 0x80; + usScratchCR32 |= 0x20; + } else { + if( ! ( (pScrn->bitsPerPixel == 8) && + ( (pSiS->VBFlags & VB_LVDS) || + ((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->VBFlags & VB_301B)) ) ) ) { + pSiS->CRT1off = 1; + if (usScratchCR17 & 0x80) pSiS->CRT1changed = TRUE; + usScratchCR32 &= ~0x20; + /* TW: We must not actually switch off CRT1 before we changed the mode! */ + } + } + outSISIDXREG(SISCR, 0x17, usScratchCR17); + outSISIDXREG(SISCR, 0x32, usScratchCR32); + if(pSiS->CRT1changed) { + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + usleep(10000); + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "CRT1 status changed by ForceCRT1 option\n"); + } + } + } + /* TW: Store the new VB connection register contents for later mode changes */ + pSiS->newCR32 = usScratchCR32; + } + + /* TW: Check if CRT1 used (or needed; this eg. if no CRT2 detected) */ if (pSiS->VBFlags & VB_VIDEOBRIDGE) { - if (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) + + /* TW: No CRT2 output? Then we NEED CRT1! + * We also need CRT1 if depth = 8 and bridge=LVDS|630+301B + */ + if ( (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) || + ( (pScrn->bitsPerPixel == 8) && + ( (pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) || + ((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->VBFlags & VB_301B)) ) ) ) { pSiS->CRT1off = 0; - } - else /* TW: no video bridge? Then we NEED CRT1! */ + } + /* TW: No CRT2 output? Then we can't use Xv on CRT2 */ + if (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) + pSiS->XvOnCRT2 = FALSE; + + } else { /* TW: no video bridge? */ + + /* Then we NEED CRT1... */ pSiS->CRT1off = 0; + /* ... and can't use CRT2 for Xv output */ + pSiS->XvOnCRT2 = FALSE; + } + + /* TW: Handle TVStandard option */ + if(pSiS->NonDefaultPAL != -1) { + if( (!(pSiS->VBFlags & VB_SISBRIDGE)) && + (!((pSiS->VBFlags & VB_CHRONTEL)) && (pSiS->ChrontelType == CHRONTEL_701x)) ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PALM and PALN only supported on Chrontel 701x and SiS30x/B/LV\n"); + pSiS->NonDefaultPAL = -1; + pSiS->VBFlags &= ~(TV_PALN | TV_PALM); + } + } + if(pSiS->NonDefaultPAL != -1) { + if((pSiS->Chipset == PCI_CHIP_SIS300) || (pSiS->Chipset == PCI_CHIP_SIS540)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PALM and PALN not supported on SiS300 and SiS540\n"); + pSiS->NonDefaultPAL = -1; + pSiS->VBFlags &= ~(TV_PALN | TV_PALM); + } + } + if(pSiS->OptTVStand != -1) { + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + if(!(pSiS->Flags & (TV_CHSCART | TV_CHHDTV))) { + pSiS->VBFlags &= ~(TV_PAL | TV_NTSC | TV_PALN | TV_PALM); + if(pSiS->OptTVStand) pSiS->VBFlags |= TV_PAL; + else pSiS->VBFlags |= TV_NTSC; + if(pSiS->NonDefaultPAL == 1) pSiS->VBFlags |= TV_PALM; + else if(!pSiS->NonDefaultPAL) pSiS->VBFlags |= TV_PALN; + } else { + pSiS->OptTVStand = pSiS->NonDefaultPAL = -1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Option TVStandard ignored for SCART and 480i HDTV\n"); + } + } else if(pSiS->Chipset == PCI_CHIP_SIS6326) { + pSiS->SiS6326Flags &= ~SIS6326_TVPAL; + if(pSiS->OptTVStand) pSiS->SiS6326Flags |= SIS6326_TVPAL; + } + } + + /* TW: Do some checks */ + if(pSiS->OptTVOver != -1) { + if(pSiS->VBFlags & VB_CHRONTEL) { + pSiS->UseCHOverScan = pSiS->OptTVOver; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "CHTVOverscan option only supported on CHRONTEL 70xx\n"); + pSiS->UseCHOverScan = -1; + } + } else pSiS->UseCHOverScan = -1; + + if(pSiS->sistvedgeenhance != -1) { + if(!(pSiS->VBFlags & VB_301)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SISTVEdgeEnhance option only supported on SiS301\n"); + pSiS->sistvedgeenhance = -1; + } + } - /* TW: Determine CRT1<>CRT2 mode */ - if (pSiS->VBFlags & DISPTYPE_DISP2) { - if (pSiS->CRT1off) /* TW: CRT2 only */ + /* TW: Determine CRT1<>CRT2 mode + * Note: When using VESA or if the bridge is in slavemode, display + * is ALWAYS in MIRROR_MODE! + * This requires extra checks in functions using this flag! + * (see sis_video.c for example) + */ + if(pSiS->VBFlags & DISPTYPE_DISP2) { + if(pSiS->CRT1off) { /* TW: CRT2 only ------------------------------- */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "CRT1 not detected or forced off. Dual Head mode can't initialize.\n"); + if(pSiSEnt) pSiSEnt->DisableDual = TRUE; + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); + SISFreeRec(pScrn); + return FALSE; + } +#endif pSiS->VBFlags |= VB_DISPMODE_SINGLE; - else /* TW: CRT1 and CRT2 - mirror image */ - pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1); - } else /* TW: CRT1 only */ + /* TW: No CRT1? Then we use the video overlay on CRT2 */ + pSiS->XvOnCRT2 = TRUE; + } else /* TW: CRT1 and CRT2 - mirror or dual head ----- */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pSiS->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1); + if(pSiS->VESA != -1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VESA option not used in Dual Head mode. VESA disabled.\n"); + } + if (pSiSEnt) pSiSEnt->DisableDual = FALSE; + pSiS->VESA = 0; + } else +#endif + pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1); + } else { /* TW: CRT1 only ------------------------------- */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No CRT2 output selected or no bridge detected. " + "Dual Head mode can't initialize.\n"); + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); + SISFreeRec(pScrn); + return FALSE; + } +#endif pSiS->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1); + } + if( (pSiS->VGAEngine == SIS_315_VGA) || + (pSiS->VGAEngine == SIS_300_VGA) ) { + if ( (!pSiS->NoXvideo) && + (!pSiS->hasTwoOverlays) ) { + xf86DrvMsg(pScrn->scrnIndex, from, + "Using Xv overlay on CRT%d\n", + pSiS->XvOnCRT2 ? 2 : 1); + } + } + + /* TW: Init Ptrs for Save/Restore functions and calc MaxClock */ SISDACPreInit(pScrn); - /* Lock extended registers */ - outw(VGA_SEQ_INDEX, (unlock << 8) | 0x05); + /* ********** end of VBFlags setup ********** */ + + /* TW: VBFlags are initialized now. Back them up for SlaveMode modes. */ + pSiS->VBFlags_backup = pSiS->VBFlags; + + /* TW: Find out about paneldelaycompensation and evaluate option */ + pSiS->sishw_ext.pdc = 0; + + if(pSiS->VGAEngine == SIS_300_VGA) { + + if(pSiS->VBFlags & (VB_LVDS | VB_301B | VB_302B)) { + /* TW: Save the current PDC if the panel is used at the moment. + * This seems by far the safest way to find out about it. + * If the system is using an old version of sisfb, we can't + * trust the pdc register value. If sisfb saved the pdc for + * us, use it. + */ + if(pSiS->sisfbpdc) { + pSiS->sishw_ext.pdc = pSiS->sisfbpdc; + } else { + if(!(pSiS->donttrustpdc)) { + unsigned char tmp; + inSISIDXREG(SISCR, 0x30, tmp); + if(tmp & 0x20) { + inSISIDXREG(SISPART1, 0x13, pSiS->sishw_ext.pdc); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unable to detect LCD PanelDelayCompensation, LCD is not active\n"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unable to detect LCD PanelDelayCompensation, please update sisfb\n"); + } + } + pSiS->sishw_ext.pdc &= 0x3c; + if(pSiS->sishw_ext.pdc) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected LCD PanelDelayCompensation %d\n", + pSiS->sishw_ext.pdc); + } + + /* If we haven't been able to find out, use our other methods */ + if(pSiS->sishw_ext.pdc == 0) { + + int i=0; + do { + if(mypdctable[i].subsysVendor == pSiS->PciInfo->subsysVendor && + mypdctable[i].subsysCard == pSiS->PciInfo->subsysCard) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI card/vendor found in list for non-default PanelDelayCompensation\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Vendor: %s, card: %s (ID %04x), PanelDelayCompensation: %d\n", + mypdctable[i].vendorName, mypdctable[i].cardName, + pSiS->PciInfo->subsysCard, mypdctable[i].pdc); + if(pSiS->PDC == -1) { + pSiS->PDC = mypdctable[i].pdc; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "PanelDelayCompensation overruled by option\n"); + } + break; + } + i++; + } while(mypdctable[i].subsysVendor != 0); + + } + + if(pSiS->PDC != -1) { + if(pSiS->BIOS) { + if(pSiS->VBFlags & VB_LVDS) { + if(pSiS->BIOS[0x220] & 0x80) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "BIOS contains custom LCD Panel Delay Compensation %d\n", + pSiS->BIOS[0x220] & 0x3c); + pSiS->BIOS[0x220] &= 0x7f; + } + } + if(pSiS->VBFlags & (VB_301B|VB_302B)) { + if(pSiS->BIOS[0x220] & 0x80) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "BIOS contains custom LCD Panel Delay Compensation %d\n", + ( (pSiS->VBLCDFlags & VB_LCD_1280x1024) ? + pSiS->BIOS[0x223] : pSiS->BIOS[0x224] ) & 0x3c); + pSiS->BIOS[0x220] &= 0x7f; + } + } + } + pSiS->sishw_ext.pdc = (pSiS->PDC & 0x3c); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using LCD Panel Delay Compensation %d\n", pSiS->PDC); + } + } + } + +#ifdef SISDUALHEAD + /* TW: In dual head mode, both heads (currently) share the maxxfbmem equally. + * If memory sharing is done differently, the following has to be changed; + * the other modules (eg. accel and Xv) use dhmOffset for hardware + * pointer settings relative to VideoRAM start and won't need to be changed. + */ + if (pSiS->DualHeadMode) { + if (pSiS->SecondHead == FALSE) { + /* ===== First head (always CRT2) ===== */ + /* We use only half of the memory available */ + pSiS->maxxfbmem /= 2; + /* Initialize dhmOffset */ + pSiS->dhmOffset = 0; + /* Copy framebuffer addresses & sizes to entity */ + pSiSEnt->masterFbAddress = pSiS->FbAddress; + pSiSEnt->masterFbSize = pSiS->maxxfbmem; + pSiSEnt->slaveFbAddress = pSiS->FbAddress + pSiS->maxxfbmem; + pSiSEnt->slaveFbSize = pSiS->maxxfbmem; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "%dKB video RAM at 0x%lx available for master head (CRT2)\n", + pSiS->maxxfbmem/1024, pSiS->FbAddress); + } else { + /* ===== Second head (always CRT1) ===== */ + /* We use only half of the memory available */ + pSiS->maxxfbmem /= 2; + /* Adapt FBAddress */ + pSiS->FbAddress += pSiS->maxxfbmem; + /* Initialize dhmOffset */ + pSiS->dhmOffset = pSiS->availMem - pSiS->maxxfbmem; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "%dKB video RAM at 0x%lx available for slave head (CRT1)\n", + pSiS->maxxfbmem/1024, pSiS->FbAddress); + } + } else + pSiS->dhmOffset = 0; +#endif + + /* TW: Note: Do not use availMem for anything from now. Use + * maxxfbmem instead. (availMem does not take dual head + * mode into account.) + */ + + /* TW: Now for something completely different: DDC. + For 300 and 310/325 series, we provide our + own functions (in order to probe CRT2 as well) + If these fail, use the VBE. + All other chipsets will use VBE. No need to re-invent + the wheel there. + */ + + pSiS->pVbe = NULL; + didddc2 = FALSE; + + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + if(xf86LoadSubModule(pScrn, "ddc")) { + xf86LoaderReqSymLists(ddcSymbols, NULL); + if((pMonitor = SiSDoPrivateDDC(pScrn))) { + didddc2 = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DDC monitor info:\n"); + xf86PrintEDID(pMonitor); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "End of DDC monitor info\n"); + xf86SetDDCproperties(pScrn, pMonitor); + pScrn->monitor->DDC = pMonitor; + } + } + } + +#ifdef SISDUALHEAD + /* TW: In dual head mode, probe DDC using VBE only for CRT1 (second head) */ + if((pSiS->DualHeadMode) && (!didddc2) && (!pSiS->SecondHead)) + didddc2 = TRUE; +#endif + + /* TW: If CRT1 is off (eventually forced), skip DDC */ + if((!didddc2) && (pSiS->CRT1off)) didddc2 = TRUE; + + /* TW: Now (re-)load and initialize the DDC module */ + if(!didddc2) { + + if(xf86LoadSubModule(pScrn, "ddc")) { + + xf86LoaderReqSymLists(ddcSymbols, NULL); + + /* TW: Now load and initialize VBE module. */ + if(xf86LoadSubModule(pScrn, "vbe")) { + xf86LoaderReqSymLists(vbeSymbols, NULL); +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + pSiS->pVbe = VBEInit(pSiS->pInt,pSiS->pEnt->index); +#else + pSiS->pVbe = VBEExtendedInit(pSiS->pInt,pSiS->pEnt->index, + SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); +#endif + if(!pSiS->pVbe) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not initialize VBE module for DDC\n"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not load VBE module for DDC\n"); + } + + if(pSiS->pVbe) { + if((pMonitor = vbeDoEDID(pSiS->pVbe,NULL))) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "VBE DDC monitor info:\n"); + xf86SetDDCproperties(pScrn, xf86PrintEDID(pMonitor)); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "End of VBE DDC monitor info:\n"); + pScrn->monitor->DDC = pMonitor; + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Could not retrieve DDC data\n"); + } + } + } + +#if 0 /* TW: DDC1 obviously no longer supported by SiS chipsets */ + if (!ret && pSiS->ddc1Read) + xf86SetDDCproperties(pScrn, xf86PrintEDID(xf86DoEDID_DDC1( + pScrn->scrnIndex,vgaHWddc1SetSpeed,pSiS->ddc1Read ))); +#endif + + /* end of DDC */ /* Set the min pixel clock */ - pSiS->MinClock = 16250; /* XXX Guess, need to check this */ + pSiS->MinClock = 12000; /* XXX Guess, need to check this (TW: good for even 50Hz interlace) */ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", pSiS->MinClock / 1000); @@ -1042,10 +3054,9 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) * If the user has specified ramdac speed in the XF86Config * file, we respect that setting. */ - if (pSiS->pEnt->device->dacSpeeds[0]) { + if(pSiS->pEnt->device->dacSpeeds[0]) { int speed = 0; - - switch (pScrn->bitsPerPixel) { + switch(pScrn->bitsPerPixel) { case 8: speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP8]; break; @@ -1059,7 +3070,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP32]; break; } - if (speed == 0) + if(speed == 0) pSiS->MaxClock = pSiS->pEnt->device->dacSpeeds[0]; else pSiS->MaxClock = speed; @@ -1078,8 +3089,131 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->maxClock = pSiS->MaxClock; clockRanges->clockIndex = -1; /* programmable */ clockRanges->interlaceAllowed = TRUE; - clockRanges->doubleScanAllowed = TRUE; /* XXX check this */ + clockRanges->doubleScanAllowed = TRUE; + + /* TW: If there is no HSync or VRefresh data for the monitor, + derive it from DDC data. (Idea taken from radeon driver) + */ + if(pScrn->monitor->DDC) { + if(pScrn->monitor->nHsync <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Substituting missing monitor HSync data by DDC data\n"); + SiSSetSyncRangeFromEdid(pScrn, 1); + } + if(pScrn->monitor->nVrefresh <= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Substituting missing monitor VRefresh data by DDC data\n"); + SiSSetSyncRangeFromEdid(pScrn, 0); + } + } + + /* + * TW: Since we have lots of built-in modes for 300/310/325/330 series + * with vb support, we replace the given default mode list with our + * own. In case the video bridge is to be used, no other than our + * built-in modes are supported; therefore, delete the entire modelist + * given. + */ + + pSiS->HaveCustomModes = FALSE; + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + if(!(pSiS->noInternalModes)) { + if((mymodes = SiSBuildBuiltInModeList(pScrn))) { +#ifdef SISDUALHEAD + if( (pSiS->UseVESA) || + ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) || + ((!pSiS->DualHeadMode) && (pSiS->VBFlags & DISPTYPE_DISP2)) ) { +#else + if((pSiS->UseVESA) || (pSiS->VBFlags & DISPTYPE_DISP2)) { +#endif + while(pScrn->monitor->Modes) + xf86DeleteMode(&pScrn->monitor->Modes, pScrn->monitor->Modes); + pScrn->monitor->Modes = mymodes; + } else { + delmode = pScrn->monitor->Modes; + while(delmode) { + if(delmode->type & M_T_DEFAULT) { + tempmode = delmode->next; + xf86DeleteMode(&pScrn->monitor->Modes, delmode); + delmode = tempmode; + } else { + delmode = delmode->next; + } + } + tempmode = pScrn->monitor->Modes; + if(tempmode) pSiS->HaveCustomModes = TRUE; + pScrn->monitor->Modes = mymodes; + while(mymodes) { + if(!mymodes->next) break; + else mymodes = mymodes->next; + } + mymodes->next = tempmode; + if(tempmode) { + tempmode->prev = mymodes; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Replaced %s mode list with built-in modes\n", + pSiS->HaveCustomModes ? "default" : "entire"); +#ifdef TWDEBUG + pScrn->modes = pScrn->monitor->Modes; + xf86PrintModes(pScrn); + pScrn->modes = NULL; +#endif + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Building list of built-in modes failed, using XFree86 defaults\n"); + } + } + } + + /* + * TW: Add our built-in modes for TV on the 6326 + */ + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Adding %s TV modes for 6326 to mode list:\n", + (pSiS->SiS6326Flags & SIS6326_TVPAL) ? "PAL" : "NTSC"); + if(pSiS->SiS6326Flags & SIS6326_TVPAL) { + SiS6326PAL800x600Mode.next = pScrn->monitor->Modes; + pScrn->monitor->Modes = &SiS6326PAL640x480Mode; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "\"PAL800x600\" \"PAL800x600U\" \"PAL720x540\" \"PAL640x480\"\n"); + } else { + SiS6326NTSC640x480Mode.next = pScrn->monitor->Modes; + pScrn->monitor->Modes = &SiS6326NTSC640x400Mode; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "\"NTSC640x480\" \"NTSC640x480U\" \"NTSC640x400\"\n"); + } + } + } + + /* + * TW: Add our built-in hi-res modes on the 6326 + */ + if(pSiS->Chipset == PCI_CHIP_SIS6326) { + if(pScrn->bitsPerPixel == 8) { + SiS6326SIS1600x1200_60Mode.next = pScrn->monitor->Modes; + pScrn->monitor->Modes = &SiS6326SIS1600x1200_60Mode; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Adding mode \"SIS1600x1200-60\" (depth 8 only)\n"); + } + if(pScrn->bitsPerPixel <= 16) { + SiS6326SIS1280x1024_75Mode.next = pScrn->monitor->Modes; + pScrn->monitor->Modes = &SiS6326SIS1280x1024_75Mode; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Adding mode \"SIS1280x1024-75\" (depth 8, 15 and 16 only)\n"); + } + } + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "\"Unknown reason\" in the following list means that the mode\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "is not supported on the chipset/bridge/current output device.\n"); + } + /* * xf86ValidateModes will check that the mode HTotal and VTotal values * don't exceed the chipset's limit if pScrn->maxHValue and @@ -1089,8 +3223,8 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* Select valid modes from those available */ /* - * XXX Assuming min pitch 256, max 4096 ==> 8192 - * XXX Assuming min height 128, max 4096 + * Assuming min pitch 256, max 4096 ==> 8192 + * Assuming min height 128, max 4096 */ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, @@ -1101,16 +3235,146 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->maxxfbmem, LOOKUP_BEST_REFRESH); - if (i == -1) { + if(i == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86ValidateModes() error\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); SISFreeRec(pScrn); return FALSE; } + /* TW: Go through mode list and mark all those modes as bad, + * - which are unsuitable for dual head mode (if running dhm), + * - which exceed the LCD panels specs (if running on LCD) + * - TODO: which exceed TV capabilities (if running on TV) + * Also, find the highest used pixelclock on the master head. + */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!pSiS->SecondHead) pSiSEnt->maxUsedClock = 0; + } +#endif + if((p = first = pScrn->modes)) { + do { + n = p->next; + + /* TW: Check the modes if they comply with our built-in tables. + * This is of practical use only if the user disabled the + * usage of the internal (built-in) modes. + */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + if(p->type & M_T_DEFAULT) { + if( ( (strcmp(p->name, "320x200") != 0) && + (strcmp(p->name, "320x240") != 0) && + (strcmp(p->name, "400x300") != 0) && + (strcmp(p->name, "512x384") != 0) ) && + (p->Flags & V_DBLSCAN) ) { + p->status = MODE_NO_DBLESCAN; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (mode not supported as doublescan)\n", p->name); + } + if( ( (strcmp(p->name, "1024x768") != 0) && + (strcmp(p->name, "1280x1024") != 0) && + (strcmp(p->name, "848x480") != 0) && + (strcmp(p->name, "856x480") != 0)) && + (p->Flags & V_INTERLACE) ) { + p->status = MODE_NO_INTERLACE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (mode not supported as interlaced)\n", p->name); + } + if( ( (strcmp(p->name, "320x200") == 0) || + (strcmp(p->name, "320x240") == 0) || + (strcmp(p->name, "400x300") == 0) || + (strcmp(p->name, "512x384") == 0) ) && + (!(p->Flags & V_DBLSCAN)) ) { + p->status = MODE_CLOCK_RANGE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (only supported as doublescan)\n", p->name); + } + } + } +#ifdef SISDUALHEAD + /* TW: Modes that require the bridge to operate in SlaveMode + * are not suitable for Dual Head mode. Also check for + * modes that exceed panel dimension. + */ + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead == FALSE) { + if( (strcmp(p->name, "320x200") == 0) || + (strcmp(p->name, "320x240") == 0) || + (strcmp(p->name, "400x300") == 0) || + (strcmp(p->name, "512x384") == 0) || + (strcmp(p->name, "640x400") == 0) ) { + p->status = MODE_BAD; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (not suitable for dual head mode)\n", + p->name); + } + } + if(pSiS->VBFlags & DISPTYPE_DISP2) { + if(pSiS->VBFlags & CRT2_LCD) { + if(pSiS->SecondHead == FALSE) { + if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) { + p->status = MODE_PANEL; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name); + } + if(p->Flags & V_INTERLACE) { + p->status = MODE_BAD; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (interlace on LCD not supported)\n", + p->name); + } + } + } + /* TO DO: TV */ + } + /* TW: Search for the highest clock on first head in order to calculate + * max clock for second head (CRT1) + */ + if(!pSiS->SecondHead) { + if((p->status == MODE_OK) && (p->Clock > pSiSEnt->maxUsedClock)) { + pSiSEnt->maxUsedClock = p->Clock; + } + } + } else { +#endif + if(pSiS->VBFlags & DISPTYPE_DISP2) { + if(pSiS->VBFlags & CRT2_LCD) { + if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) { + p->status = MODE_PANEL; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name); + } + if(p->Flags & V_INTERLACE) { + p->status = MODE_BAD; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using mode \"%s\" (interlace on LCD not supported)\n", + p->name); + } + } + } +#ifdef SISDUALHEAD + } +#endif + p = n; + } while (p != NULL && p != first); + } + /* Prune the modes marked as invalid */ xf86PruneDriverModes(pScrn); - if (i == 0 || pScrn->modes == NULL) { + if(i == 0 || pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); SISFreeRec(pScrn); return FALSE; } @@ -1120,119 +3384,143 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* Set the current mode to the first in the list */ pScrn->currentMode = pScrn->modes; + /* TW: Copy to CurrentLayout */ + pSiS->CurrentLayout.mode = pScrn->currentMode; + pSiS->CurrentLayout.displayWidth = pScrn->displayWidth; + /* Print the list of modes being used */ xf86PrintModes(pScrn); +#ifdef SISDUALHEAD + /* TW: Due to palette & timing problems we don't support 8bpp in DHM */ + if((pSiS->DualHeadMode) && (pScrn->bitsPerPixel == 8)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Colordepth 8 not supported in Dual Head mode.\n"); + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); + SISFreeRec(pScrn); + return FALSE; + } +#endif + /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); /* Load bpp-specific modules */ - switch (pScrn->bitsPerPixel) { - case 1: + switch(pScrn->bitsPerPixel) { + case 1: mod = "xf1bpp"; Sym = "xf1bppScreenInit"; break; - case 4: + case 4: mod = "xf4bpp"; Sym = "xf4bppScreenInit"; break; - case 8: - case 16: - case 24: - case 32: + case 8: + case 16: + case 24: + case 32: mod = "fb"; break; } - if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + if(mod && xf86LoadSubModule(pScrn, mod) == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not load %s module", mod); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); SISFreeRec(pScrn); return FALSE; } - if (mod) { - if (Sym) { + if(mod) { + if(Sym) { xf86LoaderReqSymbols(Sym, NULL); } else { xf86LoaderReqSymLists(fbSymbols, NULL); } } - if (!xf86LoadSubModule(pScrn, "i2c")) { - SISFreeRec(pScrn); - return FALSE; - } - - xf86LoaderReqSymLists(i2cSymbols, NULL); - /* Load XAA if needed */ - if (!pSiS->NoAccel) { - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Accel Enable\n"); - if (!xf86LoadSubModule(pScrn, "xaa")) { + if(!pSiS->NoAccel) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n"); + if(!xf86LoadSubModule(pScrn, "xaa")) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not load xaa module\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); SISFreeRec(pScrn); return FALSE; } - xf86LoaderReqSymLists(xaaSymbols, NULL); } /* Load shadowfb if needed */ - if (pSiS->ShadowFB) { - if (!xf86LoadSubModule(pScrn, "shadowfb")) { - SISFreeRec(pScrn); + if(pSiS->ShadowFB) { + if(!xf86LoadSubModule(pScrn, "shadowfb")) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not load shadowfb module\n"); +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE; +#endif + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); + SISFreeRec(pScrn); return FALSE; } xf86LoaderReqSymLists(shadowSymbols, NULL); } - /* Load DDC if needed */ - /* This gives us DDC1 - we should be able to get DDC2B using i2c */ - if (!xf86LoadSubModule(pScrn, "ddc")) { - SISFreeRec(pScrn); - return FALSE; - } - xf86LoaderReqSymLists(ddcSymbols, NULL); -/* TW: Now load and initialize VBE module. The default behavior - * for SiS630 with SiS301B, SiS302 or LVDS/CHRONTEL bridge - * is to use VESA for mode switching. This can be overruled - * with the option "VESA". - */ + /* TW: Now load and initialize VBE module for VESA. */ + pSiS->UseVESA = 0; + if(pSiS->VESA == 1) { + if(!pSiS->pVbe) { + if(xf86LoadSubModule(pScrn, "vbe")) { + xf86LoaderReqSymLists(vbeSymbols, NULL); +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + pSiS->pVbe = VBEInit(pSiS->pInt,pSiS->pEnt->index); +#else + pSiS->pVbe = VBEExtendedInit(pSiS->pInt,pSiS->pEnt->index, + SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); +#endif + } + } + if(pSiS->pVbe) { + vbe = VBEGetVBEInfo(pSiS->pVbe); + pSiS->vesamajor = (unsigned)(vbe->VESAVersion >> 8); + pSiS->vesaminor = vbe->VESAVersion & 0xff; + pSiS->vbeInfo = vbe; + SiSBuildVesaModeList(pScrn, pSiS->pVbe, vbe); + VBEFreeVBEInfo(vbe); + pSiS->UseVESA = 1; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not load and initialize VBE module. VESA disabled.\n"); + } + } - { - Bool ret; - pSiS->UseVESA=0; - if (xf86LoadSubModule(pScrn, "vbe")) { - xf86LoaderReqSymLists(vbeSymbols, NULL); - if ((pSiS->pVbe = VBEExtendedInit(NULL,pSiS->pEnt->index, - SET_BIOS_SCRATCH - | RESTORE_BIOS_SCRATCH))) { - ret = xf86SetDDCproperties(pScrn, - xf86PrintEDID(vbeDoEDID(pSiS->pVbe,NULL))); - if ( (pSiS->VESA == 1) - || ( (pSiS->VESA != 0) - && (pSiS->Chipset == PCI_CHIP_SIS630) - && (pSiS->VBFlags & (VB_301B|VB_302|VB_LVDS|VB_CHRONTEL))) ) { - vbe = VBEGetVBEInfo(pSiS->pVbe); - pSiS->vesamajor = (unsigned)(vbe->VESAVersion >> 8); - pSiS->vesaminor = vbe->VESAVersion & 0xff; - pSiS->vbeInfo = vbe; - SiSBuildVesaModeList(pScrn->scrnIndex,pSiS->pVbe, vbe); - VBEFreeVBEInfo(vbe); - pSiS->UseVESA = 1; - /* TW: from now, use VESA functions for mode switching */ - } - } - } - vbeFree(pSiS->pVbe); - pSiS->pVbe = NULL; + if(pSiS->pVbe) { + vbeFree(pSiS->pVbe); + pSiS->pVbe = NULL; } - -#if 0 - if (!ret && pSiS->ddc1Read) - xf86SetDDCProperties(xf86PrintEDID(xf86DoEDID_DDC1( - pScrn->scrnIndex,vgaHWddc1SetSpeed,pSiS->ddc1Read ))); + +#ifdef SISDUALHEAD + xf86SetPrimInitDone(pScrn->entityList[0]); #endif + sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg); + + if(pSiS->pInt) xf86FreeInt10(pSiS->pInt); + pSiS->pInt = NULL; + return TRUE; } @@ -1246,9 +3534,15 @@ SISMapMem(ScrnInfoPtr pScrn) { SISPtr pSiS; int mmioFlags; - +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = NULL; +#endif pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + pSiSEnt = pSiS->entityPrivate; +#endif + /* * Map IO registers to virtual address space */ @@ -1261,29 +3555,82 @@ SISMapMem(ScrnInfoPtr pScrn) */ mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE; #endif - pSiS->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pSiSEnt->MapCountIOBase++; + if(!(pSiSEnt->IOBase)) { + /* TW: Only map if not mapped previously */ + pSiSEnt->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, + pSiS->PciTag, pSiS->IOAddress, 0x10000); + } + pSiS->IOBase = pSiSEnt->IOBase; + } else +#endif + pSiS->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pSiS->PciTag, pSiS->IOAddress, 0x10000); - if (pSiS->IOBase == NULL) + + if(pSiS->IOBase == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not map MMIO area\n"); return FALSE; + } #ifdef __alpha__ /* * for Alpha, we need to map DENSE memory as well, for * setting CPUToScreenColorExpandBase. */ - pSiS->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pSiSEnt->MapCountIOBaseDense++; + if(!(pSiSEnt->IOBaseDense)) { + /* TW: Only map if not mapped previously */ + pSiSEnt->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pSiS->PciTag, pSiS->IOAddress, 0x10000); + } + pSiS->IOBaseDense = pSiSEnt->IOBaseDense; + } else +#endif + pSiS->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSiS->PciTag, pSiS->IOAddress, 0x10000); - if (pSiS->IOBaseDense == NULL) + if(pSiS->IOBaseDense == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not map MMIO dense area\n"); return FALSE; + } + #endif /* __alpha__ */ - pSiS->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, - pSiS->PciTag, - (unsigned long)pSiS->FbAddress, +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pSiSEnt->MapCountFbBase++; + if(!(pSiSEnt->FbBase)) { + /* TW: Only map if not mapped previously */ + pSiSEnt->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + pSiS->PciTag, (unsigned long)pSiS->realFbAddress, pSiS->FbMapSize); - if (pSiS->FbBase == NULL) - return FALSE; + pSiS->sishw_ext.pjVideoMemoryAddress = (UCHAR *)pSiSEnt->FbBase; + } + pSiS->FbBase = pSiSEnt->FbBase; + /* TW: Adapt FbBase (for DHM; dhmOffset is 0 otherwise) */ + pSiS->FbBase += pSiS->dhmOffset; + } else { +#endif + pSiS->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + pSiS->PciTag, (unsigned long)pSiS->FbAddress, + pSiS->FbMapSize); + pSiS->sishw_ext.pjVideoMemoryAddress = (UCHAR *)pSiS->FbBase; +#ifdef SISDUALHEAD + } +#endif + + if(pSiS->FbBase == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not map framebuffer area\n"); + return FALSE; + } return TRUE; } @@ -1297,22 +3644,67 @@ static Bool SISUnmapMem(ScrnInfoPtr pScrn) { SISPtr pSiS; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = NULL; +#endif pSiS = SISPTR(pScrn); - /* - * Unmap IO registers to virtual address space - */ - xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBase, 0x10000); - pSiS->IOBase = NULL; +#ifdef SISDUALHEAD + pSiSEnt = pSiS->entityPrivate; +#endif +/* TW: In dual head mode, we must not unmap if the other head still + * assumes memory as mapped +*/ +#ifdef SISDUALHEAD + if (pSiS->DualHeadMode) { + if (pSiSEnt->MapCountIOBase) { + pSiSEnt->MapCountIOBase--; + if ((pSiSEnt->MapCountIOBase == 0) || (pSiSEnt->forceUnmapIOBase)) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOBase, 0x10000); + pSiSEnt->IOBase = NULL; + pSiSEnt->MapCountIOBase = 0; + pSiSEnt->forceUnmapIOBase = FALSE; + } + pSiS->IOBase = NULL; + } #ifdef __alpha__ - xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBaseDense, 0x10000); - pSiS->IOBaseDense = NULL; + if (pSiSEnt->MapCountIOBaseDense) { + pSiSEnt->MapCountIOBaseDense--; + if ((pSiSEnt->MapCountIOBaseDense == 0) || (pSiSEnt->forceUnmapIOBaseDense)) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOBaseDense, 0x10000); + pSiSEnt->IOBaseDense = NULL; + pSiSEnt->MapCountIOBaseDense = 0; + pSiSEnt->forceUnmapIOBaseDense = FALSE; + } + pSiS->IOBaseDense = NULL; + } #endif /* __alpha__ */ + if (pSiSEnt->MapCountFbBase) { + pSiSEnt->MapCountFbBase--; + if ((pSiSEnt->MapCountFbBase == 0) || (pSiSEnt->forceUnmapFbBase)) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->FbBase, pSiS->FbMapSize); + pSiSEnt->FbBase = NULL; + pSiSEnt->MapCountFbBase = 0; + pSiSEnt->forceUnmapFbBase = FALSE; - xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->FbBase, pSiS->FbMapSize); - pSiS->FbBase = NULL; + } + pSiS->FbBase = NULL; + } + } else { +#endif + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBase, 0x10000); + pSiS->IOBase = NULL; +#ifdef __alpha__ + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBaseDense, 0x10000); + pSiS->IOBaseDense = NULL; +#endif + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->FbBase, pSiS->FbMapSize); + pSiS->FbBase = NULL; +#ifdef SISDUALHEAD + } +#endif return TRUE; } @@ -1327,18 +3719,207 @@ SISSave(ScrnInfoPtr pScrn) SISRegPtr sisReg; pSiS = SISPTR(pScrn); + +#ifdef SISDUALHEAD + /* TW: We always save master & slave */ + if(pSiS->DualHeadMode && pSiS->SecondHead) return; +#endif + vgaReg = &VGAHWPTR(pScrn)->SavedReg; sisReg = &pSiS->SavedReg; vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); - /* Save and unlock extended SIS registers */ - SISSaveUnlockExtRegisterLock(sisReg); + sisSaveUnlockExtRegisterLock(pSiS,&sisReg->sisRegs3C4[0x05],&sisReg->sisRegs3D4[0x80]); (*pSiS->SiSSave)(pScrn, sisReg); + if(pSiS->UseVESA) SISVESASaveRestore(pScrn, MODE_SAVE); + + /* TW: Save these as they may have been changed prior to SISSave() call */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + sisReg->sisRegs3D4[0x17] = pSiS->oldCR17; + if(vgaReg->numCRTC >= 0x17) vgaReg->CRTC[0x17] = pSiS->oldCR17; + sisReg->sisRegs3D4[0x32] = pSiS->oldCR32; + } +} + +/* + * TW: Just adapted from the std* functions in vgaHW.c + */ +static void +SiS_WriteAttr(SISPtr pSiS, int index, int value) +{ + CARD8 tmp; + + tmp = inb(pSiS->IODBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); + + index |= 0x20; + outb(pSiS->IODBase + VGA_ATTR_INDEX, index); + outb(pSiS->IODBase + VGA_ATTR_DATA_W, value); +} + +static int +SiS_ReadAttr(SISPtr pSiS, int index) +{ + CARD8 tmp; + + tmp = inb(pSiS->IODBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); + + index |= 0x20; + outb(pSiS->IODBase + VGA_ATTR_INDEX, index); + return (inb(pSiS->IODBase + VGA_ATTR_DATA_R)); } + +static void +SiS_SaveFonts(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4, scrn; +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + CARD8 *vgaIOBase = (CARD8 *)VGAHWPTR(pScrn)->IOBase; +#else + pointer vgaIOBase = VGAHWPTR(pScrn)->Base; +#endif + + if (pSiS->fonts != NULL) + return; + + /* If in graphics mode, don't save anything */ + attr10 = SiS_ReadAttr(pSiS, 0x10); + if (attr10 & 0x01) + return; + + pSiS->fonts = xalloc(16384); + + /* save the registers that are needed here */ + miscOut = inSISREG(SISMISCR); + inSISIDXREG(SISGR, 0x04, gr4); + inSISIDXREG(SISGR, 0x05, gr5); + inSISIDXREG(SISGR, 0x06, gr6); + inSISIDXREG(SISSR, 0x02, seq2); + inSISIDXREG(SISSR, 0x04, seq4); + + /* Force into color mode */ + outSISREG(SISMISCW, miscOut | 0x01); + + inSISIDXREG(SISSR, 0x01, scrn); + outSISIDXREG(SISSR, 0x00, 0x01); + outSISIDXREG(SISSR, 0x01, scrn | 0x20); + outSISIDXREG(SISSR, 0x00, 0x03); + + SiS_WriteAttr(pSiS, 0x10, 0x01); /* graphics mode */ + + /*font1 */ + outSISIDXREG(SISSR, 0x02, 0x04); /* write to plane 2 */ + outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */ + outSISIDXREG(SISGR, 0x04, 0x02); /* read plane 2 */ + outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */ + outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */ + slowbcopy_frombus(vgaIOBase, pSiS->fonts, 8192); + + /* font2 */ + outSISIDXREG(SISSR, 0x02, 0x08); /* write to plane 3 */ + outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */ + outSISIDXREG(SISGR, 0x04, 0x03); /* read plane 3 */ + outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */ + outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */ + slowbcopy_frombus(vgaIOBase, pSiS->fonts + 8192, 8192); + + inSISIDXREG(SISSR, 0x01, scrn); + outSISIDXREG(SISSR, 0x00, 0x01); + outSISIDXREG(SISSR, 0x01, scrn & ~0x20); + outSISIDXREG(SISSR, 0x00, 0x03); + + /* Restore clobbered registers */ + SiS_WriteAttr(pSiS, 0x10, attr10); + outSISIDXREG(SISSR, 0x02, seq2); + outSISIDXREG(SISSR, 0x04, seq4); + outSISIDXREG(SISGR, 0x04, gr4); + outSISIDXREG(SISGR, 0x05, gr5); + outSISIDXREG(SISGR, 0x06, gr6); + outSISREG(SISMISCW, miscOut); +} + +static void +SiS_RestoreFonts(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4, scrn; +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + CARD8 *vgaIOBase = (CARD8 *)VGAHWPTR(pScrn)->IOBase; +#else + pointer vgaIOBase = VGAHWPTR(pScrn)->Base; +#endif + + if (pSiS->fonts == NULL) + return; + +#if 0 + if (pVesa->mapPhys == 0xa0000 && pVesa->curBank != 0) + VESABankSwitch(pScrn->pScreen, 0); +#endif + + /* save the registers that are needed here */ + miscOut = inSISREG(SISMISCR); + attr10 = SiS_ReadAttr(pSiS, 0x10); + inSISIDXREG(SISGR, 0x01, gr1); + inSISIDXREG(SISGR, 0x03, gr3); + inSISIDXREG(SISGR, 0x04, gr4); + inSISIDXREG(SISGR, 0x05, gr5); + inSISIDXREG(SISGR, 0x06, gr6); + inSISIDXREG(SISGR, 0x08, gr8); + inSISIDXREG(SISSR, 0x02, seq2); + inSISIDXREG(SISSR, 0x04, seq4); + + /* Force into color mode */ + outSISREG(SISMISCW, miscOut | 0x01); + inSISIDXREG(SISSR, 0x01, scrn); + outSISIDXREG(SISSR, 0x00, 0x01); + outSISIDXREG(SISSR, 0x01, scrn | 0x20); + outSISIDXREG(SISSR, 0x00, 0x03); + + SiS_WriteAttr(pSiS, 0x10, 0x01); /* graphics mode */ + if (pScrn->depth == 4) { + outSISIDXREG(SISGR, 0x03, 0x00); /* don't rotate, write unmodified */ + outSISIDXREG(SISGR, 0x08, 0xFF); /* write all bits in a byte */ + outSISIDXREG(SISGR, 0x01, 0x00); /* all planes come from CPU */ + } + + outSISIDXREG(SISSR, 0x02, 0x04); /* write to plane 2 */ + outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */ + outSISIDXREG(SISGR, 0x04, 0x02); /* read plane 2 */ + outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */ + outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */ + slowbcopy_tobus(pSiS->fonts, vgaIOBase, 8192); + + outSISIDXREG(SISSR, 0x02, 0x08); /* write to plane 3 */ + outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */ + outSISIDXREG(SISGR, 0x04, 0x03); /* read plane 3 */ + outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */ + outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */ + slowbcopy_tobus(pSiS->fonts + 8192, vgaIOBase, 8192); + + inSISIDXREG(SISSR, 0x01, scrn); + outSISIDXREG(SISSR, 0x00, 0x01); + outSISIDXREG(SISSR, 0x01, scrn & ~0x20); + outSISIDXREG(SISSR, 0x00, 0x03); + + /* restore the registers that were changed */ + outSISREG(SISMISCW, miscOut); + SiS_WriteAttr(pSiS, 0x10, attr10); + outSISIDXREG(SISGR, 0x01, gr1); + outSISIDXREG(SISGR, 0x03, gr3); + outSISIDXREG(SISGR, 0x04, gr4); + outSISIDXREG(SISGR, 0x05, gr5); + outSISIDXREG(SISGR, 0x06, gr6); + outSISIDXREG(SISGR, 0x08, gr8); + outSISIDXREG(SISSR, 0x02, seq2); + outSISIDXREG(SISSR, 0x04, seq4); +} + +/* TW: VESASaveRestore taken from vesa driver */ static void SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) { @@ -1346,11 +3927,56 @@ SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) pSiS = SISPTR(pScrn); - if (pSiS->vesamajor > 1 - && (function == MODE_SAVE || pSiS->pstate)) { + /* Query amount of memory to save state */ + if (function == MODE_QUERY || + (function == MODE_SAVE && pSiS->state == NULL)) { + + /* Make sure we save at least this information in case of failure */ + (void)VBEGetVBEMode(pSiS->pVbe, &pSiS->stateMode); + SiS_SaveFonts(pScrn); + + if (pSiS->vesamajor > 1) { + if (!VBESaveRestore(pSiS->pVbe,function,(pointer)&pSiS->state, + &pSiS->stateSize,&pSiS->statePage)) + return; + + } + } + + /* Save/Restore Super VGA state */ + if (function != MODE_QUERY) { + Bool retval = TRUE; + + if (pSiS->vesamajor > 1) { + if (function == MODE_RESTORE) + memcpy(pSiS->state, pSiS->pstate, pSiS->stateSize); + + if ((retval = VBESaveRestore(pSiS->pVbe,function, + (pointer)&pSiS->state, + &pSiS->stateSize,&pSiS->statePage)) + && function == MODE_SAVE) { + /* don't rely on the memory not being touched */ + if (pSiS->pstate == NULL) + pSiS->pstate = xalloc(pSiS->stateSize); + memcpy(pSiS->pstate, pSiS->state, pSiS->stateSize); + } + } + + if (function == MODE_RESTORE) { + VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL); + SiS_RestoreFonts(pScrn); + } +#if 0 + if (!retval) + return (FALSE); +#endif + + } +#if 0 + if ( (pSiS->vesamajor > 1) && + (function == MODE_SAVE || pSiS->pstate) ) { if (function == MODE_RESTORE) memcpy(pSiS->state, pSiS->pstate, pSiS->stateSize); - ErrorF("VBESaveRestore\n"); if ((VBESaveRestore(pSiS->pVbe,function, (pointer)&pSiS->state, &pSiS->stateSize,&pSiS->statePage))) { @@ -1360,23 +3986,26 @@ SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) pSiS->pstate = xalloc(pSiS->stateSize); memcpy(pSiS->pstate, pSiS->state, pSiS->stateSize); } - ErrorF("VBESaveRestore done with success\n"); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "VBESaveRestore done with success\n"); return; } - ErrorF("VBESaveRestore done\n"); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "VBESaveRestore done\n"); } else { if (function == MODE_SAVE) (void)VBEGetVBEMode(pSiS->pVbe, &pSiS->stateMode); else VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL); } +#endif } /* - * Initialise a new mode. This is currently still using the old - * "initialise struct, restore/write struct to HW" model. That could - * be changed. - * TW: Why? + * Initialise a new mode. This is currently done using the + * "initialise struct, restore/write struct to HW" model for + * the old chipsets (5597/530/6326). For newer chipsets, + * we use either VESA or our own mode switching code. */ static Bool @@ -1388,17 +4017,25 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) SISRegPtr sisReg; vgaHWUnlock(hwp); - + SISModifyModeInfo(mode); - /* TW: Initialize SiS Port Reg definitions for externally used - * sis_bios functions. + /* TW: Initialize SiS Port Register definitions for externally used + * BIOS emulation (native code switching) functions. */ - SiSRegInit(pSiS->RelIO+0x30); + if( pSiS->VGAEngine == SIS_300_VGA || + pSiS->VGAEngine == SIS_315_VGA ) { + SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30); + } if (pSiS->UseVESA) { /* With VESA: */ + +#ifdef SISDUALHEAD + /* TW: No dual head mode when using VESA */ + if (pSiS->SecondHead) return TRUE; +#endif /* - * This order is required: + * TW: This order is required: * The video bridge needs to be adjusted before the * BIOS is run as the BIOS sets up CRT2 according to * these register settings. @@ -1406,16 +4043,33 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) * registers need to be readjusted as the BIOS may * very probably have messed them up. */ - SiSPreSetMode(pScrn); - /* TW: mode was pScrn->currentMode - VidModeExt did not work! */ - if (!SiSSetVESAMode(pScrn, mode)) + if( pSiS->VGAEngine == SIS_300_VGA || + pSiS->VGAEngine == SIS_315_VGA ) { + SiSPreSetMode(pScrn, mode); + } + if(!SiSSetVESAMode(pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSSetVESAMode() failed\n"); return FALSE; - SiSPreSetMode(pScrn); - SiSPostSetMode(pScrn, &pSiS->ModeReg, 1); - - /* Prepare the register contents */ - if (!(*pSiS->ModeInit)(pScrn, mode)) + } + sisSaveUnlockExtRegisterLock(pSiS,NULL,NULL); + if( pSiS->VGAEngine == SIS_300_VGA || + pSiS->VGAEngine == SIS_315_VGA ) { + SiSPreSetMode(pScrn, mode); + SiSPostSetMode(pScrn, &pSiS->ModeReg); + } + /* TW: Prepare some register contents and set + * up some mode dependent variables. + */ +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "REAL REGISTER CONTENTS AFTER SETMODE:\n"); +#endif + if (!(*pSiS->ModeInit)(pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ModeInit() failed\n"); return FALSE; + } pScrn->vtSema = TRUE; @@ -1423,54 +4077,135 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) vgaHWProtect(pScrn, TRUE); (*pSiS->SiSRestore)(pScrn, &pSiS->ModeReg); vgaHWProtect(pScrn, FALSE); + PDEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "HDisplay: %d, VDisplay: %d \n", + mode->HDisplay, mode->VDisplay)); - PDEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "HDisplay: %d, VDisplay: %d \n", - mode->HDisplay, mode->VDisplay)); - } else { /* Without VESA: */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!(*pSiS->ModeInit)(pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ModeInit() failed\n"); + return FALSE; + } + + pScrn->vtSema = TRUE; + + if(!(pSiS->SecondHead)) { + /* TW: Head 1 (master) is always CRT2 */ + SiSPreSetMode(pScrn, mode); + if (!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSBIOSSetModeCRT2() failed\n"); + return FALSE; + } + SiSPostSetMode(pScrn, &pSiS->ModeReg); + } else { + /* TW: Head 2 (slave) is always CRT1 */ + SiSPreSetMode(pScrn, mode); + if (!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSBIOSSetModeCRT1() failed\n"); + return FALSE; + } + SiSPostSetMode(pScrn, &pSiS->ModeReg); + } + } else { +#endif + if(pSiS->VGAEngine == SIS_300_VGA || + pSiS->VGAEngine == SIS_315_VGA) { + + /* TW: Prepare the register contents; On 300/310/325, + * we actually "abuse" this only for setting + * up some variables; the registers are NOT + * being written to the hardware as the BIOS + * emulation (native mode switching code) + * takes care of this. + */ + if(!(*pSiS->ModeInit)(pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ModeInit() failed\n"); + return FALSE; + } + + pScrn->vtSema = TRUE; + + /* 300/310/325 series: Use our own code for mode switching */ + SiSPreSetMode(pScrn, mode); + + if(!SiSBIOSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSBIOSSetMode() failed\n"); + return FALSE; + } + + SiSPostSetMode(pScrn, &pSiS->ModeReg); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "REAL REGISTER CONTENTS AFTER SETMODE:\n"); + (*pSiS->ModeInit)(pScrn, mode); +#endif + } else { - /* Initialise the ModeReg values */ - if (!vgaHWInit(pScrn, mode)) - return FALSE; + /* For other chipsets, use the old method */ - if (!(*pSiS->ModeInit)(pScrn, mode)) - return FALSE; + /* Initialise the ModeReg values */ + if(!vgaHWInit(pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "vgaHWInit() failed\n"); + return FALSE; + } - pScrn->vtSema = TRUE; + /* Reset our PIOOffset as vgaHWInit might have reset it */ + VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380; - PDEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "HDisplay: %d, VDisplay: %d \n", - mode->HDisplay, mode->VDisplay)); + /* Prepare the register contents */ + if(!(*pSiS->ModeInit)(pScrn, mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ModeInit() failed\n"); + return FALSE; + } - /* Program the registers */ - vgaHWProtect(pScrn, TRUE); - vgaReg = &hwp->ModeReg; - sisReg = &pSiS->ModeReg; + pScrn->vtSema = TRUE; - vgaReg->Attribute[0x10] = 0x01; - if (pScrn->bitsPerPixel > 8) - vgaReg->Graphics[0x05] = 0x00; + /* Program the registers */ + vgaHWProtect(pScrn, TRUE); + vgaReg = &hwp->ModeReg; + sisReg = &pSiS->ModeReg; - vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + vgaReg->Attribute[0x10] = 0x01; + if(pScrn->bitsPerPixel > 8) { + vgaReg->Graphics[0x05] = 0x00; + } - if ( (pSiS->Chipset == PCI_CHIP_SIS300) || - (pSiS->Chipset == PCI_CHIP_SIS630) || - (pSiS->Chipset == PCI_CHIP_SIS540) ) { - SiSPreSetMode(pScrn); - if (!SiSBIOSSetMode(pScrn, mode)) - return FALSE; - } - else (*pSiS->SiSRestore)(pScrn, sisReg); - - vgaHWProtect(pScrn, FALSE); + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + + (*pSiS->SiSRestore)(pScrn, sisReg); + + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + SiS6326PostSetMode(pScrn, &pSiS->ModeReg); + } + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "REAL REGISTER CONTENTS AFTER SETMODE:\n"); + (*pSiS->ModeInit)(pScrn, mode); +#endif + + vgaHWProtect(pScrn, FALSE); + } +#ifdef SISDUALHEAD + } +#endif } - -/* Reserved for debug - * - SiSDumpModeInfo(pScrn, mode); - * - */ + + /* TW: Update Currentlayout */ + pSiS->CurrentLayout.mode = mode; + + /* Debug */ +/* SiSDumpModeInfo(pScrn, mode); */ + return TRUE; } @@ -1482,53 +4217,212 @@ SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) pSiS = SISPTR(pScrn); - if (!(mode = CalcVESAModeIndex(pScrn, pMode))) return FALSE; - ErrorF("mode: %x\n",mode); + if (!(mode = SiSCalcVESAModeIndex(pScrn, pMode))) return FALSE; - mode |= 1 << 15; /* TW: Don't clear framebuffer */ - mode |= 1 << 14; /* TW: always use linear adressing */ + mode |= 1 << 15; /* TW: Don't clear framebuffer */ + mode |= 1 << 14; /* TW: Use linear adressing */ - if (VBESetVBEMode(pSiS->pVbe, mode, NULL) == FALSE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Setting mode 0x%x failed\n", - mode & 0x0fff); + if(VBESetVBEMode(pSiS->pVbe, mode, NULL) == FALSE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Setting VESA mode 0x%x failed\n", + mode & 0x0fff); return (FALSE); } - if (pMode->HDisplay != pScrn->virtualX) + if(pMode->HDisplay != pScrn->virtualX) VBESetLogicalScanline(pSiS->pVbe, pScrn->virtualX); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x succeeded\n", - mode & 0x0fff); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Setting VESA mode 0x%x succeeded\n", + mode & 0x0fff); return (TRUE); } - /* - * Restore the initial (text) mode. + * Restore the initial mode. To be used internally only! */ static void SISRestore(ScrnInfoPtr pScrn) { - vgaHWPtr hwp; - vgaRegPtr vgaReg; - SISPtr pSiS; - SISRegPtr sisReg; + SISPtr pSiS = SISPTR(pScrn); + SISRegPtr sisReg = &pSiS->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + vgaRegPtr vgaReg = &hwp->SavedReg; + Bool doit = FALSE, doitlater = FALSE; - hwp = VGAHWPTR(pScrn); - pSiS = SISPTR(pScrn); - vgaReg = &hwp->SavedReg; - sisReg = &pSiS->SavedReg; + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + +#ifdef SISDUALHEAD + /* TW: We always restore master AND slave */ + if(pSiS->DualHeadMode && pSiS->SecondHead) return; +#endif + + /* TW: We must not disable the sequencer if the bridge is in SlaveMode! */ + if(!(SiSBridgeIsInSlaveMode(pScrn))) { + vgaHWProtect(pScrn, TRUE); + } + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL); +#endif + + /* TW: First, restore CRT1 on/off and VB connection registers */ + outSISIDXREG(SISCR, 0x32, pSiS->oldCR32); + if(!(pSiS->oldCR17 & 0x80)) { /* TW: CRT1 was off */ + if(!(SiSBridgeIsInSlaveMode(pScrn))) { /* TW: Bridge is NOT in SlaveMode now -> do it */ + doit = TRUE; + } else { + doitlater = TRUE; + } + } else { /* TW: CRT1 was on -> do it now */ + doit = TRUE; + } + + if(doit) { + outSISIDXREG(SISCR, 0x17, pSiS->oldCR17); + } + + /* TW: For 30xB/LV, restoring the registers does not + * work. We "manually" set the old mode, instead. + * The same applies for SiS730 machines with LVDS. + * Finally, this behavior can be forced by setting + * the option RestoreBySetMode. + */ + if( ( (pSiS->restorebyset) || + (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) || + ((pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) ) && + (pSiS->OldMode) ) { + + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); + } + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "Restoring by setting old mode 0x%02x\n", pSiS->OldMode); + + if( (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) && + (!pSiS->restorebyset) ) { + if(pSiS->OldMode == 0x03) pSiS->OldMode = 0x13; + } + + pSiS->SiS_Pr->UseCustomMode = FALSE; + pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE; + SiSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, pSiS->OldMode, FALSE); +#ifdef TWDEBUG + { + SISRegPtr pReg = &pSiS->ModeReg; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "REAL REGISTER CONTENTS AFTER RESTORE BY SETMODE:\n"); + (*pSiS->SiSSave)(pScrn, pReg); + } +#endif + + } else { - vgaHWProtect(pScrn, TRUE); + if(pSiS->VBFlags & VB_VIDEOBRIDGE) { + /* TW: If a video bridge is present, we need to restore + * non-extended (=standard VGA) SR and CR registers + * before restoring the extended ones and the bridge + * registers itself. Unfortunately, the vgaHWRestore + * routine clears CR17[7] - which must not be done if + * the bridge is in slave mode. + */ + if(!(SiSBridgeIsInSlaveMode(pScrn))) { + vgaHWProtect(pScrn, TRUE); + + if(pSiS->Primary) { + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + } + } + } + + (*pSiS->SiSRestore)(pScrn, sisReg); - (*pSiS->SiSRestore)(pScrn, sisReg); + } - SISRestoreExtRegisterLock(sisReg); + if(doitlater) { + outSISIDXREG(SISCR, 0x17, pSiS->oldCR17); + } - vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[0x05],sisReg->sisRegs3D4[0x80]); + + if( ( (pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) || + (pSiS->restorebyset) ) { + + /* TW: SiS730/LVDS has extreme problems restoring the text display due + * to over-sensible LCD panels + */ + + vgaHWProtect(pScrn, TRUE); + + if(pSiS->Primary) { + vgaHWRestore(pScrn, vgaReg, (VGA_SR_FONTS | VGA_SR_CMAP)); + } + + vgaHWProtect(pScrn, FALSE); + + } else { + + vgaHWProtect(pScrn, TRUE); + + if(pSiS->Primary) { + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + } + + vgaHWProtect(pScrn, FALSE); + + } + + } else { /* All other chipsets */ + + vgaHWProtect(pScrn, TRUE); +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL); +#endif + (*pSiS->SiSRestore)(pScrn, sisReg); + + vgaHWProtect(pScrn, TRUE); + if(pSiS->Primary) { + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + } - vgaHWProtect(pScrn, FALSE); + /* TW: Restore TV. This is rather complicated, but if we don't do it, + * TV output will flicker terribly + */ + if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { + if(sisReg->sis6326tv[0] & 0x04) { + unsigned char tmp; + int val; + + orSISIDXREG(SISSR, 0x01, 0x20); + tmp = SiS6326GetTVReg(pScrn,0x00); + tmp &= ~0x04; + while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */ + SiS6326SetTVReg(pScrn,0x00,tmp); + for(val=0; val < 2; val++) { + while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */ + while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */ + } + SiS6326SetTVReg(pScrn, 0x00, sisReg->sis6326tv[0]); + tmp = inSISREG(SISINPSTAT); + outSISREG(SISAR, 0x20); + tmp = inSISREG(SISINPSTAT); + while(inSISREG(SISINPSTAT) & 0x01); + while(!(inSISREG(SISINPSTAT) & 0x01)); + andSISIDXREG(SISSR, 0x01, ~0x20); + for(val=0; val < 10; val++) { + while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */ + while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */ + } + andSISIDXREG(SISSR, 0x01, ~0x20); + } + } + + sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[5],sisReg->sisRegs3D4[0x80]); + + vgaHWProtect(pScrn, FALSE); + } } static void @@ -1539,26 +4433,49 @@ SISVESARestore(ScrnInfoPtr pScrn) if(pSiS->UseVESA) SISVESASaveRestore(pScrn, MODE_RESTORE); } -/* TW: Restore bridge output registers - to be called BEFORE VESARestore */ +/* TW: Restore bridge registers - to be called BEFORE VESARestore */ static void SISBridgeRestore(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - if ( (pSiS->Chipset == PCI_CHIP_SIS300) || - (pSiS->Chipset == PCI_CHIP_SIS630) || - (pSiS->Chipset == PCI_CHIP_SIS540) ) { +#ifdef SISDUALHEAD + /* We only restore for master head */ + if(pSiS->DualHeadMode && pSiS->SecondHead) return; +#endif + + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + SiSRestoreBridge(pScrn, &pSiS->SavedReg); + } +} + +/* TW: Our generic BlockHandler for Xv */ +static void +SISBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[i]; + ScrnInfoPtr pScrn = xf86Screens[i]; + SISPtr pSiS = SISPTR(pScrn); + + pScreen->BlockHandler = pSiS->BlockHandler; + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScreen->BlockHandler = SISBlockHandler; - SiSRestoreBridge(pScrn, &pSiS->SavedReg); + if(pSiS->VideoTimerCallback) { + (*pSiS->VideoTimerCallback)(pScrn, currentTime.milliseconds); } } /* Mandatory - * This gets called at the start of each server generation */ + * This gets called at the start of each server generation + * + * TW: We use pScrn and not CurrentLayout here, because the + * properties we use have not changed (displayWidth, + * depth, bitsPerPixel) + */ static Bool SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { - /* The vgaHW references will disappear one day */ ScrnInfoPtr pScrn; vgaHWPtr hwp; SISPtr pSiS; @@ -1568,46 +4485,99 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) unsigned long OnScreenSize; int height, width, displayWidth; unsigned char *FBStart; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = NULL; +#endif - /* - * First get the ScrnInfoRec - */ pScrn = xf86Screens[pScreen->myNum]; hwp = VGAHWPTR(pScrn); - hwp->MapSize = 0x10000; /* Standard 64k VGA window */ - pSiS = SISPTR(pScrn); - if (pSiS->UseVESA) - pSiS->pVbe = VBEExtendedInit(NULL,pSiS->pEnt->index, SET_BIOS_SCRATCH - | RESTORE_BIOS_SCRATCH); + if(pSiS->UseVESA) { +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + pSiS->pVbe = VBEInit(NULL, pSiS->pEnt->index); +#else + pSiS->pVbe = VBEExtendedInit(NULL, pSiS->pEnt->index, + SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); +#endif + } + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pSiSEnt = pSiS->entityPrivate; + pSiSEnt->refCount++; + } +#endif /* Map the VGA memory and get the VGA IO base */ - if (!vgaHWMapMem(pScrn)) - return FALSE; + if(pSiS->Primary) { + hwp->MapSize = 0x10000; /* Standard 64k VGA window */ + if(!vgaHWMapMem(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not map VGA window\n"); + return FALSE; + } + } vgaHWGetIOBase(hwp); + /* TW: Patch the PIOOffset inside vgaHW to use + * our relocated IO ports. + */ + VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380; + /* Map the SIS memory and MMIO areas */ - if (!SISMapMem(pScrn)) + if(!SISMapMem(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSMapMem() failed\n"); return FALSE; + } + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + /* TW: Enable TurboQueue so that SISSave() saves it in enabled + * state. If we don't do this, X will hang after a restart! + * (Happens for some unknown reason only when using VESA + * for mode switching; assumingly a BIOS issue.) + * This is done on 300 and 310/325 series only. + */ + if(pSiS->UseVESA) { + SiSEnableTurboQueue(pScrn); + } /* Save the current state */ SISSave(pScrn); + /* TW: Save the current mode number */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + inSISIDXREG(SISCR, 0x34, pSiS->OldMode); + } + /* Initialise the first mode */ - if (!SISModeInit(pScrn, pScrn->currentMode)) + if(!SISModeInit(pScrn, pScrn->currentMode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSModeInit() failed\n"); return FALSE; + } - /* Clear frame buffer */ - OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay * (pScrn->bitsPerPixel / 8); - memset(pSiS->FbBase, 0, OnScreenSize); - - /* Darken the screen for aesthetic reasons and set the viewport */ + /* Darken the screen for aesthetic reasons */ + /* TW: Not using Dual Head variant on purpose; we darken + * the screen for both displays, and un-darken + * it when the second head is finished + */ SISSaveScreen(pScreen, SCREEN_SAVER_ON); + + /* Set the viewport */ SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + /* Clear frame buffer */ + OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay + * (pScrn->bitsPerPixel / 8); + bzero(pSiS->FbBase, OnScreenSize); + /* * The next step is to setup the screen's visuals, and initialise the * framebuffer code. In cases where the framebuffer's default @@ -1625,36 +4595,41 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) */ miClearVisualTypes(); - /* Setup the visuals we support. */ /* * For bpp > 8, the default visuals are not acceptable because we only * support TrueColor and not DirectColor. */ - - if (pScrn->bitsPerPixel > 8) { - if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, - pScrn->defaultVisual)) - return FALSE; - + if(pScrn->bitsPerPixel > 8) { + if(!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, + pScrn->defaultVisual)) { + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "miSetVisualTypes() failed (bpp %d)\n", pScrn->bitsPerPixel); + return FALSE; + } } else { - if (!miSetVisualTypes(pScrn->depth, + if(!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), - pScrn->rgbBits, pScrn->defaultVisual)) + pScrn->rgbBits, pScrn->defaultVisual)) { + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "miSetVisualTypes() failed (bpp %d)\n", pScrn->bitsPerPixel); return FALSE; + } } width = pScrn->virtualX; height = pScrn->virtualY; displayWidth = pScrn->displayWidth; - if (pSiS->Rotate) { + if(pSiS->Rotate) { height = pScrn->virtualX; width = pScrn->virtualY; } - if (pSiS->ShadowFB) { + if(pSiS->ShadowFB) { pSiS->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); pSiS->ShadowPtr = xalloc(pSiS->ShadowPitch * height); displayWidth = pSiS->ShadowPitch / (pScrn->bitsPerPixel >> 3); @@ -1664,18 +4639,39 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) FBStart = pSiS->FbBase; } - if (!miSetPixmapDepths()) + if(!miSetPixmapDepths()) { + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "miSetPixmapDepths() failed\n"); return FALSE; - - { - static int GlobalHWQueueLength = 0; - - pSiS->cmdQueueLenPtr = &(GlobalHWQueueLength); } +#ifdef SISDUALHEAD + if(pSiS->SecondHead) + pSiS->cmdQueueLenPtr = &(SISPTR(pSiSEnt->pScrn_1)->cmdQueueLen); + else +#endif + pSiS->cmdQueueLenPtr = &(pSiS->cmdQueueLen); + + pSiS->cmdQueueLen = 0; /* TW: Force an EngineIdle() at start */ + #ifdef XF86DRI - pSiS->directRenderingEnabled = SISDRIScreenInit(pScreen); - /* Force the initialization of the context */ +#ifdef SISDUALHEAD + /* TW: No DRI in dual head mode */ + if(pSiS->DualHeadMode) { + pSiS->directRenderingEnabled = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "DRI not supported in Dual Head mode\n"); + } else +#endif + /* Force the initialization of the context */ + if(pSiS->VGAEngine != SIS_315_VGA) { + pSiS->directRenderingEnabled = SISDRIScreenInit(pScreen); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED, + "DRI not supported on this chipset\n"); + pSiS->directRenderingEnabled = FALSE; + } #endif /* @@ -1683,41 +4679,42 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * pScreen fields. */ - switch (pScrn->bitsPerPixel) { - case 1: + switch(pScrn->bitsPerPixel) { + case 1: ret = xf1bppScreenInit(pScreen, FBStart, width, - height, pScrn->xDpi, pScrn->yDpi, + height, pScrn->xDpi, pScrn->yDpi, displayWidth); break; - case 4: + case 4: ret = xf4bppScreenInit(pScreen, FBStart, width, - height, pScrn->xDpi, pScrn->yDpi, + height, pScrn->xDpi, pScrn->yDpi, displayWidth); break; - case 8: - case 16: - case 24: - case 32: + case 8: + case 16: + case 24: + case 32: ret = fbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, pScrn->yDpi, displayWidth, pScrn->bitsPerPixel); init_picture = 1; break; - default: + default: xf86DrvMsg(scrnIndex, X_ERROR, "Internal error: invalid bpp (%d) in SISScrnInit\n", pScrn->bitsPerPixel); ret = FALSE; break; } - if (!ret) - { - ErrorF ("SetMode Error@!\n"); + if (!ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf1bpp/xf4bpp/fbScreenInit() failed\n"); + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); return FALSE; } - if (pScrn->bitsPerPixel > 8) { + if(pScrn->bitsPerPixel > 8) { /* Fixup RGB ordering */ visual = pScreen->visuals + pScreen->numVisuals; while (--visual >= pScreen->visuals) { @@ -1730,80 +4727,142 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) visual->blueMask = pScrn->mask.blue; } } - } else if (pScrn->depth == 1) { + } else if(pScrn->depth == 1) { SIS1bppColorMap(pScrn); } - /* must be after RGB ordering fixed */ - if (init_picture) - fbPictureInit(pScreen, 0, 0); - if (!pSiS->ShadowFB) /* hardware cursor needs to wrap this layer */ - SISDGAInit(pScreen); + /* Initialize RENDER ext; must be after RGB ordering fixed */ + if(init_picture) fbPictureInit(pScreen, 0, 0); + + /* hardware cursor needs to wrap this layer <-- TW: what does that mean? */ + if(!pSiS->ShadowFB) SISDGAInit(pScreen); + xf86SetBlackWhitePixels(pScreen); - if (!pSiS->NoAccel) { - if ( pSiS->Chipset == PCI_CHIP_SIS300 || - pSiS->Chipset == PCI_CHIP_SIS630 || - pSiS->Chipset == PCI_CHIP_SIS540) + if(!pSiS->NoAccel) { + switch(pSiS->VGAEngine) { + case SIS_530_VGA: + case SIS_300_VGA: SiS300AccelInit(pScreen); - else if (pSiS->Chipset == PCI_CHIP_SIS530) - SiS530AccelInit(pScreen); - else + break; + case SIS_315_VGA: + SiS310AccelInit(pScreen); + break; + default: SiSAccelInit(pScreen); + } } miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); /* Initialise cursor functions */ - miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); - if (pSiS->HWCursor) + if(pSiS->HWCursor) SiSHWCursorInit(pScreen); /* Initialise default colourmap */ - if (!miCreateDefColormap(pScreen)) - return FALSE; - -/* marked by archer for adding VB palette - if (!vgaHWHandleColormaps(pScreen)) + if(!miCreateDefColormap(pScreen)) { + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "miCreateDefColormap() failed\n"); return FALSE; -*/ - - if (!xf86HandleColormaps(pScreen, 256, 8, SISLoadPalette, NULL, - CMAP_RELOAD_ON_MODE_SWITCH)) + } + + if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits, + SISLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86HandleColormaps() failed\n"); return FALSE; + } if(pSiS->ShadowFB) { - RefreshAreaFuncPtr refreshArea = SISRefreshArea; - - if(pSiS->Rotate) { - if (!pSiS->PointerMoved) { - pSiS->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = SISPointerMoved; - } - - switch(pScrn->bitsPerPixel) { - case 8: refreshArea = SISRefreshArea8; break; - case 16: refreshArea = SISRefreshArea16; break; - case 24: refreshArea = SISRefreshArea24; break; - case 32: refreshArea = SISRefreshArea32; break; + RefreshAreaFuncPtr refreshArea = SISRefreshArea; + + if(pSiS->Rotate) { + if(!pSiS->PointerMoved) { + pSiS->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = SISPointerMoved; + } + + switch(pScrn->bitsPerPixel) { + case 8: refreshArea = SISRefreshArea8; break; + case 16: refreshArea = SISRefreshArea16; break; + case 24: refreshArea = SISRefreshArea24; break; + case 32: refreshArea = SISRefreshArea32; break; + } } - } - ShadowFBInit(pScreen, refreshArea); + ShadowFBInit(pScreen, refreshArea); } - - xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0); + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) + /* TW: DPMS for dual head mode */ + xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSetDH, 0); + else +#endif + xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0); + + /* Init memPhysBase and fbOffset in pScrn */ + pScrn->memPhysBase = pSiS->FbAddress; + pScrn->fbOffset = 0; #ifdef XvExtension - if (!pSiS->NoXvideo) { - /* HW Xv for SiS630 */ - if (pSiS->Chipset == PCI_CHIP_SIS630) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SiS630 HW Xv\n" ); - SISInitVideo(pScreen); - } - else { /* generic Xv */ + if(!pSiS->NoXvideo) { +#ifdef SISDUALHEAD + /* TW: On chipsets with only one overlay, we support + * Xv only in "real" dual head mode, not Xinerama + */ + if ( ((pSiS->VGAEngine == SIS_300_VGA) || + (pSiS->VGAEngine == SIS_315_VGA) ) + && + ((pSiS->hasTwoOverlays) || + (!pSiS->DualHeadMode) || + (noPanoramiXExtension) ) ) { +#else + if ( (pSiS->VGAEngine == SIS_300_VGA) || + (pSiS->VGAEngine == SIS_315_VGA) ) { +#endif +#ifdef SISDUALHEAD + if (pSiS->DualHeadMode) { + if ( pSiS->hasTwoOverlays || + (pSiS->XvOnCRT2 && (!pSiS->SecondHead)) || + ((!pSiS->XvOnCRT2 && pSiS->SecondHead)) ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using SiS300/310/325 series HW Xv on CRT%d\n", + (pSiS->SecondHead ? 1 : 2)); + SISInitVideo(pScreen); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Not using SiS300/310/325 series HW Xv on CRT%d\n", + (pSiS->SecondHead ? 1 : 2)); + } + } else { +#endif + if (pSiS->hasTwoOverlays) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using SiS300/310/325 series HW Xv\n" ); + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using SiS300/310/325 series HW Xv on CRT%d\n", + (pSiS->XvOnCRT2 ? 2 : 1)); + SISInitVideo(pScreen); +#ifdef SISDUALHEAD + } +#endif +#ifdef USE6326VIDEO + } else if( pSiS->Chipset == PCI_CHIP_SIS6326 || + pSiS->Chipset == PCI_CHIP_SIS530 || + pSiS->Chipset == PCI_CHIP_SIS5597 ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using SiS5597/5598/6326/530/620 HW Xv\n" ); + SIS6326InitVideo(pScreen); +#endif + } else { /* generic Xv */ XF86VideoAdaptorPtr *ptr; int n; @@ -1813,48 +4872,126 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86XVScreenInit(pScreen, ptr, n); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using generic Xv\n" ); } + if (!noPanoramiXExtension) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "HW Xv not supported in Xinerama mode\n"); } } #endif #ifdef XF86DRI - if (pSiS->directRenderingEnabled) { + if(pSiS->directRenderingEnabled) { /* Now that mi, drm and others have done their thing, * complete the DRI setup. */ pSiS->directRenderingEnabled = SISDRIFinishScreenInit(pScreen); } - if (pSiS->directRenderingEnabled) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n"); + if(pSiS->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); /* TODO */ /* SISSetLFBConfig(pSiS); */ } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n"); } #endif pSiS->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = SISCloseScreen; - pScreen->SaveScreen = SISSaveScreen; +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) + pScreen->SaveScreen = SISSaveScreenDH; + else +#endif + pScreen->SaveScreen = SISSaveScreen; + + /* Install BlockHandler */ + pSiS->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = SISBlockHandler; /* Report any unused options (only for the first generation) */ - if (serverGeneration == 1) { - xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + if(serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); } /* Turn on the screen now */ - SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + /* TW: We do this in dual head mode after second head is finished */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); + } else +#endif + SISSaveScreen(pScreen, SCREEN_SAVER_OFF); return TRUE; } - /* Usually mandatory */ Bool SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + SISPtr pSiS = SISPTR(pScrn); + + if(!pSiS->NoAccel) { + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); + } + } + + return SISModeInit(xf86Screens[scrnIndex], mode); +} + +#ifdef CYCLECRT2 +/* TW: Cycle CRT2 output devices */ +Bool +SISCycleCRT2Type(int scrnIndex, DisplayModePtr mode) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + SISPtr pSiS = SISPTR(pScrn); + int i = 0; + + /* TW: Only on 300 and 310/325 series */ + if(pSiS->VGAEngine != SIS_300_VGA && + pSiS->VGAEngine != SIS_315_VGA) return FALSE; + + /* TW: Only if there is a video bridge */ + if(pSiS->VBFlags & VB_VIDEOBRIDGE) return FALSE; + + /* TW: Only if there were more than 1 CRT2 devices detected */ + if(pSiS->detectedCRT2Devices & CRT2_VGA) i++; + if(pSiS->detectedCRT2Devices & CRT2_LCD) i++; + if(pSiS->detectedCRT2Devices & CRT2_TV) i++; + if(i <= 1) return FALSE; + + /* TW: Cycle CRT2 type */ + i = (pSiS->VBFlags & DISPTYPE_DISP2) << 1; + while(!(i & pSiS->detectedCRT2Devices)) { + i <<= 1; + if(i > CRT2_VGA) i = CRT2_LCD; + } + + /* TW: Check if mode is suitable for desired output device */ + if(!SiS_CheckCalcModeIndex(pScrn, pScrn->currentMode, + ((pSiS->VBFlags & ~(DISPTYPE_DISP2)) | i))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Current mode not suitable for desired CRT2 output device\n"); + return FALSE; + } + + /* TW: Sync the accelerators */ + if(!pSiS->NoAccel) { + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); + } + } + + pSiS->VBFlags &= ~(DISPTYPE_DISP2); + pSiS->VBFlags |= i; + return SISModeInit(xf86Screens[scrnIndex], mode); } +#endif /* * This function is used to initialize the Start Address - the first @@ -1867,100 +5004,142 @@ SISAdjustFrame(int scrnIndex, int x, int y, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; SISPtr pSiS; vgaHWPtr hwp; - int base = y * pScrn->displayWidth + x; - int vgaIOBase; + int base; unsigned char temp; - + hwp = VGAHWPTR(pScrn); pSiS = SISPTR(pScrn); - vgaIOBase = VGAHWPTR(pScrn)->IOBase; - - if (pSiS->UseVESA) { - /* TW: Let BIOS adjust frame if using VESA */ - VBESetDisplayStart(pSiS->pVbe, x, y, TRUE); - } - else { - - if (pScrn->bitsPerPixel < 8) { - base = (y * pScrn->displayWidth + x + 3) >> 3; - } else { - base = y * pScrn->displayWidth + x ; - /* calculate base bpp dep. */ - switch (pScrn->bitsPerPixel) { - case 16: - base >>= 1; - break; - case 24: - base = ((base * 3)) >> 2; - base -= base % 6; - break; - case 32: - break; - default: /* 8bpp */ - base >>= 2; - break; - } - } - - outw(vgaIOBase + 4, (base & 0x00FF00) | 0x0C); - outw(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D); - switch (pSiS->Chipset) { - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - outb(VGA_SEQ_INDEX, 0x0D); - temp = (base & 0xFF0000) >> 16; - PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "3C5/0Dh set to hex %2X, base 0x%x\n", temp, base)); - outb(VGA_SEQ_DATA, temp); - if (pSiS->VBFlags) { - /* UnLockCRT2(pSiS->RelIO); */ - sisUnLockCRT2(pSiS->RelIO+0x30); - outSISIDXREG(pSiS->RelIO+4, 6, GETVAR8(base)); - outSISIDXREG(pSiS->RelIO+4, 5, GETBITS(base, 15:8)); - outSISIDXREG(pSiS->RelIO+4, 4, GETBITS(base, 23:16)); - /* LockCRT2(pSiS->RelIO); */ - sisLockCRT2(pSiS->RelIO+0x30); - } - break; - default: - outb(VGA_SEQ_INDEX, 0x27); - temp = inb(VGA_SEQ_DATA) & 0xF0; - temp |= (base & 0x0F0000) >> 16; - PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "3C5/27h set to hex %2X, base %d\n", temp, base)); - outb(VGA_SEQ_DATA, temp); - } - + + base = y * pSiS->CurrentLayout.displayWidth + x; + + if(pSiS->UseVESA) { + + /* TW: Let BIOS adjust frame if using VESA */ + VBESetDisplayStart(pSiS->pVbe, x, y, TRUE); + + } else { + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if(pScrn->bitsPerPixel < 8) { + base = (y * pSiS->CurrentLayout.displayWidth + x + 3) >> 3; + } else { + base = y * pSiS->CurrentLayout.displayWidth + x; + + /* calculate base bpp dep. */ + switch(pSiS->CurrentLayout.bitsPerPixel) { + case 16: + base >>= 1; + break; + case 24: + base = ((base * 3)) >> 2; + base -= base % 6; + break; + case 32: + break; + default: /* 8bpp */ + base >>= 2; + break; + } + } + +#ifdef SISDUALHEAD + if (pSiS->DualHeadMode) { + /* TW: We assume that DualHeadMode only can be true for + * dual head capable chipsets (and thus save the check + * for chipset here) + */ + if (!pSiS->SecondHead) { + /* TW: Head 1 (master) is always CRT2 */ + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + outSISIDXREG(SISPART1, 0x06, GETVAR8(base)); + outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8)); + outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16)); + if (pSiS->VGAEngine == SIS_315_VGA) { + setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); + } + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + } else { + /* TW: Head 2 (slave) is always CRT1 */ + base += (pSiS->dhmOffset/4); + outSISIDXREG(SISCR, 0x0D, base & 0xFF); + outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); + outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); + if (pSiS->VGAEngine == SIS_315_VGA) { + setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); + } + } + } else { +#endif + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + outSISIDXREG(SISCR, 0x0D, base & 0xFF); + outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); + outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); + if (pSiS->VBFlags & CRT2_ENABLE) { + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + outSISIDXREG(SISPART1, 0x06, GETVAR8(base)); + outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8)); + outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16)); + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + } + break; + case SIS_315_VGA: + outSISIDXREG(SISCR, 0x0D, base & 0xFF); + outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); + outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); + setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); + if (pSiS->VBFlags & CRT2_ENABLE) { + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + outSISIDXREG(SISPART1, 0x06, GETVAR8(base)); + outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8)); + outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16)); + setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + } + break; + default: + outSISIDXREG(SISCR, 0x0D, base & 0xFF); + outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); + inSISIDXREG(SISSR, 0x27, temp); + temp &= 0xF0; + temp |= (base & 0x0F0000) >> 16; + outSISIDXREG(SISSR, 0x27, temp); + } +#ifdef SISDUALHEAD + } +#endif } /* if not VESA */ + } /* * 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. - * (TW: This might be dangerous with TQ) + * Mandatory! */ - -/* Mandatory */ static Bool SISEnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; -#ifdef XF86DRI SISPtr pSiS = SISPTR(pScrn); -#endif - SISSaveUnlockExtRegisterLock(NULL); - if (!SISModeInit(pScrn, pScrn->currentMode)) + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); + + if(!SISModeInit(pScrn, pScrn->currentMode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "SiSEnterVT: SISModeInit() failed\n"); return FALSE; + } SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); -#ifdef XF86DRI /* TW: this is to be done AFTER switching the mode */ - if (pSiS->directRenderingEnabled) +#ifdef XF86DRI + /* TW: this is to be done AFTER switching the mode */ + if(pSiS->directRenderingEnabled) DRIUnlock(screenInfo.screens[scrnIndex]); #endif @@ -1970,45 +5149,65 @@ SISEnterVT(int scrnIndex, int flags) /* * 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! */ - -/* Mandatory */ static void SISLeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; vgaHWPtr hwp = VGAHWPTR(pScrn); - SISPtr pSiS; - + SISPtr pSiS = SISPTR(pScrn); #ifdef XF86DRI ScreenPtr pScreen; -#endif - pSiS = SISPTR(pScrn); - -#ifdef XF86DRI /* TW: to be done before mode change */ - if (pSiS->directRenderingEnabled) { + /* TW: to be done before mode change */ + if(pSiS->directRenderingEnabled) { pScreen = screenInfo.screens[scrnIndex]; DRILock(pScreen, 0); } #endif +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode && pSiS->SecondHead) return; +#endif + + if(pSiS->CursorInfoPtr) { +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!pSiS->SecondHead) { + pSiS->ForceCursorOff = TRUE; + pSiS->CursorInfoPtr->HideCursor(pScrn); + SISWaitVBRetrace(pScrn); + pSiS->ForceCursorOff = FALSE; + } + } else { +#endif + pSiS->CursorInfoPtr->HideCursor(pScrn); + SISWaitVBRetrace(pScrn); +#ifdef SISDUALHEAD + } +#endif + } + SISBridgeRestore(pScrn); - if (pSiS->UseVESA) { + if(pSiS->UseVESA) { + /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2, - * VBESaveRestore() does not re-enable CRT1. So we set any mode now, + * VBESaveRestore() does not restore CRT1. So we set any mode now, * because VBESetVBEMode correctly restores CRT1. Afterwards, we * can call VBESaveRestore to restore original mode. */ if ( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2)) ) - VBESetVBEMode(pSiS->pVbe, (pSiS->VesaModeList->n) | 0xc000, NULL); + VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL); + SISVESARestore(pScrn); - } - SISRestore(pScrn); + } else { + + SISRestore(pScrn); + + } vgaHWLock(hwp); } @@ -2017,48 +5216,113 @@ SISLeaveVT(int scrnIndex, int flags) /* * This is called at the end of each server generation. It restores the * original (text) mode. It should really also unmap the video memory too. + * Mandatory! */ - -/* Mandatory */ static Bool SISCloseScreen(int scrnIndex, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; vgaHWPtr hwp = VGAHWPTR(pScrn); SISPtr pSiS = SISPTR(pScrn); - xf86CursorInfoPtr pCursorInfo = pSiS->CursorInfoPtr; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif #ifdef XF86DRI - if (pSiS->directRenderingEnabled) { + if(pSiS->directRenderingEnabled) { SISDRICloseScreen(pScreen); - pSiS->directRenderingEnabled=FALSE; + pSiS->directRenderingEnabled = FALSE; } #endif - if (pScrn->vtSema) { - if (pCursorInfo) - pCursorInfo->HideCursor(pScrn); + if(pScrn->vtSema) { + + if(pSiS->CursorInfoPtr) { +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(!pSiS->SecondHead) { + pSiS->ForceCursorOff = TRUE; + pSiS->CursorInfoPtr->HideCursor(pScrn); + SISWaitVBRetrace(pScrn); + pSiS->ForceCursorOff = FALSE; + } + } else { +#endif + pSiS->CursorInfoPtr->HideCursor(pScrn); + SISWaitVBRetrace(pScrn); +#ifdef SISDUALHEAD + } +#endif + } + SISBridgeRestore(pScrn); - if (pSiS->UseVESA) { - /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2, - * VBESaveRestore() does not re-enable CRT1. So we set any mode now, + + if(pSiS->UseVESA) { + + /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2, + * VBESaveRestore() does not restore CRT1. So we set any mode now, * because VBESetVBEMode correctly restores CRT1. Afterwards, we * can call VBESaveRestore to restore original mode. */ - if ( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2))) - VBESetVBEMode(pSiS->pVbe, (pSiS->VesaModeList->n) | 0xc000, NULL); + if( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2))) + VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL); + SISVESARestore(pScrn); + + } else { + + SISRestore(pScrn); + } - SISRestore(pScrn); + vgaHWLock(hwp); - SISUnmapMem(pScrn); } - if(pSiS->AccelInfoPtr) + + SISUnmapMem(pScrn); + vgaHWUnmapMem(pScrn); + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + pSiSEnt = pSiS->entityPrivate; + pSiSEnt->refCount--; + } +#endif + + if(pSiS->pInt) { + xf86FreeInt10(pSiS->pInt); + pSiS->pInt = NULL; + } + + if(pSiS->AccelInfoPtr) { XAADestroyInfoRec(pSiS->AccelInfoPtr); - if(pCursorInfo) - xf86DestroyCursorInfoRec(pCursorInfo); + pSiS->AccelInfoPtr = NULL; + } + + if(pSiS->CursorInfoPtr) { + xf86DestroyCursorInfoRec(pSiS->CursorInfoPtr); + pSiS->CursorInfoPtr = NULL; + } + + if(pSiS->ShadowPtr) { + xfree(pSiS->ShadowPtr); + pSiS->ShadowPtr = NULL; + } + + if(pSiS->DGAModes) { + xfree(pSiS->DGAModes); + pSiS->DGAModes = NULL; + } + + if(pSiS->adaptor) { + xfree(pSiS->adaptor); + pSiS->adaptor = NULL; + } + pScrn->vtSema = FALSE; - + + /* Restore Blockhandler */ + pScreen->BlockHandler = pSiS->BlockHandler; + pScreen->CloseScreen = pSiS->CloseScreen; return (*pScreen->CloseScreen)(scrnIndex, pScreen); } @@ -2085,17 +5349,23 @@ SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; SISPtr pSiS = SISPTR(pScrn); - if (pSiS->UseVESA) { - if (CalcVESAModeIndex(pScrn, mode)) - return (MODE_OK); - else - return (MODE_BAD); + if(pSiS->UseVESA) { + if(SiSCalcVESAModeIndex(pScrn, mode)) + return(MODE_OK); + else + return(MODE_BAD); } - if ((pSiS->Chipset == PCI_CHIP_SIS300) || - (pSiS->Chipset == PCI_CHIP_SIS630) || - (pSiS->Chipset == PCI_CHIP_SIS540)) { - if (sisCalcModeIndex(pScrn, mode) < 0x14) - return (MODE_BAD); + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { +#ifdef SISDUALHEAD + if((pSiS->DualHeadMode) && (pSiS->SecondHead)) { + /* DHM: Only check modes for CRT1 */ + if(SiS_CalcModeIndex(pScrn, mode) < 0x14) + return(MODE_BAD); + } else +#endif + if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags) < 0x14) + return(MODE_BAD); + } return(MODE_OK); @@ -2108,32 +5378,175 @@ static Bool SISSaveScreen(ScreenPtr pScreen, int mode) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + if ((pScrn != NULL) && pScrn->vtSema) { SISPtr pSiS = SISPTR(pScrn); + /* enable access to extended sequencer registers */ - outb(VGA_SEQ_INDEX, 0x11); - /* if not blanked obtain state of LCD blank flags set by BIOS */ - if (!pSiS->Blank) { - unsigned char val; - val = inb(VGA_SEQ_DATA); - pSiS->LCDon = val; - } - if (!xf86IsUnblank(mode)) { - pSiS->Blank = TRUE; - outb(VGA_SEQ_DATA, (pSiS->LCDon | 0x8)); - } else { - pSiS->Blank = FALSE; - /* don't just unblanking; use LCD state set by BIOS */ - outb(VGA_SEQ_DATA, (pSiS->LCDon)); +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if(pSiS->VGAEngine == SIS_300_VGA) { + + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + if(!xf86IsUnblank(mode)) { + pSiS->Blank = TRUE; + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + pSiS->Blank = FALSE; + SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } else { + /* if not blanked obtain state of LCD blank flags set by BIOS */ + if(!pSiS->Blank) { + inSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + + if(!xf86IsUnblank(mode)) { + pSiS->Blank = TRUE; + outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08); + } else { + pSiS->Blank = FALSE; + /* don't just unblanking; use LCD state set by BIOS */ + outSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + } + + } else if(pSiS->VGAEngine == SIS_315_VGA) { + + if(!pSiS->Blank) { + inSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + + if(pSiS->VBFlags & VB_CHRONTEL) { + if(!xf86IsUnblank(mode)) { + pSiS->Blank = TRUE; + SiS_Chrontel701xBLOff(pSiS->SiS_Pr); + } else { + pSiS->Blank = FALSE; + SiS_Chrontel701xBLOn(pSiS->SiS_Pr); + } + } else if(pSiS->VBFlags & VB_LVDS) { + if(!xf86IsUnblank(mode)) { + pSiS->Blank = TRUE; + outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08); + } else { + pSiS->Blank = FALSE; + outSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + } else if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) { + if(!xf86IsUnblank(mode)) { + pSiS->Blank = TRUE; + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + pSiS->Blank = FALSE; + SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } + } + } return vgaHWSaveScreen(pScreen, mode); } -#ifdef DEBUG -/* local used for debug */ +#ifdef SISDUALHEAD +/* TW: SaveScreen for dual head mode */ +static Bool +SISSaveScreenDH(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if ((pScrn != NULL) && pScrn->vtSema) { + + SISPtr pSiS = SISPTR(pScrn); + if (pSiS->SecondHead) { + + /* Slave head is always CRT1 */ + return vgaHWSaveScreen(pScreen, mode); + + } else { + + /* Master head is always CRT2 */ + + /* We can only blank LCD, not other CRT2 devices */ + if(!(pSiS->VBFlags & CRT2_LCD)) return TRUE; + + /* enable access to extended sequencer registers */ +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if(pSiS->VGAEngine == SIS_300_VGA) { + + if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) { + if(!xf86IsUnblank(mode)) { + pSiS->BlankCRT2 = TRUE; + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + pSiS->BlankCRT2 = FALSE; + SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } else { + /* if not blanked obtain state of LCD blank flags set by BIOS */ + if(!pSiS->BlankCRT2) { + inSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + + if (!xf86IsUnblank(mode)) { + pSiS->BlankCRT2 = TRUE; + outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08); + } else { + pSiS->BlankCRT2 = FALSE; + /* don't just unblank; use LCD state set by BIOS */ + outSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + } + + } else if(pSiS->VGAEngine == SIS_315_VGA) { + + if(!pSiS->BlankCRT2) { + inSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + + if(pSiS->VBFlags & VB_CHRONTEL) { + if(!xf86IsUnblank(mode)) { + pSiS->BlankCRT2 = TRUE; + SiS_Chrontel701xBLOff(pSiS->SiS_Pr); + } else { + pSiS->BlankCRT2 = FALSE; + SiS_Chrontel701xBLOn(pSiS->SiS_Pr); + } + } else if(pSiS->VBFlags & VB_LVDS) { + if(!xf86IsUnblank(mode)) { + pSiS->BlankCRT2 = TRUE; + outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08); + } else { + pSiS->BlankCRT2 = FALSE; + outSISIDXREG(SISSR, 0x11, pSiS->LCDon); + } + } else if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) { + if(!xf86IsUnblank(mode)) { + pSiS->BlankCRT2 = TRUE; + SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); + } else { + pSiS->BlankCRT2 = FALSE; + SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); + } + } + + } + } + } + return TRUE; +} +#endif + +#ifdef DEBUG +/* locally used for debug */ static void SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode) { @@ -2153,19 +5566,6 @@ SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode) xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Blank End : %x\n", mode->CrtcVBlankEnd); xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Total : %x\n", mode->CrtcVTotal); xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt VAdjusted : %x\n", mode->CrtcVAdjusted); - -/* - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Display : %x\n", mode->HDisplay); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Sync Start : %x\n", mode->HSyncStart); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Sync End : %x\n", mode->HSyncEnd); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Total : %x\n", mode->HTotal); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Hz Skew : %x\n", mode->HSkew); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Display : %x\n", mode->VDisplay); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Sync Start : %x\n", mode->VSyncStart); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Sync End : %x\n", mode->VSyncEnd); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Total : %x\n", mode->VTotal); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Vt Scan : %x\n", mode->VScan); -*/ } #endif @@ -2173,193 +5573,1737 @@ SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode) static void SISModifyModeInfo(DisplayModePtr mode) { -/* - mode->Clock = 31500; - mode->CrtcHTotal = 832; - mode->CrtcHDisplay = 640; - mode->CrtcHBlankStart = 648; - mode->CrtcHSyncStart = 664; - mode->CrtcHSyncEnd = 704; - mode->CrtcHBlankEnd = 824; - - mode->CrtcVTotal = 520; - mode->CrtcVDisplay = 480; - mode->CrtcVBlankStart = 488; - mode->CrtcVSyncStart = 489; - mode->CrtcVSyncEnd = 492; - mode->CrtcVBlankEnd = 512; -*/ - if (mode->CrtcHBlankStart == mode->CrtcHDisplay) +#if 1 + if(mode->CrtcHBlankStart == mode->CrtcHDisplay) mode->CrtcHBlankStart++; - if (mode->CrtcHBlankEnd == mode->CrtcHTotal) + if(mode->CrtcHBlankEnd == mode->CrtcHTotal) mode->CrtcHBlankEnd--; - if (mode->CrtcVBlankStart == mode->CrtcVDisplay) + if(mode->CrtcVBlankStart == mode->CrtcVDisplay) mode->CrtcVBlankStart++; - if (mode->CrtcVBlankEnd == mode->CrtcVTotal) + if(mode->CrtcVBlankEnd == mode->CrtcVTotal) mode->CrtcVBlankEnd--; +#endif } -void SiSPreSetMode(ScrnInfoPtr pScrn) +/* TW: Enable the TurboQueue (For 300 and 310/325 series only) */ +void +SiSEnableTurboQueue(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - unsigned char usScratchCR30, usScratchCR31; - unsigned char usScratchCR32, usScratchCR33; unsigned short SR26, SR27; unsigned long temp; - int vbflag; - - usScratchCR30 = usScratchCR31 = usScratchCR33 = 0; - outb(SISCR, 0x31); - usScratchCR31 = inb(SISCR+1); - outb(SISCR, 0x33); /* TW: CRT1 refresh rate index */ - usScratchCR33 = inb(SISCR+1); - outb(SISCR, 0x32); /* TW: Bridge connection info */ - usScratchCR32 = inb(SISCR+1); - outb(SISCR, 0x30); - usScratchCR30 = inb(SISCR+1); - - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Bridge registers were 30=0x%02x, 31=0x%02x, 32=0x%02x, " - "33=0x%02x (VBFlags=0x%x)\n", - usScratchCR30, usScratchCR31, usScratchCR32, - usScratchCR33, pSiS->VBFlags); - usScratchCR30 = 0; - usScratchCR31 &= ~0x60; /* TW: clear VB_Drivermode & VB_OutputDisable */ - - vbflag=pSiS->VBFlags; - switch (vbflag & (CRT2_TV|CRT2_LCD|CRT2_VGA)) - { case CRT2_TV: - if (vbflag & TV_HIVISION) - usScratchCR30 |= 0x80; - else if (vbflag & TV_SVIDEO) - usScratchCR30 |= 0x08; - else if (vbflag & TV_AVIDEO) - usScratchCR30 |= 0x04; - else if (vbflag & TV_SCART) - usScratchCR30 |= 0x10; - if (vbflag & TV_PAL) - usScratchCR31 |= 0x01; - else - usScratchCR31 &= ~0x01; -#if 0 /* TW: Old code */ - if (vbflag & TV_HIVISION) usScratchCR30 |= 0x80; - else if (vbflag & TV_PAL) usScratchCR31 |= 0x01; - if (vbflag & TV_AVIDEO) usScratchCR30 |= 0x04; - else if (vbflag & TV_SVIDEO) usScratchCR30 |= 0x08; - else if (vbflag & TV_SCART) usScratchCR30 |= 0x10; + switch (pSiS->VGAEngine) { + case SIS_300_VGA: + if ((!pSiS->NoAccel) && (pSiS->TurboQueue)) { + /* TQ size is always 512k */ + temp = (pScrn->videoRam/64) - 8; + SR26 = temp & 0xFF; + inSISIDXREG(SISSR, 0x27, SR27); + SR27 &= 0xFC; + SR27 |= (0xF0 | ((temp >> 8) & 3)); + outSISIDXREG(SISSR, 0x26, SR26); + outSISIDXREG(SISSR, 0x27, SR27); + } + break; + case SIS_315_VGA: + if (!pSiS->NoAccel) { + /* TW: On 310/325 series, there are three queue modes available + * which are chosen by setting bits 7:5 in SR26: + * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep + * track of the queue, the FIFO, command parsing and so + * on. This is the one comparable to the 300 series. + * 2. VRAM queue mode (bit 6, 0x40). In this case, one will + * have to do queue management himself. Register 0x85c4 will + * hold the location of the next free queue slot, 0x85c8 + * is the "queue read pointer" whose way of working is + * unknown to me. Anyway, this mode would require a + * translation of the MMIO commands to some kind of + * accelerator assembly and writing these commands + * to the memory location pointed to by 0x85c4. + * We will not use this, as nobody knows how this + * "assembly" works, and as it would require a complete + * re-write of the accelerator code. + * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the + * queue in AGP memory space. + * We go MMIO here. + * SR26 bit 4 is called "Bypass H/W queue". + * SR26 bit 1 is called "Enable Command Queue Auto Correction" + * SR26 bit 0 resets the queue + * Size of queue memory is encoded in bits 3:2 like this: + * 00 (0x00) 512K + * 01 (0x04) 1M + * 10 (0x08) 2M + * 11 (0x0C) 4M + * The queue location is to be written to 0x85C0. + */ +#if 0 + if (pSiS->TurboQueue) { #endif - usScratchCR30 |= 0x01; - usScratchCR31 &= ~0x04; - break; - case CRT2_LCD: - usScratchCR30 |= 0x21; - usScratchCR31 |= 0x02; - break; - case CRT2_VGA: - usScratchCR30 |= 0x41; - break; - default: /* TW: When CRT2Type is NONE, we can calculate a proper rate for CRT1 */ - usScratchCR30 |= 0x00; - usScratchCR31 |= 0x20; /* TW: VB_OUTPUT_DISABLE */ - if (pSiS->UseVESA) - usScratchCR33 = SISSearchCRT1Rate(pScrn->currentMode); + /* TW: We only use MMIO Cmd Queue, not VRAM or AGP */ + /* TW: Set Command Queue Threshold to max value 11111b */ + outSISIDXREG(SISSR, 0x27, 0x1F); + /* TW: Syncronous reset for Command Queue */ + outSISIDXREG(SISSR, 0x26, 0x01); + /* TW: Do some magic (cp readport to writeport) */ + temp = MMIO_IN32(pSiS->IOBase, 0x85C8); + MMIO_OUT32(pSiS->IOBase, 0x85C4, temp); + /* TW: Enable MMIO Command Queue mode (0x20), + * Enable_command_queue_auto_correction (0x02) + * (no idea, but sounds good, so use it) + * 512k (0x00) (does this apply to MMIO mode?) */ + outSISIDXREG(SISSR, 0x26, 0x22); + /* TW: Calc Command Queue position (Q is always 512k)*/ + temp = (pScrn->videoRam - 512) * 1024; + /* TW: Set Q position */ + MMIO_OUT32(pSiS->IOBase, 0x85C0, temp); +#if 0 + } else { + /* TW: Is there a non-TurboQueue mode within MMIO mode? */ + } +#endif + } + break; + default: + break; } - /* - * TW: for VESA: no DRIVERMODE, otherwise +} + +/* TW: Things to do before a ModeSwitch. We set up the + * video bridge configuration and the TurboQueue. + */ +void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char usScratchCR30, usScratchCR31; + unsigned char usScratchCR32, usScratchCR33; + unsigned char usScratchCR17, usScratchCR38 = 0; + int vbflag, temp = 0; + int crt1rateindex = 0; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); /* Unlock Registers */ +#endif + + vbflag = pSiS->VBFlags; + pSiS->IsCustom = FALSE; + + if(pSiS->HaveCustomModes) { + if(!(mode->type & M_T_DEFAULT)) { + pSiS->IsCustom = TRUE; + } + } + + /* TW: The CR3x registers are for communicating with our BIOS emulation + * code (native code in init.c/init301.c) or the BIOS (via VESA) + */ + inSISIDXREG(SISCR, 0x30, usScratchCR30); /* Bridge config */ + inSISIDXREG(SISCR, 0x31, usScratchCR31); /* Bridge config */ + usScratchCR32 = pSiS->newCR32; /* Bridge connection info (use our new value) */ + inSISIDXREG(SISCR, 0x33, usScratchCR33); /* CRT1 refresh rate index */ + if(pSiS->Chipset != PCI_CHIP_SIS300) { + switch(pSiS->VGAEngine) { + case SIS_300_VGA: temp = 0x35; break; + case SIS_315_VGA: temp = 0x38; break; + } + } + if(temp) inSISIDXREG(SISCR, temp, usScratchCR38); /* PAL-M, PAL-N selection */ + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "VBFlags=0x%x\n", pSiS->VBFlags); + + xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 3, + "Before: CR30=0x%02x, CR31=0x%02x, CR32=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n", + usScratchCR30, usScratchCR31, usScratchCR32, usScratchCR33, temp, usScratchCR38); + + usScratchCR30 = 0; + usScratchCR31 &= ~0x60; /* TW: Clear VB_Drivermode & VB_OutputDisable */ +#if 0 /* TW: For future use */ + if( (pSiS->VBFlags & VB_LVDS) || + (pSiS->VBFlags & VB_301) || + ( (pSiS->VBFlags & (VB_301B | VB_302B |VB_30xLV | VB_30xLVX)) && + (!(pSiS->VBLCDFlags & VB_LCD_1400x1050)) ) ) { +#endif + usScratchCR31 |= 0x04; /* TW: Set VB_NotSimuMode (not for 30xB/1400x1050?) */ +#if 0 + } +#endif + + switch(vbflag & (CRT2_TV|CRT2_LCD|CRT2_VGA)) { + case CRT2_TV: + if(vbflag & TV_CHSCART) { + usScratchCR38 |= 0x04; + usScratchCR31 |= 0x01; + } else if(vbflag & TV_CHHDTV) { + usScratchCR38 |= 0x08; + usScratchCR31 &= ~0x01; + } else if(vbflag & TV_HIVISION) + usScratchCR30 |= 0x80; + else if(vbflag & TV_SVIDEO) + usScratchCR30 |= 0x08; + else if(vbflag & TV_AVIDEO) + usScratchCR30 |= 0x04; + else if(vbflag & TV_SCART) + usScratchCR30 |= 0x10; + else + usScratchCR30 |= 0x08; /* default: SVIDEO */ + + if(!(vbflag & (TV_CHSCART | TV_CHHDTV))) { + if(vbflag & TV_PAL) { + usScratchCR31 |= 0x01; + usScratchCR38 &= ~0xC0; + if( (vbflag & VB_SISBRIDGE) || + ((vbflag & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_701x)) ) { + if(vbflag & TV_PALM) usScratchCR38 |= 0x40; + else if(vbflag & TV_PALN) usScratchCR38 |= 0x80; + } + } else + usScratchCR31 &= ~0x01; + } + + usScratchCR30 |= 0x01; /* Set SimuScanMode */ + + usScratchCR31 &= ~0x04; /* Clear NotSimuMode */ + pSiS->SiS_Pr->SiS_CHOverScan = pSiS->UseCHOverScan; + if(pSiS->OptTVSOver == 1) { + pSiS->SiS_Pr->SiS_CHSOverScan = TRUE; + } else { + pSiS->SiS_Pr->SiS_CHSOverScan = FALSE; + } + break; + case CRT2_LCD: + usScratchCR30 |= 0x21; /* LCD + SimuScanMode */ + break; + case CRT2_VGA: + usScratchCR30 |= 0x41; /* VGA2 + SimuScanMode */ + break; + default: + usScratchCR30 |= 0x00; + usScratchCR31 |= 0x20; /* VB_OUTPUT_DISABLE */ + if(pSiS->UseVESA) { + crt1rateindex = SISSearchCRT1Rate(pScrn, mode); + } + } + /* TW: for VESA: no DRIVERMODE, otherwise * -) CRT2 will not be initialized correctly when using mode - * where LCD has to scale + * where LCD has to scale, and * -) CRT1 will have too low rate */ - if (pSiS->UseVESA) usScratchCR31 &= ~0x40; - else usScratchCR31 |= 0x40; /* 0x40=drivermode */ + if (pSiS->UseVESA) { + usScratchCR31 &= 0x40; /* TW: Clear Drivermode */ +#ifdef TWDEBUG + usScratchCR31 |= 0x40; /* DEBUG (for non-slave mode VESA) */ + crt1rateindex = SISSearchCRT1Rate(pScrn, mode); +#endif + } else { + usScratchCR31 |= 0x40; /* TW: Set Drivermode */ + if(!pSiS->IsCustom) { + crt1rateindex = SISSearchCRT1Rate(pScrn, mode); + } else { + crt1rateindex = usScratchCR33; + } + } + outSISIDXREG(SISCR, 0x30, usScratchCR30); + outSISIDXREG(SISCR, 0x31, usScratchCR31); + if(temp) { + usScratchCR38 &= ~0x03; /* Clear LCDA/DualEdge bits */ + outSISIDXREG(SISCR, temp, usScratchCR38); + } + + pSiS->SiS_Pr->SiS_UseOEM = pSiS->OptUseOEM; + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) { + /* CRT1 */ + usScratchCR33 &= 0xf0; + usScratchCR33 |= (crt1rateindex & 0x0f); + } else { + /* CRT2 */ + usScratchCR33 &= 0x0f; + if(vbflag & CRT2_VGA) usScratchCR33 |= ((crt1rateindex << 4) & 0xf0); + } + } else { +#endif + if(vbflag & CRT2_VGA) { + usScratchCR33 = (crt1rateindex & 0x0f) | ((crt1rateindex & 0x0f) << 4); + } else { + usScratchCR33 = crt1rateindex & 0x0f; + } + if((!(pSiS->UseVESA)) && (vbflag & CRT2_ENABLE)) { +#ifndef TWDEBUG + if(pSiS->CRT1off) usScratchCR33 &= 0xf0; +#endif + } +#ifdef SISDUALHEAD + } +#endif + outSISIDXREG(SISCR, 0x33, usScratchCR33); + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + "After: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x\n", + usScratchCR30, usScratchCR31, usScratchCR33); + + /* Enable TurboQueue */ + SiSEnableTurboQueue(pScrn); + + if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE)) { + /* Switch on CRT1 for modes that require the bridge in SlaveMode */ + inSISIDXREG(SISCR, 0x17, usScratchCR17); + if(!(usScratchCR17 & 0x80)) { + orSISIDXREG(SISCR, 0x17, 0x80); + outSISIDXREG(SISSR, 0x00, 0x01); + usleep(10000); + outSISIDXREG(SISSR, 0x00, 0x03); + } + } + +} + +/* Functions for adjusting various TV settings */ + +/* These are used by the PostSetMode() functions as well as + * the (hopefully) upcoming display properties extension/tool. + * + * There is each a Set and a Get routine. The Set functions + * take a value of the same range as the corresponding option. + * The Get routines return a value of the same range (although + * not necessarily the same value as previously set because + * of the lower resolution of the respective setting compared + * to the valid range). + * The Get routines return -2 on error (eg. hardware does not + * support this setting). + * Note: The x and y positioning routines accept a position + * RELATIVE to the default position. All other routines + * take ABSOLUTE values. + * + * The Set functions will store the property regardless if TV is + * currently used or not and if the hardware supports the property + * or not. The Get routines will return this stored + * value if TV is not currently used (because the register does + * not contain the correct value then) or if the hardware supports + * the respective property. This should make it easier for the + * display property tool because it does not have to know the + * hardware features. + * + * All the routines are dual head aware. It does not matter + * if the function is called from the CRT1 or CRT2 session. + * The values will be stored in pSiSEnt if we're running dual. + */ + +void SiS_SetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->chtvlumabandwidthcvbs = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->chtvlumabandwidthcvbs = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_CHRONTEL)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + val /= 8; + if((val == 0) || (val == 1)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x03),0xFE); + } + break; + case CHRONTEL_701x: + val /= 4; + if((val >= 0) && (val <= 3)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x02),0xFC); + } + break; + } +} + +int SiS_GetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->chtvlumabandwidthcvbs; + else +#endif + return (int)pSiS->chtvlumabandwidthcvbs; + } else { +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x01) * 8); + case CHRONTEL_701x: + return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x03) * 4); + default: + return -2; + } + } +} + +void SiS_SetCHTVlumabandwidthsvideo(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->chtvlumabandwidthsvideo = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->chtvlumabandwidthsvideo = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_CHRONTEL)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + val /= 6; + if((val >= 0) && (val <= 2)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 9) | 0x03),0xF9); + } + break; + case CHRONTEL_701x: + val /= 4; + if((val >= 0) && (val <= 3)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 10) | 0x02),0xF3); + } + break; + } +} + +int SiS_GetCHTVlumabandwidthsvideo(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->chtvlumabandwidthsvideo; + else +#endif + return (int)pSiS->chtvlumabandwidthsvideo; + } else { +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x06) >> 1) * 6); + case CHRONTEL_701x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x0c) >> 2) * 4); + default: + return -2; + } + } +} + +void SiS_SetCHTVlumaflickerfilter(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->chtvlumaflickerfilter = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->chtvlumaflickerfilter = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_CHRONTEL)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + val /= 6; + if((val >= 0) && (val <= 2)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 10) | 0x01),0xF3); + } + break; + case CHRONTEL_701x: + val /= 4; + if((val >= 0) && (val <= 3)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 10) | 0x01),0xF3); + } + break; + } +} + +int SiS_GetCHTVlumaflickerfilter(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif - sisSetReg1(SISCR, 0x30, usScratchCR30); - sisSetReg1(SISCR, 0x31, usScratchCR31); - sisSetReg1(SISCR, 0x33, usScratchCR33); + if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->chtvlumaflickerfilter; + else +#endif + return (int)pSiS->chtvlumaflickerfilter; + } else { +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 6); + case CHRONTEL_701x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 4); + default: + return -2; + } + } +} + +void SiS_SetCHTVchromabandwidth(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->chtvchromabandwidth = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->chtvchromabandwidth = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_CHRONTEL)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + val /= 4; + if((val >= 0) && (val <= 3)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x03),0xCF); + } + break; + case CHRONTEL_701x: + val /= 8; + if((val >= 0) && (val <= 1)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x02),0xEF); + } + break; + } +} + +int SiS_GetCHTVchromabandwidth(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->chtvchromabandwidth; + else +#endif + return (int)pSiS->chtvchromabandwidth; + } else { +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x30) >> 4) * 4); + case CHRONTEL_701x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x10) >> 4) * 8); + default: + return -2; + } + } +} + +void SiS_SetCHTVchromaflickerfilter(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->chtvchromaflickerfilter = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->chtvchromaflickerfilter = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_CHRONTEL)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + val /= 6; + if((val >= 0) && (val <= 2)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x01),0xCF); + } + break; + case CHRONTEL_701x: + val /= 4; + if((val >= 0) && (val <= 3)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x01),0xCF); + } + break; + } +} + +int SiS_GetCHTVchromaflickerfilter(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->chtvchromaflickerfilter; + else +#endif + return (int)pSiS->chtvchromaflickerfilter; + } else { +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x30) >> 4) * 6); + case CHRONTEL_701x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x30) >> 4) * 4); + default: + return -2; + } + } +} + +void SiS_SetCHTVcvbscolor(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->chtvcvbscolor = val ? 1 : 0; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->chtvcvbscolor = pSiS->chtvcvbscolor; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_CHRONTEL)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + if(!val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x4003,0x00); + else SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x0003,~0x40); + break; + case CHRONTEL_701x: + if(!val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x0002,~0x20); + else SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x2002,0x00); + break; + } +} + +int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->chtvcvbscolor; + else +#endif + return (int)pSiS->chtvcvbscolor; + } else { +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x40) >> 6) ^ 0x01); + case CHRONTEL_701x: + return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x20) >> 5) ^ 0x01); + default: + return -2; + } + } +} + +void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->chtvtextenhance = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->chtvtextenhance = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_CHRONTEL)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + val /= 6; + if((val >= 0) && (val <= 2)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x01),0xFC); + } + break; + case CHRONTEL_701x: + val /= 2; + if((val >= 0) && (val <= 7)) { + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x03),0xF8); + } + break; + } +} + +int SiS_GetCHTVtextenhance(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->chtvtextenhance; + else +#endif + return (int)pSiS->chtvtextenhance; + } else { +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x03) * 6); + case CHRONTEL_701x: + return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x07) * 2); + default: + return -2; + } + } +} + +void SiS_SetCHTVcontrast(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->chtvcontrast = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->chtvcontrast = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_CHRONTEL)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + val /= 2; + if((val >= 0) && (val <= 7)) { + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x11),0xF8); + break; + case CHRONTEL_701x: + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x08),0xF8); + break; + } + } +} + +int SiS_GetCHTVcontrast(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->chtvcontrast; + else +#endif + return (int)pSiS->chtvcontrast; + } else { +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x11) & 0x07) * 2); + case CHRONTEL_701x: + return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x08) & 0x07) * 2); + default: + return -2; + } + } +} + +void SiS_SetSISTVedgeenhance(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->sistvedgeenhance = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->sistvedgeenhance = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_301)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + val /= 2; + if((val >= 0) && (val <= 7)) { + setSISIDXREG(SISPART2,0x3A, 0x1F, (val << 5)); + } +} + +int SiS_GetSISTVedgeenhance(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_301 && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->sistvedgeenhance; + else +#endif + return (int)pSiS->sistvedgeenhance; + } else { + unsigned char temp; +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + inSISIDXREG(SISPART2, 0x3a, temp); + return(int)(((temp & 0xe0) >> 5) * 2); + } +} + +void SiS_SetSISTVantiflicker(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->sistvantiflicker = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->sistvantiflicker = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_SISBRIDGE)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + val /= 2; + if((val >= 0) && (val <= 7)) { + setSISIDXREG(SISPART2,0x0A,0x8F, (val << 4)); + } +} + +int SiS_GetSISTVantiflicker(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_SISBRIDGE && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->sistvantiflicker; + else +#endif + return (int)pSiS->sistvantiflicker; + } else { + unsigned char temp; +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + inSISIDXREG(SISPART2, 0x0a, temp); + return(int)(((temp & 0x70) >> 4) * 2); + } +} + +void SiS_SetSISTVsaturation(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + pSiS->sistvsaturation = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->sistvsaturation = val; +#endif + + if(!(pSiS->VBFlags & CRT2_TV)) return; + if(!(pSiS->VBFlags & VB_SISBRIDGE)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + val /= 2; + if((val >= 0) && (val <= 7)) { + setSISIDXREG(SISPART4,0x21,0xF8, val); + } +} + +int SiS_GetSISTVsaturation(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + + if(!(pSiS->VBFlags & VB_SISBRIDGE && pSiS->VBFlags & CRT2_TV)) { +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->sistvsaturation; + else +#endif + return (int)pSiS->sistvsaturation; + } else { + unsigned char temp; +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + inSISIDXREG(SISPART4, 0x21, temp); + return(int)((temp & 0x07) * 2); + } +} + +void SiS_SetSIS6326TVantiflicker(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char tmp; + + pSiS->sis6326antiflicker = val; + + if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Bridge registers set to 30=0x%02x, 31=0x%02x, 33=0x%02x\n", - usScratchCR30, usScratchCR31, usScratchCR33); + tmp = SiS6326GetTVReg(pScrn,0x00); + if(!(tmp & 0x04)) return; + + /* Valid values: 0=off, 1=low, 2=med, 3=high, 4=adaptive */ + if(val >= 0 && val <= 4) { + tmp &= 0x1f; + tmp |= (val << 5); + SiS6326SetTVReg(pScrn,0x00,tmp); + } +} + +int SiS_GetSIS6326TVantiflicker(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char tmp; + + if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) { + return (int)pSiS->sis6326antiflicker; + } + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + tmp = SiS6326GetTVReg(pScrn,0x00); + if(!(tmp & 0x04)) { + return (int)pSiS->sis6326antiflicker; + } else { + return (int)((tmp >> 5) & 0x07); + } +} + +void SiS_SetSIS6326TVenableyfilter(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char tmp; + + if(val) val = 1; + pSiS->sis6326enableyfilter = val; + + if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif - /* Set Turbo Queue as 512K */ - /* TW: This is done here _and_ in SiS300Init() because SiS300Init() only - * sets up structure but structure is not written to hardware (using - * SiS300Restore) on SiS630, 300, 540 (unless VESA is used). - */ - if (!pSiS->NoAccel) { - if (pSiS->TurboQueue) { - temp = (pScrn->videoRam/64) - 8; - SR26 = temp & 0xFF; - SR27 = ((temp >> 8) & 3) | 0xF0; - sisSetReg1(SISSR, 0x26, SR26); - sisSetReg1(SISSR, 0x27, SR27); - } - } + tmp = SiS6326GetTVReg(pScrn,0x00); + if(!(tmp & 0x04)) return; + + tmp = SiS6326GetTVReg(pScrn,0x43); + tmp &= ~0x10; + tmp |= ((val & 0x01) << 4); + SiS6326SetTVReg(pScrn,0x43,tmp); } -/* TW: This doesn't work yet. Switching CRT1 off this way causes a white screen on CRT2 */ -void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg, int LockAfterwards) +int SiS_GetSIS6326TVenableyfilter(ScrnInfoPtr pScrn) { -#if 0 - SISPtr pSiS = SISPTR(pScrn); - unsigned char usScratchCR17; - unsigned char SR5State; + SISPtr pSiS = SISPTR(pScrn); + unsigned char tmp; + + if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) { + return (int)pSiS->sis6326enableyfilter; + } + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + tmp = SiS6326GetTVReg(pScrn,0x00); + if(!(tmp & 0x04)) { + return (int)pSiS->sis6326enableyfilter; + } else { + tmp = SiS6326GetTVReg(pScrn,0x43); + return (int)((tmp >> 4) & 0x01); + } +} + +void SiS_SetSIS6326TVyfilterstrong(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char tmp; + + if(val) val = 1; + pSiS->sis6326yfilterstrong = val; + + if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + tmp = SiS6326GetTVReg(pScrn,0x00); + if(!(tmp & 0x04)) return; + + tmp = SiS6326GetTVReg(pScrn,0x43); + if(tmp & 0x10) { + tmp &= ~0x40; + tmp |= ((val & 0x01) << 6); + SiS6326SetTVReg(pScrn,0x43,tmp); + } +} - outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */ - SR5State = inb(VGA_SEQ_DATA); - outw(VGA_SEQ_INDEX, 0x8605); +int SiS_GetSIS6326TVyfilterstrong(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char tmp; + + if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) { + return (int)pSiS->sis6326yfilterstrong; + } + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + tmp = SiS6326GetTVReg(pScrn,0x00); + if(!(tmp & 0x04)) { + return (int)pSiS->sis6326yfilterstrong; + } else { + tmp = SiS6326GetTVReg(pScrn,0x43); + if(!(tmp & 0x10)) { + return (int)pSiS->sis6326yfilterstrong; + } else { + return (int)((tmp >> 6) & 0x01); + } + } +} + +void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif - if ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) && - pScrn->bitsPerPixel == 8) - pSiS->CRT1off = 0; + pSiS->tvxpos = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->tvxpos = val; +#endif - xf86DrvMsg(0, X_PROBED, "CRT1off %d\n", pSiS->CRT1off); + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + + if(pSiS->VBFlags & CRT2_TV) { + + if(pSiS->VBFlags & VB_CHRONTEL) { + + int x = pSiS->tvx; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) x = pSiSEnt->tvx; +#endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + if((val >= -32) && (val <= 32)) { + x += val; + if(x < 0) x = 0; + SiS_SetCH700x(pSiS->SiS_Pr, (((x & 0xff) << 8) | 0x0a)); + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, (((x & 0x0100) << 1) | 0x08),0xFD); + } + break; + case CHRONTEL_701x: + /* TO DO */ + break; + } + + } else if(pSiS->VBFlags & VB_SISBRIDGE) { + + if((val >= -32) && (val <= 32)) { + unsigned char p2_1f,p2_2b,p2_2c,p2_2d,p2_43; + const unsigned char p2_left_ntsc[8][4] = { + { 0x48, 0x63, 0x49, 0xf4 }, + { 0x45, 0x60, 0x46, 0xf1 }, + { 0x43, 0x6e, 0x44, 0xff }, + { 0x40, 0x6b, 0x41, 0xfc }, + { 0x3e, 0x69, 0x3f, 0xfa }, + { 0x3c, 0x67, 0x3d, 0xf8 }, + { 0x39, 0x64, 0x3a, 0xf5 }, + { 0x37, 0x62, 0x38, 0xf3 } + }; + const unsigned char p2_right_ntsc[8][4] = { + { 0x4b, 0x66, 0x4c, 0xf7 }, + { 0x4c, 0x67, 0x4d, 0xf8 }, + { 0x4e, 0x69, 0x4f, 0xfa }, + { 0x4f, 0x6a, 0x50, 0xfb }, + { 0x51, 0x6c, 0x52, 0xfd }, + { 0x53, 0x6e, 0x54, 0xff }, + { 0x55, 0x60, 0x56, 0xf1 }, + { 0x56, 0x61, 0x57, 0xf2 } + }; + const unsigned char p2_left_pal[8][4] = { + { 0x5b, 0x66, 0x5c, 0x87 }, + { 0x59, 0x64, 0x5a, 0x85 }, + { 0x56, 0x61, 0x57, 0x82 }, + { 0x53, 0x6e, 0x54, 0x8f }, + { 0x50, 0x6b, 0x51, 0x8c }, + { 0x4d, 0x68, 0x4e, 0x89 }, + { 0x4a, 0x65, 0x4b, 0x86 }, + { 0x49, 0x64, 0x4a, 0x85 } + }; + const unsigned char p2_right_pal[8][4] = { + { 0x5f, 0x6a, 0x60, 0x8b }, + { 0x61, 0x6c, 0x62, 0x8d }, + { 0x63, 0x6e, 0x64, 0x8f }, + { 0x65, 0x60, 0x66, 0x81 }, + { 0x66, 0x61, 0x67, 0x82 }, + { 0x68, 0x63, 0x69, 0x84 }, + { 0x69, 0x64, 0x6a, 0x85 }, + { 0x6b, 0x66, 0x6c, 0x87 } + }; + val /= 4; + p2_2d = pSiS->p2_2d; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) p2_2d = pSiSEnt->p2_2d; +#endif + p2_2d &= 0xf0; + if(val < 0) { + val = -val; + if(val == 8) val = 7; + if(pSiS->VBFlags & TV_PAL) { + p2_1f = p2_left_pal[val][0]; + p2_2b = p2_left_pal[val][1]; + p2_2c = p2_left_pal[val][2]; + p2_2d |= (p2_left_pal[val][3] & 0x0f); + } else { + p2_1f = p2_left_ntsc[val][0]; + p2_2b = p2_left_ntsc[val][1]; + p2_2c = p2_left_ntsc[val][2]; + p2_2d |= (p2_left_ntsc[val][3] & 0x0f); + } + } else { + if(val == 8) val = 7; + if(pSiS->VBFlags & TV_PAL) { + p2_1f = p2_right_pal[val][0]; + p2_2b = p2_right_pal[val][1]; + p2_2c = p2_right_pal[val][2]; + p2_2d |= (p2_right_pal[val][3] & 0x0f); + } else { + p2_1f = p2_right_ntsc[val][0]; + p2_2b = p2_right_ntsc[val][1]; + p2_2c = p2_right_ntsc[val][2]; + p2_2d |= (p2_right_ntsc[val][3] & 0x0f); + } + } + p2_43 = p2_1f + 3; + SISWaitRetraceCRT2(pScrn); + outSISIDXREG(SISPART2,0x1f,p2_1f); + outSISIDXREG(SISPART2,0x2b,p2_2b); + outSISIDXREG(SISPART2,0x2c,p2_2c); + outSISIDXREG(SISPART2,0x2d,p2_2d); + outSISIDXREG(SISPART2,0x43,p2_43); + } + } + } + + } else if(pSiS->Chipset == PCI_CHIP_SIS6326) { + + if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) { + + unsigned char tmp; + unsigned short temp1, temp2, temp3; + + tmp = SiS6326GetTVReg(pScrn,0x00); + if(tmp & 0x04) { + + temp1 = pSiS->tvx1; + temp2 = pSiS->tvx2; + temp3 = pSiS->tvx3; + if((val >= -16) && (val <= 16)) { + if(val > 0) { + temp1 += (val * 4); + temp2 += (val * 4); + while((temp1 > 0x0fff) || (temp2 > 0x0fff)) { + temp1 -= 4; + temp2 -= 4; + } + } else { + val = -val; + temp3 += (val * 4); + while(temp3 > 0x03ff) { + temp3 -= 4; + } + } + } + SiS6326SetTVReg(pScrn,0x3a,(temp1 & 0xff)); + tmp = SiS6326GetTVReg(pScrn,0x3c); + tmp &= 0xf0; + tmp |= ((temp1 & 0x0f00) >> 8); + SiS6326SetTVReg(pScrn,0x3c,tmp); + SiS6326SetTVReg(pScrn,0x26,(temp2 & 0xff)); + tmp = SiS6326GetTVReg(pScrn,0x27); + tmp &= 0x0f; + tmp |= ((temp2 & 0x0f00) >> 4); + SiS6326SetTVReg(pScrn,0x27,tmp); + SiS6326SetTVReg(pScrn,0x12,(temp3 & 0xff)); + tmp = SiS6326GetTVReg(pScrn,0x13); + tmp &= ~0xC0; + tmp |= ((temp3 & 0x0300) >> 2); + SiS6326SetTVReg(pScrn,0x13,tmp); + } + } + } +} - outb(SISCR, 0x17); - usScratchCR17 = inb(SISCR+1); +int SiS_GetTVxposoffset(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->tvxpos; + else +#endif + return (int)pSiS->tvxpos; +} - xf86DrvMsg(0, X_PROBED, "CR17 was 0x%2x\n", usScratchCR17); - if (pSiS->CRT1off) - usScratchCR17 &= ~0x80; /* sisReg->sisRegs3D4[0x17] &= ~0x80; */ - else - usScratchCR17 |= 0x80; /* sisReg->sisRegs3D4[0x17] |= 0x80; */ +void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif - xf86DrvMsg(0, X_PROBED, "CR17 set to 0x%2x\n", usScratchCR17); - /* SetReg1(SISCR, 0x17, usScratchCR17); */ + pSiS->tvypos = val; +#ifdef SISDUALHEAD + if(pSiSEnt) pSiSEnt->tvypos = val; +#endif - if (LockAfterwards) - outw(VGA_SEQ_INDEX, (SR5State << 8) | 0x05); /* Relock Registers */ + if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { + + if(pSiS->VBFlags & CRT2_TV) { + + if(pSiS->VBFlags & VB_CHRONTEL) { + + int y = pSiS->tvy; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) y = pSiSEnt->tvy; #endif + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + if((val >= -32) && (val <= 32)) { + y -= val; + if(y < 0) y = 0; + SiS_SetCH700x(pSiS->SiS_Pr, (((y & 0xff) << 8) | 0x0b)); + SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((y & 0x0100) | 0x08),0xFE); + } + break; + case CHRONTEL_701x: + /* TO DO */ + break; + } + + } else if(pSiS->VBFlags & VB_SISBRIDGE) { + + if((val >= -32) && (val <= 32)) { + char p2_01, p2_02; + val /= 4; + p2_01 = pSiS->p2_01; + p2_02 = pSiS->p2_02; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) { + p2_01 = pSiSEnt->p2_01; + p2_02 = pSiSEnt->p2_02; + } +#endif + p2_01 += (val * 2); + p2_02 += (val * 2); + while((p2_01 <= 0) || (p2_02 <= 0)) { + p2_01 += 2; + p2_02 += 2; + } + SISWaitRetraceCRT2(pScrn); + outSISIDXREG(SISPART2,0x01,p2_01); + outSISIDXREG(SISPART2,0x02,p2_02); + } + } + + } + + } else if(pSiS->Chipset == PCI_CHIP_SIS6326) { + + if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) { + + unsigned char tmp; + int temp1, limit; + + tmp = SiS6326GetTVReg(pScrn,0x00); + if(tmp & 0x04) { + + if((val >= -16) && (val <= 16)) { + temp1 = (unsigned short)pSiS->tvy1; + limit = (pSiS->SiS6326Flags & SIS6326_TVPAL) ? 625 : 525; + if(val > 0) { + temp1 += (val * 4); + if(temp1 > limit) temp1 -= limit; + } else { + val = -val; + temp1 -= (val * 2); + if(temp1 <= 0) temp1 += (limit -1); + } + SiS6326SetTVReg(pScrn,0x11,(temp1 & 0xff)); + tmp = SiS6326GetTVReg(pScrn,0x13); + tmp &= ~0x30; + tmp |= ((temp1 & 0x300) >> 4); + SiS6326SetTVReg(pScrn,0x13,tmp); + if(temp1 == 1) tmp = 0x10; + else { + if(pSiS->SiS6326Flags & SIS6326_TVPAL) { + if((temp1 <= 3) || (temp1 >= (limit - 2))) tmp = 0x08; + else if(temp1 < 22) tmp = 0x02; + else tmp = 0x04; + } else { + if((temp1 <= 5) || (temp1 >= (limit - 4))) tmp = 0x08; + else if(temp1 < 19) tmp = 0x02; + else tmp = 0x04; + } + } + SiS6326SetTVReg(pScrn,0x21,tmp); + } + } + } + } } +int SiS_GetTVyposoffset(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiSEnt && pSiS->DualHeadMode) + return (int)pSiSEnt->tvypos; + else +#endif + return (int)pSiS->tvypos; +} -static void -SISSaveUnlockExtRegisterLock(SISRegPtr sisReg) +/* TW: Disable CRT1 for saving bandwidth. This doesn't work with VESA; + * VESA uses the bridge in SlaveMode and switching CRT1 off while the + * bridge is in SlaveMode not that clever... + */ +void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) { + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; +#endif + unsigned char usScratchCR17; + Bool flag = FALSE; + Bool doit = TRUE; + int temp; + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "CRT1off is %d\n", pSiS->CRT1off); +#endif + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE)) { + + if(pSiS->VBFlags != pSiS->VBFlags_backup) { + pSiS->VBFlags = pSiS->VBFlags_backup; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VBFlags restored to %0lx\n", pSiS->VBFlags); + } + + /* TW: -) We can't switch off CRT1 if bridge is in SlaveMode. + * -) If we change to a SlaveMode-Mode (like 512x384), we + * need to adapt VBFlags for eg. Xv. + */ +#ifdef SISDUALHEAD + if(!pSiS->DualHeadMode) { +#endif + if(SiSBridgeIsInSlaveMode(pScrn)) { + doit = FALSE; + temp = pSiS->VBFlags; + pSiS->VBFlags &= (~VB_DISPMODE_SINGLE); + pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_DISP1); + if(temp != pSiS->VBFlags) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "VBFlags changed to 0x%0lx\n", pSiS->VBFlags); + } + } +#ifdef SISDUALHEAD + } +#endif + if(doit) { + inSISIDXREG(SISCR, 0x17, usScratchCR17); + if(pSiS->CRT1off) { + if(usScratchCR17 & 0x80) flag = TRUE; + usScratchCR17 &= ~0x80; + } else { + if(!(usScratchCR17 & 0x80)) flag = TRUE; + usScratchCR17 |= 0x80; + } + outSISIDXREG(SISCR, 0x17, usScratchCR17); + /* TW: Reset only if status changed */ + if(flag) { + outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ + usleep(10000); + outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ + } + } + } + + /* TW: Apply TV settings given by options + Do this even in DualHeadMode: + - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1 + - if this is called by SetModeCRT2, CRT2 mode has changed (duh!) + -> In both cases, the settings must be re-applied. + */ + if(pSiS->VBFlags & CRT2_TV) { + int val; + if(pSiS->VBFlags & VB_CHRONTEL) { + int mychtvlumabandwidthcvbs = pSiS->chtvlumabandwidthcvbs; + int mychtvlumabandwidthsvideo = pSiS->chtvlumabandwidthsvideo; + int mychtvlumaflickerfilter = pSiS->chtvlumaflickerfilter; + int mychtvchromabandwidth = pSiS->chtvchromabandwidth; + int mychtvchromaflickerfilter = pSiS->chtvchromaflickerfilter; + int mychtvcvbscolor = pSiS->chtvcvbscolor; + int mychtvtextenhance = pSiS->chtvtextenhance; + int mychtvcontrast = pSiS->chtvcontrast; + int mytvxpos = pSiS->tvxpos; + int mytvypos = pSiS->tvypos; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) { + mychtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs; + mychtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo; + mychtvlumaflickerfilter = pSiSEnt->chtvlumaflickerfilter; + mychtvchromabandwidth = pSiSEnt->chtvchromabandwidth; + mychtvchromaflickerfilter = pSiSEnt->chtvchromaflickerfilter; + mychtvcvbscolor = pSiSEnt->chtvcvbscolor; + mychtvtextenhance = pSiSEnt->chtvtextenhance; + mychtvcontrast = pSiSEnt->chtvcontrast; + mytvxpos = pSiSEnt->tvxpos; + mytvypos = pSiSEnt->tvypos; + } +#endif + if((val = mychtvlumabandwidthcvbs) != -1) { + SiS_SetCHTVlumabandwidthcvbs(pScrn, val); + } + if((val = mychtvlumabandwidthsvideo) != -1) { + SiS_SetCHTVlumabandwidthsvideo(pScrn, val); + } + if((val = mychtvlumaflickerfilter) != -1) { + SiS_SetCHTVlumaflickerfilter(pScrn, val); + } + if((val = mychtvchromabandwidth) != -1) { + SiS_SetCHTVchromabandwidth(pScrn, val); + } + if((val = mychtvchromaflickerfilter) != -1) { + SiS_SetCHTVchromaflickerfilter(pScrn, val); + } + if((val = mychtvcvbscolor) != -1) { + SiS_SetCHTVcvbscolor(pScrn, val); + } + if((val = mychtvtextenhance) != -1) { + SiS_SetCHTVtextenhance(pScrn, val); + } + if((val = mychtvcontrast) != -1) { + SiS_SetCHTVcontrast(pScrn, val); + } + /* Backup default TV position registers */ + switch(pSiS->ChrontelType) { + case CHRONTEL_700x: + pSiS->tvx = SiS_GetCH700x(pSiS->SiS_Pr, 0x0a); + pSiS->tvx |= (((SiS_GetCH700x(pSiS->SiS_Pr, 0x08) & 0x02) >> 1) << 8); + pSiS->tvy = SiS_GetCH700x(pSiS->SiS_Pr, 0x0b); + pSiS->tvy |= ((SiS_GetCH700x(pSiS->SiS_Pr, 0x08) & 0x01) << 8); +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) { + pSiSEnt->tvx = pSiS->tvx; + pSiSEnt->tvy = pSiS->tvy; + } +#endif + break; + case CHRONTEL_701x: + /* TO DO */ + break; + } + if((val = mytvxpos) != 0) { + SiS_SetTVxposoffset(pScrn, val); + } + if((val = mytvypos) != 0) { + SiS_SetTVyposoffset(pScrn, val); + } + } + if(pSiS->VBFlags & VB_301) { + int mysistvedgeenhance = pSiS->sistvedgeenhance; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) { + mysistvedgeenhance = pSiSEnt->sistvedgeenhance; + } +#endif + if((val = mysistvedgeenhance) != -1) { + SiS_SetSISTVedgeenhance(pScrn, val); + } + } + if(pSiS->VBFlags & VB_SISBRIDGE) { + int mysistvantiflicker = pSiS->sistvantiflicker; + int mysistvsaturation = pSiS->sistvsaturation; + int mytvxpos = pSiS->tvxpos; + int mytvypos = pSiS->tvypos; +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) { + mysistvantiflicker = pSiSEnt->sistvantiflicker; + mysistvsaturation = pSiSEnt->sistvsaturation; + mytvxpos = pSiSEnt->tvxpos; + mytvypos = pSiSEnt->tvypos; + } +#endif + /* Backup default TV position registers */ + inSISIDXREG(SISPART2,0x2d,pSiS->p2_2d); + inSISIDXREG(SISPART2,0x01,pSiS->p2_01); + inSISIDXREG(SISPART2,0x02,pSiS->p2_02); +#ifdef SISDUALHEAD + if(pSiSEnt && pSiS->DualHeadMode) { + pSiSEnt->p2_2d = pSiS->p2_2d; + pSiSEnt->p2_01 = pSiS->p2_01; + pSiSEnt->p2_02 = pSiS->p2_02; + } +#endif + if((val = mysistvantiflicker) != -1) { + SiS_SetSISTVantiflicker(pScrn, val); + } + if((val = mysistvsaturation) != -1) { + SiS_SetSISTVsaturation(pScrn, val); + } + if((val = mytvxpos) != 0) { + SiS_SetTVxposoffset(pScrn, val); + } + if((val = mytvypos) != 0) { + SiS_SetTVyposoffset(pScrn, val); + } + } + } - outb(VGA_SEQ_INDEX,0x05); - /* save State */ - if (sisReg) - sisReg->sisRegs3C4[5] = inb (VGA_SEQ_DATA); - /* unlock */ - outb(VGA_SEQ_DATA, 0x86); } -static void -SISRestoreExtRegisterLock(SISRegPtr sisReg) +/* Post-set SiS6326 TV registers */ +void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) { - /* restore lock */ - outw(VGA_SEQ_DATA,sisReg->sisRegs3C4[5] << 8 | 0x05); + SISPtr pSiS = SISPTR(pScrn); + unsigned char tmp; + int val; + + if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + /* Backup default TV position registers */ + pSiS->tvx1 = SiS6326GetTVReg(pScrn,0x3a); + pSiS->tvx1 |= ((SiS6326GetTVReg(pScrn,0x3c) & 0x0f) << 8); + pSiS->tvx2 = SiS6326GetTVReg(pScrn,0x26); + pSiS->tvx2 |= ((SiS6326GetTVReg(pScrn,0x27) & 0xf0) << 4); + pSiS->tvx3 = SiS6326GetTVReg(pScrn,0x12); + pSiS->tvx3 |= ((SiS6326GetTVReg(pScrn,0x13) & 0xC0) << 2); + pSiS->tvy1 = SiS6326GetTVReg(pScrn,0x11); + pSiS->tvy1 |= ((SiS6326GetTVReg(pScrn,0x13) & 0x30) << 4); + + /* TW: Handle TVPosOffset options (BEFORE switching on TV) */ + if((val = pSiS->tvxpos) != 0) { + SiS_SetTVxposoffset(pScrn, val); + } + if((val = pSiS->tvypos) != 0) { + SiS_SetTVyposoffset(pScrn, val); + } + + /* TW: Switch on TV output. This is rather complicated, but + * if we don't do it, TV output will flicker terribly. + */ + if(pSiS->SiS6326Flags & SIS6326_TVON) { + orSISIDXREG(SISSR, 0x01, 0x20); + tmp = SiS6326GetTVReg(pScrn,0x00); + tmp &= ~0x04; + while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */ + SiS6326SetTVReg(pScrn,0x00,tmp); + for(val=0; val < 2; val++) { + while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */ + while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */ + } + SiS6326SetTVReg(pScrn, 0x00, sisReg->sis6326tv[0]); + tmp = inSISREG(SISINPSTAT); + outSISREG(SISAR, 0x20); + tmp = inSISREG(SISINPSTAT); + while(inSISREG(SISINPSTAT) & 0x01); + while(!(inSISREG(SISINPSTAT) & 0x01)); + andSISIDXREG(SISSR, 0x01, ~0x20); + for(val=0; val < 10; val++) { + while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */ + while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */ + } + andSISIDXREG(SISSR, 0x01, ~0x20); + } + + tmp = SiS6326GetTVReg(pScrn,0x00); + if(!(tmp & 0x04)) return; + + /* TW: Apply TV settings given by options */ + if((val = pSiS->sis6326antiflicker) != -1) { + SiS_SetSIS6326TVantiflicker(pScrn, val); + } + if((val = pSiS->sis6326enableyfilter) != -1) { + SiS_SetSIS6326TVenableyfilter(pScrn, val); + } + if((val = pSiS->sis6326yfilterstrong) != -1) { + SiS_SetSIS6326TVyfilterstrong(pScrn, val); + } + } +/* Check if video bridge is in slave mode */ +BOOLEAN +SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char usScratchP1_00; + + if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return FALSE; + + inSISIDXREG(SISPART1,0x00,usScratchP1_00); + if( ((pSiS->VGAEngine == SIS_300_VGA) && (usScratchP1_00 & 0xa0) == 0x20) || + ((pSiS->VGAEngine == SIS_315_VGA) && (usScratchP1_00 & 0x50) == 0x10) ) { + return TRUE; + } else { + return FALSE; + } +} + +/* TW: Build a list of the VESA modes the BIOS reports as valid */ static void -SiSBuildVesaModeList(int scrnIndex, vbeInfoPtr pVbe, VbeInfoBlock *vbe) +SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; SISPtr pSiS = SISPTR(pScrn); int i = 0; - while (vbe->VideoModePtr[i] != 0xffff) { + + while(vbe->VideoModePtr[i] != 0xffff) { sisModeInfoPtr m; VbeModeInfoBlock *mode; int id = vbe->VideoModePtr[i++]; @@ -2368,39 +7312,38 @@ SiSBuildVesaModeList(int scrnIndex, vbeInfoPtr pVbe, VbeInfoBlock *vbe) if ((mode = VBEGetModeInfo(pVbe, id)) == NULL) continue; - bpp = mode->BitsPerPixel; - /* TW: Doesn't work on SiS630 VBE 3.0: */ - /* mode->GreenMaskSize + mode->BlueMaskSize - + mode->RedMaskSize; */ + bpp = mode->BitsPerPixel; m = xnfcalloc(sizeof(sisModeInfoRec),1); m->width = mode->XResolution; m->height = mode->YResolution; m->bpp = bpp; m->n = id; - m->next = pSiS->VesaModeList; + m->next = pSiS->SISVESAModeList; - xf86DrvMsgVerb(scrnIndex, X_PROBED, 3, - "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n", - m->n, m->width, m->height, m->bpp); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n", + m->n, m->width, m->height, m->bpp); - pSiS->VesaModeList = m; + pSiS->SISVESAModeList = m; VBEFreeModeInfo(mode); } } -static UShort CalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) +/* TW: Calc VESA mode from given resolution/depth */ +static UShort +SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) { SISPtr pSiS = SISPTR(pScrn); - sisModeInfoPtr m = pSiS->VesaModeList; + sisModeInfoPtr m = pSiS->SISVESAModeList; UShort i = (pScrn->bitsPerPixel+7)/8 - 1; UShort ModeIndex = 0; - while (m) { - if (pScrn->bitsPerPixel == m->bpp - && mode->HDisplay == m->width - && mode->VDisplay == m->height) + while(m) { + if(pScrn->bitsPerPixel == m->bpp && + mode->HDisplay == m->width && + mode->VDisplay == m->height) return m->n; m = m->next; } @@ -2410,97 +7353,296 @@ static UShort CalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) mode->HDisplay, mode->VDisplay, pScrn->bitsPerPixel); switch(mode->HDisplay) { - case 640: - ModeIndex = VESAModeIndex_640x480[i]; - break; - case 720: - if(mode->VDisplay == 480) - ModeIndex = VESAModeIndex_720x480[i]; - else - ModeIndex = VESAModeIndex_720x576[i]; - break; - case 800: - ModeIndex = VESAModeIndex_800x600[i]; - break; - case 1024: - ModeIndex = VESAModeIndex_1024x768[i]; - break; - case 1280: - ModeIndex = VESAModeIndex_1280x1024[i]; - break; - case 1600: - ModeIndex = VESAModeIndex_1600x1200[i]; - break; - case 1920: - ModeIndex = VESAModeIndex_1920x1440[i]; - break; - } - - if (!ModeIndex) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "No valid mode found for %dx%dx%d in built-in table either.", - mode->HDisplay, mode->VDisplay, pScrn->bitsPerPixel); - - return(ModeIndex); + case 512: + if(mode->VDisplay == 384) + ModeIndex = VESAModeIndex_512x384[i]; + break; + case 640: + if(mode->VDisplay == 480) + ModeIndex = VESAModeIndex_640x480[i]; + break; + case 800: + if(mode->VDisplay == 600) + ModeIndex = VESAModeIndex_800x600[i]; + break; + case 1024: + if(mode->VDisplay == 768) + ModeIndex = VESAModeIndex_1024x768[i]; + break; + case 1280: + if(mode->VDisplay == 1024) + ModeIndex = VESAModeIndex_1280x1024[i]; + break; + case 1600: + if(mode->VDisplay == 1200) + ModeIndex = VESAModeIndex_1600x1200[i]; + break; + case 1920: + if(mode->VDisplay == 1440) + ModeIndex = VESAModeIndex_1920x1440[i]; + break; + } + + if(!ModeIndex) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "No valid mode found for %dx%dx%d in built-in table either.\n", + mode->HDisplay, mode->VDisplay, pScrn->bitsPerPixel); + + return(ModeIndex); } -/* TW: Calculate CR33 (rate index) for CRT1 if CRT2 is disabled. - Calculation is done using currentmode structure, therefore - it is recommended to set VertRefresh and HorizSync to correct - values in Config file. - */ -unsigned char SISSearchCRT1Rate(DisplayModePtr mode) +/* TW: Calculate the vertical refresh rate from a mode */ +int +SiSCalcVRate(DisplayModePtr mode) { float hsync, refresh = 0; - int i = 0; - unsigned short xres=mode->HDisplay; - unsigned short yres=mode->VDisplay; - unsigned char index; - if (mode->HSync > 0.0) + if(mode->HSync > 0.0) hsync = mode->HSync; - else if (mode->HTotal > 0) + else if(mode->HTotal > 0) hsync = (float)mode->Clock / (float)mode->HTotal; else hsync = 0.0; - if (mode->VTotal > 0) + + if(mode->VTotal > 0) refresh = hsync * 1000.0 / mode->VTotal; - if (mode->Flags & V_INTERLACE) { + + if(mode->Flags & V_INTERLACE) refresh *= 2.0; - } - if (mode->Flags & V_DBLSCAN) { + + if(mode->Flags & V_DBLSCAN) refresh /= 2.0; - } - if (mode->VScan > 1) { + + if(mode->VScan > 1) refresh /= mode->VScan; - } - if (mode->VRefresh > 0.0) + + if(mode->VRefresh > 0.0) refresh = mode->VRefresh; - if (hsync == 0 || refresh == 0) - return 0x02; /* TW: Default mode index */ - else { - index = 0; - while ((sisx_vrate[i].idx != 0) && (sisx_vrate[i].xres <= xres)) { - if ((sisx_vrate[i].xres == xres) - && (sisx_vrate[i].yres == yres)) { - if (sisx_vrate[i].refresh == refresh) { - index = sisx_vrate[i].idx; - break; - } else if (sisx_vrate[i].refresh > refresh) { - if ((sisx_vrate[i].refresh - refresh) <= 2) { - index = sisx_vrate[i].idx; - } else if (((refresh - sisx_vrate[i - 1].refresh) <= 2) - && (sisx_vrate[i].idx != 1)) { - index = sisx_vrate[i - 1].idx; - } - break; + + if(hsync == 0 || refresh == 0) return(0); + + return((int)(refresh)); +} + +/* TW: Calculate CR33 (rate index) for CRT1. + * Calculation is done using currentmode, therefore it is + * recommended to set VertRefresh and HorizSync to correct + * values in config file. + */ +unsigned char +SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + SISPtr pSiS = SISPTR(pScrn); + int i = 0; + int irefresh; + unsigned short xres = mode->HDisplay; + unsigned short yres = mode->VDisplay; + unsigned char index; + BOOLEAN checksis730 = FALSE; + + irefresh = SiSCalcVRate(mode); + if(!irefresh) { + if(xres == 800 || xres == 1024 || xres == 1280) return 0x02; + else return 0x01; + } + + /* SiS730 has troubles on CRT2 if CRT1 is at 32bpp */ + if( (pSiS->sishw_ext.jChipType == SIS_730) && + (pSiS->VBFlags & VB_VIDEOBRIDGE) && + (pSiS->CurrentLayout.bitsPerPixel == 32) ) { +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) { + checksis730 = TRUE; + } + } else +#endif + if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE) && (!pSiS->CRT1off)) { + checksis730 = TRUE; + } + } + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh); +#endif + + /* We need the REAL refresh rate here */ + if(mode->Flags & V_INTERLACE) + irefresh /= 2; + + /* Do not multiply by 2 when DBLSCAN! */ + +#ifdef TWDEBUG + xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh); +#endif + + index = 0; + while((sisx_vrate[i].idx != 0) && (sisx_vrate[i].xres <= xres)) { + if((sisx_vrate[i].xres == xres) && (sisx_vrate[i].yres == yres)) { + if((checksis730 == FALSE) || (sisx_vrate[i].SiS730valid32bpp == TRUE)) { + if(sisx_vrate[i].refresh == irefresh) { + index = sisx_vrate[i].idx; + break; + } else if(sisx_vrate[i].refresh > irefresh) { + if((sisx_vrate[i].refresh - irefresh) <= 3) { + index = sisx_vrate[i].idx; + } else if( ((checksis730 == FALSE) || (sisx_vrate[i - 1].SiS730valid32bpp == TRUE)) && + ((irefresh - sisx_vrate[i - 1].refresh) <= 2) && + (sisx_vrate[i].idx != 1) ) { + index = sisx_vrate[i - 1].idx; + } + break; + } } } i++; - } - if (index > 0) + } + if(index > 0) return index; - else - return 0x02; /* TW: Default Rate index */ + else { + /* TW: Default Rate index */ + if(xres == 800 || xres == 1024 || xres == 1280) return 0x02; + else return 0x01; } } +void +SISWaitRetraceCRT1(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + int watchdog; + unsigned char temp; + + inSISIDXREG(SISCR,0x17,temp); + if(!(temp & 0x80)) return; + + watchdog = 65536; + while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog); + watchdog = 65536; + while((inSISREG(SISINPSTAT) & 0x08) && --watchdog); +} + +void +SISWaitRetraceCRT2(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + int watchdog; + unsigned char temp, reg; + + switch(pSiS->VGAEngine) { + case SIS_300_VGA: + reg = 0x28; + break; + case SIS_315_VGA: + reg = 0x33; + break; + default: + return; + } + + watchdog = 65536; + do { + inSISIDXREG(SISPART1, reg, temp); + if(temp & 0x80) break; + } while(--watchdog); + watchdog = 65536; + do { + inSISIDXREG(SISPART1, reg, temp); + if(!(temp & 0x80)) break; + } while(--watchdog); +} + +static void +SISWaitVBRetrace(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiS->SecondHead) + SISWaitRetraceCRT1(pScrn); + else + SISWaitRetraceCRT2(pScrn); + } else { +#endif + if(pSiS->VBFlags & DISPTYPE_DISP1) { + SISWaitRetraceCRT1(pScrn); + } + if(pSiS->VBFlags & DISPTYPE_DISP2) { + if(!(SiSBridgeIsInSlaveMode(pScrn))) { + SISWaitRetraceCRT2(pScrn); + } + } +#ifdef SISDUALHEAD + } +#endif +} + +void +sisSaveUnlockExtRegisterLock(SISPtr pSiS, unsigned char *reg1, unsigned char *reg2) +{ + register unsigned char val; + unsigned long mylockcalls; + + pSiS->lockcalls++; + mylockcalls = pSiS->lockcalls; + + /* check if already unlocked */ + inSISIDXREG(SISSR, 0x05, val); + if(val != 0xa1) { + /* save State */ + if(reg1) *reg1 = val; + /* unlock */ + outSISIDXREG(SISSR, 0x05, 0x86); + inSISIDXREG(SISSR, 0x05, val); + if(val != 0xA1) { +#ifdef TWDEBUG + unsigned char val1, val2; + int i; +#endif + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR, + "Failed to unlock sr registers (%p, %x, 0x%02x; %d)\n", + pSiS, pSiS->RelIO, val, mylockcalls); +#ifdef TWDEBUG + for(i = 0; i <= 0x3f; i++) { + inSISIDXREG(SISSR, i, val1); + inSISIDXREG(0x3c4, i, val2); + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, + "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n", i, val1, val2, mylockcalls); + } +#endif + if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) { + /* Emergency measure: unlock at 0x3c4, and try to enable Relocated IO ports */ + outSISIDXREG(0x3c4,0x05,0x86); + andSISIDXREG(0x3c4,0x33,~0x20); + outSISIDXREG(SISSR, 0x05, 0x86); + } + } + } + if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) { + inSISIDXREG(SISCR, 0x80, val); + if(val != 0xa1) { + /* save State */ + if(reg2) *reg2 = val; + outSISIDXREG(SISCR, 0x80, 0x86); + inSISIDXREG(SISCR, 0x80, val); + if(val != 0xA1) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR, + "Failed to unlock cr registers (%p, %x, 0x%02x)\n", + pSiS, pSiS->RelIO, val); + } + } + } +} + +void +sisRestoreExtRegisterLock(SISPtr pSiS, unsigned char reg1, unsigned char reg2) +{ + /* restore lock */ +#ifndef UNLOCK_ALWAYS + outSISIDXREG(SISSR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00); + if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) { + outSISIDXREG(SISCR, 0x80, reg2 == 0xA1 ? 0x86 : 0x00); + } +#endif +} + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c index 66019fd43..d8ed1144c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c @@ -1,4 +1,30 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c,v 1.7 2002/04/04 14:05:48 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.c,v 1.10 2003/01/29 15:42:17 eich Exp $ */ +/* + * Video bridge detection and configuration for 300 and 310/325 series + * + * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * + * 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 Thomas Winischhofer not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Thomas Winischhofer makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THOMAS WINISCHHOFER 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: Thomas Winischhofer <thomas@winischhofer.net> + * (Completely rewritten) + */ #include "xf86.h" #include "xf86_ansic.h" @@ -9,148 +35,319 @@ #include "sis_regs.h" #include "sis_vb.h" -/* TW: Detect CRT2-LCD and LCD size */ +static const SiS_LCD_StStruct SiS300_LCD_Type[]= +{ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 0 - invalid */ + { VB_LCD_800x600, 800, 600, LCD_800x600, 0}, /* 1 */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 2 */ + { VB_LCD_1280x1024,1280, 1024, LCD_1280x1024, 2}, /* 3 */ + { VB_LCD_1280x960, 1280, 960, LCD_1280x960, 3}, /* 4 */ + { VB_LCD_640x480, 640, 480, LCD_640x480, 4}, /* 5 */ + { VB_LCD_1024x600, 1024, 600, LCD_1024x600, 10}, /* 6 */ + { VB_LCD_1152x768, 1152, 768, LCD_1152x768, 7}, /* 7 */ + { VB_LCD_320x480, 320, 480, LCD_320x480, 6}, /* 8 */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 9 */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* a */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* b */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* c */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* d */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* e */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* f */ +}; + +static const SiS_LCD_StStruct SiS310_LCD_Type[]= +{ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 0 - invalid */ + { VB_LCD_800x600, 800, 600, LCD_800x600, 0}, /* 1 */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* 2 */ + { VB_LCD_1280x1024, 1280,1024, LCD_1280x1024, 2}, /* 3 */ + { VB_LCD_640x480, 640, 480, LCD_640x480, 4}, /* 4 */ + { VB_LCD_1024x600, 1024, 600, LCD_1024x600, 10}, /* 5 */ + { VB_LCD_1152x864, 1152, 864, LCD_1152x864, 11}, /* 6 */ + { VB_LCD_1280x960, 1280, 960, LCD_1280x960, 3}, /* 7 */ + { VB_LCD_1152x768, 1152, 768, LCD_1152x768, 7}, /* 8 */ + { VB_LCD_1400x1050, 1400,1050, LCD_1400x1050, 8}, /* 9 */ + { VB_LCD_1280x768, 1280, 768, LCD_1280x768, 9}, /* a */ + { VB_LCD_1600x1200, 1600,1200, LCD_1600x1200, 5}, /* b */ + { VB_LCD_320x480, 320, 480, LCD_320x480, 6}, /* c */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* d */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1}, /* e */ + { VB_LCD_1024x768, 1024, 768, LCD_1024x768, 1} /* f */ +}; + +static const char *panelres[] = { + "800x600", + "1024x768", + "1280x1024", + "1280x960", + "640x480", + "1600x1200", + "320x480", + "1152x768", + "1400x1050", + "1280x768", + "1024x600", + "1152x864" +}; + +/* Detect CRT1 */ +void SISCRT1PreInit(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + unsigned char CR32, SR17; + unsigned char CRT1Detected = 0; + unsigned char OtherDevices = 0; + + if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) { + pSiS->CRT1off = 0; + return; + } + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode && pSiS->SecondHead) { + pSiS->CRT1off = 0; + return; + } +#endif + + inSISIDXREG(SISCR, 0x32, CR32); + inSISIDXREG(SISSR, 0x17, SR17); + + if ( (pSiS->VGAEngine == SIS_300_VGA) && + (pSiS->Chipset != PCI_CHIP_SIS300) && + (SR17 & 0x0F) ) { + + if(SR17 & 0x01) CRT1Detected = 1; + if(SR17 & 0x0E) OtherDevices = 1; + + } else { + + if(CR32 & 0x20) CRT1Detected = 1; + if(CR32 & 0x5F) OtherDevices = 1; + + } + + if(pSiS->CRT1off == -1) { + if(!CRT1Detected) { + + /* BIOS detected no CRT1. */ + /* If other devices exist, switch it off */ + if(OtherDevices) pSiS->CRT1off = 1; + else pSiS->CRT1off = 0; + + } else { + + /* BIOS detected CRT1, leave/switch it on */ + pSiS->CRT1off = 0; + + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "%sCRT1 connection detected\n", + CRT1Detected ? "" : "No "); +} + +/* Detect CRT2-LCD and LCD size */ void SISLCDPreInit(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - int CR32, SR17, CR36; + unsigned char CR32, SR17, CR36, CR37; + USHORT textindex; - if (!(pSiS->VBFlags & VB_VIDEOBRIDGE)) + if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) { return; + } + + inSISIDXREG(SISCR, 0x32, CR32); + inSISIDXREG(SISSR, 0x17, SR17); - inSISIDXREG(pSiS->RelIO+CROFFSET, 0x32, CR32); - inSISIDXREG(pSiS->RelIO+SROFFSET, 0x17, SR17); - - if ( (SR17 & 0x0F) && (pSiS->Chipset != PCI_CHIP_SIS300) ) { - if ( (SR17 & 0x01) && (!pSiS->CRT1off) ) - pSiS->CRT1off = 0; - else { - if (SR17 & 0x0E) - pSiS->CRT1off = 1; - else - pSiS->CRT1off = 0; - } - if (SR17 & 0x02) + if( (pSiS->VGAEngine == SIS_300_VGA) && + (pSiS->Chipset != PCI_CHIP_SIS300) && + (SR17 & 0x0F) ) { + if(SR17 & 0x02) pSiS->VBFlags |= CRT2_LCD; } else { - if ( (CR32 & 0x20) && (!pSiS->CRT1off) ) - pSiS->CRT1off = 0; - else { - if (CR32 & 0x5F) - pSiS->CRT1off = 1; - else - pSiS->CRT1off = 0; - } - if (CR32 & 0x08) + if(CR32 & 0x08) pSiS->VBFlags |= CRT2_LCD; } - if (pSiS->VBFlags & CRT2_LCD) { - inSISIDXREG(pSiS->RelIO+CROFFSET, 0x36, CR36); - switch (CR36) { - case 1: - pSiS->VBFlags |= LCD_800x600; - pSiS->LCDheight = 600; - break; - case 2: - pSiS->VBFlags |= LCD_1024x768; - pSiS->LCDheight = 768; - break; - case 3: - pSiS->VBFlags |= LCD_1280x1024; - pSiS->LCDheight = 1024; - break; - case 4: - pSiS->VBFlags |= LCD_1280x960; /* TW */ - pSiS->LCDheight = 960; - break; - case 5: - pSiS->VBFlags |= LCD_640x480; /* TW */ - pSiS->LCDheight = 480; - break; - default: - pSiS->VBFlags |= LCD_1024x768; /* TW */ - pSiS->LCDheight = 768; - break; - } + if(pSiS->VBFlags & CRT2_LCD) { + inSISIDXREG(SISCR, 0x36, CR36); + inSISIDXREG(SISCR, 0x37, CR37); + if((pSiS->VGAEngine == SIS_315_VGA) && (!CR36)) { + /* TW: Old 650/301LV BIOS version "forgot" to set CR36, CR37 */ + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "BIOS-provided LCD information invalid, probing myself...\n"); + if(pSiS->VBFlags & VB_LVDS) pSiS->SiS_Pr->SiS_IF_DEF_LVDS = 1; + else pSiS->SiS_Pr->SiS_IF_DEF_LVDS = 0; + SiS_GetPanelID(pSiS->SiS_Pr, &pSiS->sishw_ext); + inSISIDXREG(SISCR, 0x36, CR36); + inSISIDXREG(SISCR, 0x37, CR37); + } + if(pSiS->VGAEngine == SIS_300_VGA) { + pSiS->VBLCDFlags |= SiS300_LCD_Type[(CR36 & 0x0f)].VBLCD_lcdflag; + pSiS->LCDheight = SiS300_LCD_Type[(CR36 & 0x0f)].LCDheight; + pSiS->LCDwidth = SiS300_LCD_Type[(CR36 & 0x0f)].LCDwidth; + pSiS->sishw_ext.ulCRT2LCDType = SiS300_LCD_Type[(CR36 & 0x0f)].LCDtype; + textindex = SiS300_LCD_Type[(CR36 & 0x0f)].LCDrestextindex; + } else { + pSiS->VBLCDFlags |= SiS310_LCD_Type[(CR36 & 0x0f)].VBLCD_lcdflag; + pSiS->LCDheight = SiS310_LCD_Type[(CR36 & 0x0f)].LCDheight; + pSiS->LCDwidth = SiS310_LCD_Type[(CR36 & 0x0f)].LCDwidth; + pSiS->sishw_ext.ulCRT2LCDType = SiS310_LCD_Type[(CR36 & 0x0f)].LCDtype; + textindex = SiS310_LCD_Type[(CR36 & 0x0f)].LCDrestextindex; + } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected LCD panel resolution %s (type %d, %s%s)\n", + panelres[textindex], + (pSiS->VGAEngine == SIS_315_VGA) ? ((CR36 & 0x0f) - 1) : ((CR36 & 0xf0) >> 4), + (pSiS->VBFlags & VB_LVDS) ? + (CR37 & 0x10 ? "non-expanding, " : "expanding, ") : + ( ((pSiS->VBFlags & VB_301B) && (pSiS->VGAEngine == SIS_300_VGA)) ? + (CR37 & 0x10 ? "non-expanding, " : "expanding, ") : + (CR37 & 0x10 ? "self-scaling, " : "non-self-scaling, ") ), + CR37 & 0x01 ? "RGB18" : "RGB24"); } } -/* TW: Detect CRT2-TV connector type and PAL/NTSC flag */ +/* Detect CRT2-TV connector type and PAL/NTSC flag */ void SISTVPreInit(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - int CR32, CR38, SR16, SR17; + unsigned char SR16, SR17, SR38, CR32, CR38=0, CR79; + int temp = 0; - if (!(pSiS->VBFlags & VB_VIDEOBRIDGE)) + if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return; - inSISIDXREG(pSiS->RelIO+CROFFSET, 0x32, CR32); - inSISIDXREG(pSiS->RelIO+SROFFSET, 0x17, SR17); + inSISIDXREG(SISCR, 0x32, CR32); + inSISIDXREG(SISSR, 0x17, SR17); + inSISIDXREG(SISSR, 0x16, SR16); + inSISIDXREG(SISSR, 0x38, SR38); + switch(pSiS->VGAEngine) { + case SIS_300_VGA: + if(pSiS->Chipset != PCI_CHIP_SIS300) temp = 0x35; + break; + case SIS_315_VGA: + temp = 0x38; + break; + } + if(temp) { + inSISIDXREG(SISCR, temp, CR38); + } - if ( (SR17 & 0x0F) && (pSiS->Chipset != PCI_CHIP_SIS300) ) { - if (SR17 & 0x04) /* { */ /* TW: Determine TV type even if not using TV output */ - pSiS->VBFlags |= CRT2_TV; +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(vb.c: SR17=%02x CR32=%02x)\n", SR17, CR32); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(vb.c: SR16=%02x SR38=%02x)\n", SR16, SR38); +#endif + + if( (pSiS->VGAEngine == SIS_300_VGA) && + (pSiS->Chipset != PCI_CHIP_SIS300) && + (SR17 & 0x0F) ) { - if (SR17 & 0x20) + if(SR17 & 0x04) + pSiS->VBFlags |= CRT2_TV; + + if(SR17 & 0x20) pSiS->VBFlags |= TV_SVIDEO; - else if (SR17 & 0x10) + else if (SR17 & 0x10) pSiS->VBFlags |= TV_AVIDEO; - inSISIDXREG(pSiS->RelIO+SROFFSET, 0x16, SR16); - if (SR16 & 0x20) - pSiS->VBFlags |= TV_PAL; - else + + if(pSiS->VBFlags & (TV_SVIDEO | TV_AVIDEO)) { + if(SR16 & 0x20) + pSiS->VBFlags |= TV_PAL; + else pSiS->VBFlags |= TV_NTSC; - /* } */ + } + } else { - if (CR32 & 0x47) /* { */ - pSiS->VBFlags |= CRT2_TV; - if (CR32 & 0x04) - pSiS->VBFlags |= TV_SCART; - else if (CR32 & 0x02) + + if(CR32 & 0x47) + pSiS->VBFlags |= CRT2_TV; + + if(CR32 & 0x04) + pSiS->VBFlags |= TV_SCART; + else if(CR32 & 0x02) pSiS->VBFlags |= TV_SVIDEO; - else if (CR32 & 0x01) + else if(CR32 & 0x01) pSiS->VBFlags |= TV_AVIDEO; - else if (CR32 & 0x40) + else if(CR32 & 0x40) pSiS->VBFlags |= (TV_SVIDEO | TV_HIVISION); - inSISIDXREG(pSiS->RelIO+SROFFSET, 0x38, CR38); - if (CR38 & 0x01) - pSiS->VBFlags |= TV_PAL; - else - pSiS->VBFlags |= TV_NTSC; - /* } */ + else if((CR38 & 0x04) && (pSiS->VBFlags & VB_CHRONTEL)) + pSiS->VBFlags |= (TV_CHSCART | TV_PAL); + else if((CR38 & 0x08) && (pSiS->VBFlags & VB_CHRONTEL)) + pSiS->VBFlags |= (TV_CHHDTV | TV_NTSC); + + if(pSiS->VBFlags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION)) { + if( (pSiS->Chipset == PCI_CHIP_SIS550) || /* TW: ? */ + (pSiS->Chipset == PCI_CHIP_SIS650) ) { + inSISIDXREG(SISCR, 0x79, CR79); + if(CR79 & 0x20) { + pSiS->VBFlags |= TV_PAL; + if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM; + else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN; + } else + pSiS->VBFlags |= TV_NTSC; + } else if(pSiS->VGAEngine == SIS_300_VGA) { + /* TW: Should be SR38 here as well, but this + * does not work. Looks like a BIOS bug (2.04.5c). + */ + if(SR16 & 0x20) + pSiS->VBFlags |= TV_PAL; + else + pSiS->VBFlags |= TV_NTSC; + } else { /* 315, 330 */ + if(SR38 & 0x01) { + pSiS->VBFlags |= TV_PAL; + if(CR38 & 0x40) pSiS->VBFlags |= TV_PALM; + else if(CR38 & 0x80) pSiS->VBFlags |= TV_PALN; + } else + pSiS->VBFlags |= TV_NTSC; + } + } + } + if(pSiS->VBFlags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION | TV_CHSCART | TV_CHHDTV)) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "%sTV standard %s\n", + (pSiS->VBFlags & (TV_CHSCART | TV_CHHDTV)) ? "Using " : "Detected default ", + (pSiS->VBFlags & TV_NTSC) ? + ((pSiS->VBFlags & TV_CHHDTV) ? "480i HDTV" : "NTSC") : + ((pSiS->VBFlags & TV_PALM) ? "PALM" : + ((pSiS->VBFlags & TV_PALN) ? "PALN" : "PAL"))); } - -/* TW: This is old code: */ - - /* TW: Reading PAL/NTSC flag from 0x31 is not a good idea. We'd - * better read this from POWER_ON_TRAP (0x38) some day. */ -#if 0 - inSISIDXREG(pSiS->RelIO+CROFFSET, 0x31, temp); - if (temp & 0x01) - pSiS->VBFlags |= TV_PAL; - else - pSiS->VBFlags |= TV_NTSC; -#endif } -/* TW: Detect CRT2-VGA */ +/* Detect CRT2-VGA */ void SISCRT2PreInit(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - int SR17, CR32; + unsigned char SR17, CR32; if (!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return; - inSISIDXREG(pSiS->RelIO+CROFFSET, 0x32, CR32); - inSISIDXREG(pSiS->RelIO+SROFFSET, 0x17, SR17); + /* CRT2-VGA not supported on LVDS and 30xLV(X) */ + if (pSiS->VBFlags & (VB_LVDS|VB_30xLV|VB_30xLVX)) + return; - if ( (SR17 & 0x0F) && (pSiS->Chipset != PCI_CHIP_SIS300) ) { - if (SR17 & 0x08) + inSISIDXREG(SISCR, 0x32, CR32); + inSISIDXREG(SISSR, 0x17, SR17); + + if( (pSiS->VGAEngine == SIS_300_VGA) && + (pSiS->Chipset != PCI_CHIP_SIS300) && + (SR17 & 0x0F) ) { + + if(SR17 & 0x08) pSiS->VBFlags |= CRT2_VGA; + } else { - if (CR32 & 0x10) + + if(CR32 & 0x10) pSiS->VBFlags |= CRT2_VGA; + } } + + + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h index b78af5477..4419ccf39 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h @@ -1,33 +1,43 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h,v 1.5 2002/01/17 09:57:30 eich Exp $ */ - -/* CR30 VBInfo = CR31:CR30 */ -#define SET_SIMU_SCAN_MODE 0x0001 -#define SWITCH_TO_CRT2 0x0002 -#define SET_CRT2_TO_AVIDEO 0x0004 /* Composite */ -#define SET_CRT2_TO_SVIDEO 0x0008 -#define SET_CRT2_TO_SCART 0x0010 -#define SET_CRT2_TO_LCD 0x0020 -#define SET_CRT2_TO_RAMDAC 0x0040 -#define SET_CRT2_TO_HIVISION_TV 0x0080 -#define SET_CRT2_TO_TV (SET_CRT2_TO_AVIDEO | SET_CRT2_TO_SVIDEO | \ - SET_CRT2_TO_SCART | SET_CRT2_TO_HIVISION_TV) -/* CR31 */ -#define SET_PAL_TV 0x0100 -#define SET_IN_SLAVE_MODE 0x0200 -#define SET_NO_SIMU_ON_LOCK 0x0400 -#define SET_NO_SIMU_TV_ON_LOCK SET_NO_SIMU_ON_LOCK -#define DISABLE_LOAD_CRT2DAC 0x1000 -#define DISABLE_CRT2_DISPLAY 0x2000 -#define DRIVER_MODE 0x4000 - -typedef struct _SiS301Reg { - CARD8 *VBPart1; - CARD8 *VBPart2; - CARD8 *VBPart3; - CARD8 *VBPart4; -} SiS301RegRec, SiS301RegPtr; +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vb.h,v 1.7 2003/01/29 15:42:17 eich Exp $ */ +/* + * Video bridge detection and configuration for 300 and 310/325 series + * + * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * + * 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 Thomas Winischhofer not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Thomas Winischhofer makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THOMAS WINISCHHOFER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THOMAS WINISCHHOFER 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: Thomas Winischhofer <thomas@winischhofer.net> + * (Completely rewritten) + */ +typedef struct _SiS_LCD_StStruct +{ + ULONG VBLCD_lcdflag; + USHORT LCDwidth; + USHORT LCDheight; + USHORT LCDtype; + UCHAR LCDrestextindex; +} SiS_LCD_StStruct; +void SISCRT1PreInit(ScrnInfoPtr pScrn); void SISLCDPreInit(ScrnInfoPtr pScrn); void SISTVPreInit(ScrnInfoPtr pScrn); void SISCRT2PreInit(ScrnInfoPtr pScrn); + +extern BOOLEAN SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h new file mode 100644 index 000000000..d377deeda --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h @@ -0,0 +1,368 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.3 2003/02/10 01:14:16 tsi Exp $ */ + +#ifndef _VGATYPES_ +#define _VGATYPES_ + +#ifdef LINUX_XF86 +#include "xf86Pci.h" +#endif + +#ifdef LINUX_KERNEL /* TW: We don't want the X driver to depend on kernel source */ +#include <linux/ioctl.h> +#endif + +#ifndef TC +#define far +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef CHAR +typedef char CHAR; +#endif + +#ifndef SHORT +typedef short SHORT; +#endif + +#ifndef LONG +typedef long LONG; +#endif + +#ifndef UCHAR +typedef unsigned char UCHAR; +#endif + +#ifndef USHORT +typedef unsigned short USHORT; +#endif + +#ifndef ULONG +typedef unsigned long ULONG; +#endif + +#ifndef PUCHAR +typedef UCHAR far *PUCHAR; +#endif + +#ifndef PUSHORT +typedef USHORT far *PUSHORT; +#endif + +#ifndef PULONG +typedef ULONG far *PULONG; +#endif + +#ifndef PVOID +typedef void far *PVOID; +#endif +#ifndef VOID +typedef void VOID; +#endif + +#ifndef BOOLEAN +typedef UCHAR BOOLEAN; +#endif + +#ifndef WINCE_HEADER +#ifndef bool +typedef UCHAR bool; +#endif +#endif /*WINCE_HEADER*/ + +#ifndef VBIOS_VER_MAX_LENGTH +#define VBIOS_VER_MAX_LENGTH 4 +#endif + +#ifndef LINUX_KERNEL /* For kernel, this is defined in sisfb.h */ +#ifndef WIN2000 +#ifndef SIS_CHIP_TYPE +typedef enum _SIS_CHIP_TYPE { + SIS_VGALegacy = 0, +#ifdef LINUX_XF86 + SIS_530, /* TW */ + SIS_OLD, /* TW */ +#endif + SIS_300, + SIS_630, + SIS_730, + SIS_540, + SIS_315H, /* SiS 310 */ + SIS_315, + SIS_315PRO, /* SiS 325 */ + SIS_550, + SIS_650, + SIS_740, + SIS_330, + MAX_SIS_CHIP +} SIS_CHIP_TYPE; +#endif +#endif +#endif + +#ifndef WIN2000 +#ifndef SIS_VB_CHIP_TYPE +typedef enum _SIS_VB_CHIP_TYPE { + VB_CHIP_Legacy = 0, + VB_CHIP_301, + VB_CHIP_301B, + VB_CHIP_301LV, + VB_CHIP_301LVX, + VB_CHIP_302, + VB_CHIP_302B, + VB_CHIP_302LV, + VB_CHIP_302LVX, + VB_CHIP_303, + VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */ + MAX_VB_CHIP +} SIS_VB_CHIP_TYPE; +#endif +#endif + +#ifndef WIN2000 +#ifndef SIS_LCD_TYPE +typedef enum _SIS_LCD_TYPE { + LCD_INVALID = 0, + LCD_800x600, + LCD_1024x768, + LCD_1280x1024, + LCD_1280x960, + LCD_640x480, + LCD_1600x1200, + LCD_1920x1440, + LCD_2048x1536, + LCD_320x480, /* TW: FSTN */ + LCD_1400x1050, + LCD_1152x864, + LCD_1152x768, + LCD_1280x768, + LCD_1024x600, + LCD_UNKNOWN +} SIS_LCD_TYPE; +#endif +#endif + +#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/ +#ifndef PSIS_DSReg +typedef struct _SIS_DSReg +{ + UCHAR jIdx; + UCHAR jVal; +} SIS_DSReg, *PSIS_DSReg; +#endif + +#ifndef SIS_HW_DEVICE_INFO + +typedef struct _SIS_HW_DEVICE_INFO SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO; + +typedef BOOLEAN (*PSIS_QUERYSPACE) (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *); + + +struct _SIS_HW_DEVICE_INFO +{ + PVOID pDevice; /* The pointer to the physical device data structure + in each OS or NULL for unused. */ + UCHAR *pjVirtualRomBase; /* base virtual address of VBIOS ROM Space */ + /* or base virtual address of ROM image file. */ + /* if NULL, then read from pjROMImage; */ + /* Note:ROM image file is the file of VBIOS ROM */ + + BOOLEAN UseROM; /* TW: Use the ROM image if provided */ + + UCHAR *pjCustomizedROMImage;/* base virtual address of ROM image file. */ + /* wincE:ROM image file is the file for OEM */ + /* customized table */ + /* Linux: not used */ + /* NT : not used */ + /* Note : pjCustomizedROMImage=NULL if no ROM image file */ + + UCHAR *pjVideoMemoryAddress;/* base virtual memory address */ + /* of Linear VGA memory */ + + ULONG ulVideoMemorySize; /* size, in bytes, of the memory on the board */ + ULONG ulIOAddress; /* base I/O address of VGA ports (0x3B0) */ + UCHAR jChipType; /* Used to Identify SiS Graphics Chip */ + /* defined in the data structure type */ + /* "SIS_CHIP_TYPE" */ + + UCHAR jChipRevision; /* Used to Identify SiS Graphics Chip Revision */ + UCHAR ujVBChipID; /* the ID of video bridge */ + /* defined in the data structure type */ + /* "SIS_VB_CHIP_TYPE" */ + + USHORT usExternalChip; /* NO VB or other video bridge(not */ + /* SiS video bridge) */ + /* if ujVBChipID = VB_CHIP_UNKNOWN, */ + /* then bit0=1 : LVDS,bit1=1 : trumpion, */ + /* bit2=1 : CH7005 & no video bridge if */ + /* usExternalChip = 0. */ + /* Note: CR37[3:1]: */ + /* 001:SiS 301 */ + /* 010:LVDS */ + /* 011:Trumpion LVDS Scaling Chip */ + /* 100:LVDS(LCD-out)+Chrontel 7005 */ + /* 101:Single Chrontel 7005 */ + /* TW: This has changed on 310/325 series! */ + + ULONG ulCRT2LCDType; /* defined in the data structure type */ + /* "SIS_LCD_TYPE" */ + + BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */ + + BOOLEAN bSkipDramSizing; /* True: Skip video memory sizing. */ + PSIS_DSReg pSR; /* restore SR registers in initial function. */ + /* end data :(idx, val) = (FF, FF). */ + /* Note : restore SR registers if */ + /* bSkipDramSizing = TRUE */ + + PSIS_DSReg pCR; /* restore CR registers in initial function. */ + /* end data :(idx, val) = (FF, FF) */ + /* Note : restore cR registers if */ + /* bSkipDramSizing = TRUE */ + + PSIS_QUERYSPACE pQueryVGAConfigSpace; /* Get/Set VGA Configuration */ + /* space */ + + PSIS_QUERYSPACE pQueryNorthBridgeSpace;/* Get/Set North Bridge */ + /* space */ + + UCHAR szVBIOSVer[VBIOS_VER_MAX_LENGTH]; + + UCHAR pdc; /* TW: PanelDelayCompensation */ + +#ifdef LINUX_XF86 + PCITAG PciTag; /* PCI Tag for Linux XF86 */ +#endif +}; +#endif +#endif + + +/* TW: Addtional IOCTL for communication sisfb <> X driver */ +/* If changing this, sisfb.h must also be changed (for sisfb) */ + +#ifdef LINUX_XF86 /* We don't want the X driver to depend on the kernel source */ + +/* TW: ioctl for identifying and giving some info (esp. memory heap start) */ +#define SISFB_GET_INFO 0x80046ef8 /* Wow, what a terrible hack... */ + +/* TW: Structure argument for SISFB_GET_INFO ioctl */ +typedef struct _SISFB_INFO sisfb_info, *psisfb_info; + +struct _SISFB_INFO { + unsigned long sisfb_id; /* for identifying sisfb */ +#ifndef SISFB_ID +#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */ +#endif + int chip_id; /* PCI ID of detected chip */ + int memory; /* video memory in KB which sisfb manages */ + int heapstart; /* heap start (= sisfb "mem" argument) in KB */ + unsigned char fbvidmode; /* current sisfb mode */ + + unsigned char sisfb_version; + unsigned char sisfb_revision; + unsigned char sisfb_patchlevel; + + unsigned char sisfb_caps; /* sisfb's capabilities */ + + int sisfb_tqlen; /* turbo queue length (in KB) */ + + unsigned int sisfb_pcibus; /* The card's PCI ID */ + unsigned int sisfb_pcislot; + unsigned int sisfb_pcifunc; + + unsigned char sisfb_lcdpdc; + + char reserved[236]; /* for future use */ +}; +#endif + +#ifndef WIN2000 +#ifndef WINCE_HEADER +#ifndef BUS_DATA_TYPE +typedef enum _BUS_DATA_TYPE { + ConfigurationSpaceUndefined = -1, + Cmos, + EisaConfiguration, + Pos, + CbusConfiguration, + PCIConfiguration, + VMEConfiguration, + NuBusConfiguration, + PCMCIAConfiguration, + MPIConfiguration, + MPSAConfiguration, + PNPISAConfiguration, + MaximumBusDataType +} BUS_DATA_TYPE, *PBUS_DATA_TYPE; +#endif +#endif /* WINCE_HEADER */ + +#ifndef PCI_TYPE0_ADDRESSES +#define PCI_TYPE0_ADDRESSES 6 +#endif + +#ifndef PCI_TYPE1_ADDRESSES +#define PCI_TYPE1_ADDRESSES 2 +#endif + +#ifndef WINCE_HEADER +#ifndef PCI_COMMON_CONFIG +typedef struct _PCI_COMMON_CONFIG { + USHORT VendorID; /* (ro) */ + USHORT DeviceID; /* (ro) */ + USHORT Command; /* Device control */ + USHORT Status; + UCHAR RevisionID; /* (ro) */ + UCHAR ProgIf; /* (ro) */ + UCHAR SubClass; /* (ro) */ + UCHAR BaseClass; /* (ro) */ + UCHAR CacheLineSize; /* (ro+) */ + UCHAR LatencyTimer; /* (ro+) */ + UCHAR HeaderType; /* (ro) */ + UCHAR BIST; /* Built in self test */ + + union { + struct _PCI_HEADER_TYPE_0 { + ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; + ULONG CIS; + USHORT SubVendorID; + USHORT SubSystemID; + ULONG ROMBaseAddress; + ULONG Reserved2[2]; + + UCHAR InterruptLine; /* */ + UCHAR InterruptPin; /* (ro) */ + UCHAR MinimumGrant; /* (ro) */ + UCHAR MaximumLatency; /* (ro) */ + } type0; + + + } u; + + UCHAR DeviceSpecific[192]; + +} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; +#endif +#endif /* WINCE_HEADER */ + +#ifndef FIELD_OFFSET +#define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field)) +#endif + +#ifndef PCI_COMMON_HDR_LENGTH +#define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific)) +#endif +#endif + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h new file mode 100644 index 000000000..700598676 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h @@ -0,0 +1,571 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.3 2003/02/10 01:14:17 tsi Exp $ */ + +#ifdef _INIT_ +#define EXTERN +#else +#define EXTERN extern +#endif /* _INIT_ */ + +#ifndef _VSTRUCT_ +#define _VSTRUCT_ + +typedef struct _SiS_PanelDelayTblStruct +{ + UCHAR timer[2]; +} SiS_PanelDelayTblStruct; + +typedef struct _SiS_LCDDataStruct +{ + USHORT RVBHCMAX; + USHORT RVBHCFACT; + USHORT VGAHT; + USHORT VGAVT; + USHORT LCDHT; + USHORT LCDVT; +} SiS_LCDDataStruct; + +typedef struct _SiS_TVDataStruct +{ + USHORT RVBHCMAX; + USHORT RVBHCFACT; + USHORT VGAHT; + USHORT VGAVT; + USHORT TVHDE; + USHORT TVVDE; + USHORT RVBHRS; + UCHAR FlickerMode; + USHORT HALFRVBHRS; + UCHAR RY1COE; + UCHAR RY2COE; + UCHAR RY3COE; + UCHAR RY4COE; +} SiS_TVDataStruct; + +typedef struct _SiS_LVDSDataStruct +{ + USHORT VGAHT; + USHORT VGAVT; + USHORT LCDHT; + USHORT LCDVT; +} SiS_LVDSDataStruct; + +typedef struct _SiS_LVDSDesStruct +{ + USHORT LCDHDES; + USHORT LCDVDES; +} SiS_LVDSDesStruct; + +typedef struct _SiS_LVDSCRT1DataStruct +{ + UCHAR CR[15]; +} SiS_LVDSCRT1DataStruct; + +/*add for LCDA*/ +typedef struct _SiS_LCDACRT1DataStruct +{ + UCHAR CR[17]; +} SiS_LCDACRT1DataStruct; + +typedef struct _SiS_CHTVRegDataStruct +{ + UCHAR Reg[16]; +} SiS_CHTVRegDataStruct; + +typedef struct _SiS_StStruct +{ + UCHAR St_ModeID; + USHORT St_ModeFlag; + UCHAR St_StTableIndex; + UCHAR St_CRT2CRTC; + UCHAR St_ResInfo; + UCHAR VB_StTVFlickerIndex; + UCHAR VB_StTVEdgeIndex; + UCHAR VB_StTVYFilterIndex; +} SiS_StStruct; + +typedef struct _SiS_VBModeStruct +{ + UCHAR ModeID; + UCHAR VB_TVDelayIndex; + UCHAR VB_TVFlickerIndex; + UCHAR VB_TVPhaseIndex; + UCHAR VB_TVYFilterIndex; + UCHAR VB_LCDDelayIndex; + UCHAR _VB_LCDHIndex; + UCHAR _VB_LCDVIndex; +} SiS_VBModeStruct; + +typedef struct _SiS_StandTableStruct +{ + UCHAR CRT_COLS; + UCHAR ROWS; + UCHAR CHAR_HEIGHT; + USHORT CRT_LEN; + UCHAR SR[4]; + UCHAR MISC; + UCHAR CRTC[0x19]; + UCHAR ATTR[0x14]; + UCHAR GRC[9]; +} SiS_StandTableStruct; + +typedef struct _SiS_ExtStruct +{ + UCHAR Ext_ModeID; + USHORT Ext_ModeFlag; + USHORT Ext_ModeInfo; + USHORT Ext_Point; + USHORT Ext_VESAID; + UCHAR Ext_VESAMEMSize; + UCHAR Ext_RESINFO; + UCHAR VB_ExtTVFlickerIndex; + UCHAR VB_ExtTVEdgeIndex; + UCHAR VB_ExtTVYFilterIndex; + UCHAR REFindex; +} SiS_ExtStruct; + +typedef struct _SiS_Ext2Struct +{ + USHORT Ext_InfoFlag; + UCHAR Ext_CRT1CRTC; + UCHAR Ext_CRTVCLK; + UCHAR Ext_CRT2CRTC; + UCHAR ModeID; + USHORT XRes; + USHORT YRes; + USHORT ROM_OFFSET; +} SiS_Ext2Struct; + +typedef struct _SiS_Part2PortTblStruct +{ + UCHAR CR[12]; +} SiS_Part2PortTblStruct; + +typedef struct _SiS_CRT1TableStruct +{ + UCHAR CR[17]; +} SiS_CRT1TableStruct; + +typedef struct _SiS_MCLKDataStruct +{ + UCHAR SR28,SR29,SR2A; + USHORT CLOCK; +} SiS_MCLKDataStruct; + +typedef struct _SiS_ECLKDataStruct +{ + UCHAR SR2E,SR2F,SR30; + USHORT CLOCK; +} SiS_ECLKDataStruct; + +typedef struct _SiS_VCLKDataStruct +{ + UCHAR SR2B,SR2C; + USHORT CLOCK; +} SiS_VCLKDataStruct; + +typedef struct _SiS_VBVCLKDataStruct +{ + UCHAR Part4_A,Part4_B; + USHORT CLOCK; +} SiS_VBVCLKDataStruct; + +typedef struct _SiS_StResInfoStruct +{ + USHORT HTotal; + USHORT VTotal; +} SiS_StResInfoStruct; + +typedef struct _SiS_ModeResInfoStruct +{ + USHORT HTotal; + USHORT VTotal; + UCHAR XChar; + UCHAR YChar; +} SiS_ModeResInfoStruct; + +typedef UCHAR DRAM4Type[4]; + +typedef struct _SiS_Private +{ +#ifdef LINUX_KERNEL + USHORT RelIO; +#endif + USHORT SiS_P3c4; + USHORT SiS_P3d4; + USHORT SiS_P3c0; + USHORT SiS_P3ce; + USHORT SiS_P3c2; + USHORT SiS_P3ca; + USHORT SiS_P3c6; + USHORT SiS_P3c7; + USHORT SiS_P3c8; + USHORT SiS_P3c9; + USHORT SiS_P3da; + USHORT SiS_Part1Port; + USHORT SiS_Part2Port; + USHORT SiS_Part3Port; + USHORT SiS_Part4Port; + USHORT SiS_Part5Port; + USHORT SiS_IF_DEF_LVDS; + USHORT SiS_IF_DEF_TRUMPION; + USHORT SiS_IF_DEF_DSTN; + USHORT SiS_IF_DEF_FSTN; + USHORT SiS_IF_DEF_CH70xx; + USHORT SiS_IF_DEF_HiVision; + UCHAR SiS_VGAINFO; + BOOLEAN SiS_UseROM; + int SiS_CHOverScan; + BOOLEAN SiS_CHSOverScan; + BOOLEAN SiS_ChSW; + int SiS_UseOEM; + USHORT SiS_Backup70xx; + USHORT SiS_CRT1Mode; + USHORT SiS_flag_clearbuffer; + int SiS_RAMType; + UCHAR SiS_ChannelAB; + UCHAR SiS_DataBusWidth; + USHORT SiS_ModeType; + USHORT SiS_VBInfo; + USHORT SiS_LCDResInfo; + USHORT SiS_LCDTypeInfo; + USHORT SiS_LCDInfo; + USHORT SiS_VBType; + USHORT SiS_VBExtInfo; + USHORT SiS_HiVision; + USHORT SiS_SelectCRT2Rate; + USHORT SiS_SetFlag; + USHORT SiS_RVBHCFACT; + USHORT SiS_RVBHCMAX; + USHORT SiS_RVBHRS; + USHORT SiS_VGAVT; + USHORT SiS_VGAHT; + USHORT SiS_VT; + USHORT SiS_HT; + USHORT SiS_VGAVDE; + USHORT SiS_VGAHDE; + USHORT SiS_VDE; + USHORT SiS_HDE; + USHORT SiS_NewFlickerMode; + USHORT SiS_RY1COE; + USHORT SiS_RY2COE; + USHORT SiS_RY3COE; + USHORT SiS_RY4COE; + USHORT SiS_LCDHDES; + USHORT SiS_LCDVDES; + USHORT SiS_DDC_Port; + USHORT SiS_DDC_Index; + USHORT SiS_DDC_Data; + USHORT SiS_DDC_Clk; + USHORT SiS_DDC_DataShift; + USHORT SiS_DDC_DeviceAddr; + USHORT SiS_DDC_ReadAddr; + USHORT SiS_DDC_SecAddr; + USHORT SiS_Panel800x600; + USHORT SiS_Panel1024x768; + USHORT SiS_Panel1280x1024; + USHORT SiS_Panel1600x1200; + USHORT SiS_Panel1280x960; + USHORT SiS_Panel1400x1050; + USHORT SiS_Panel320x480; + USHORT SiS_Panel1152x768; + USHORT SiS_Panel1280x768; + USHORT SiS_Panel1024x600; + USHORT SiS_Panel640x480; + USHORT SiS_Panel1152x864; + USHORT SiS_PanelMax; + USHORT SiS_PanelMinLVDS; + USHORT SiS_PanelMin301; + USHORT SiS_ChrontelInit; + + /* Pointers: */ + const SiS_StStruct *SiS_SModeIDTable; + const SiS_StandTableStruct *SiS_StandTable; + const SiS_ExtStruct *SiS_EModeIDTable; + const SiS_Ext2Struct *SiS_RefIndex; + const SiS_VBModeStruct *SiS_VBModeIDTable; + const SiS_CRT1TableStruct *SiS_CRT1Table; + const SiS_MCLKDataStruct *SiS_MCLKData_0; + const SiS_MCLKDataStruct *SiS_MCLKData_1; + const SiS_ECLKDataStruct *SiS_ECLKData; + const SiS_VCLKDataStruct *SiS_VCLKData; + const SiS_VBVCLKDataStruct *SiS_VBVCLKData; + const SiS_StResInfoStruct *SiS_StResInfo; + const SiS_ModeResInfoStruct *SiS_ModeResInfo; + const UCHAR *SiS_ScreenOffset; + + const UCHAR *pSiS_OutputSelect; + const UCHAR *pSiS_SoftSetting; + + const DRAM4Type *SiS_SR15; /* pointer : point to array */ +#ifndef LINUX_XF86 + UCHAR *pSiS_SR07; + const DRAM4Type *SiS_CR40; /* pointer : point to array */ + UCHAR *SiS_CR49; + UCHAR *SiS_SR25; + UCHAR *pSiS_SR1F; + UCHAR *pSiS_SR21; + UCHAR *pSiS_SR22; + UCHAR *pSiS_SR23; + UCHAR *pSiS_SR24; + UCHAR *pSiS_SR31; + UCHAR *pSiS_SR32; + UCHAR *pSiS_SR33; + UCHAR *pSiS_CRT2Data_1_2; + UCHAR *pSiS_CRT2Data_4_D; + UCHAR *pSiS_CRT2Data_4_E; + UCHAR *pSiS_CRT2Data_4_10; + const USHORT *pSiS_RGBSenseData; + const USHORT *pSiS_VideoSenseData; + const USHORT *pSiS_YCSenseData; + const USHORT *pSiS_RGBSenseData2; /*301b*/ + const USHORT *pSiS_VideoSenseData2; + const USHORT *pSiS_YCSenseData2; +#endif + const UCHAR *SiS_NTSCPhase; + const UCHAR *SiS_PALPhase; + const UCHAR *SiS_NTSCPhase2; + const UCHAR *SiS_PALPhase2; + const UCHAR *SiS_PALMPhase; + const UCHAR *SiS_PALNPhase; + const UCHAR *SiS_PALMPhase2; + const UCHAR *SiS_PALNPhase2; + const UCHAR *SiS_SpecialPhase; + const SiS_LCDDataStruct *SiS_StLCD1024x768Data; + const SiS_LCDDataStruct *SiS_ExtLCD1024x768Data; + const SiS_LCDDataStruct *SiS_St2LCD1024x768Data; + const SiS_LCDDataStruct *SiS_StLCD1280x1024Data; + const SiS_LCDDataStruct *SiS_ExtLCD1280x1024Data; + const SiS_LCDDataStruct *SiS_St2LCD1280x1024Data; + const SiS_LCDDataStruct *SiS_NoScaleData1024x768; + const SiS_LCDDataStruct *SiS_NoScaleData1280x1024; + const SiS_LCDDataStruct *SiS_LCD1280x960Data; + const SiS_LCDDataStruct *SiS_NoScaleData1400x1050; + const SiS_LCDDataStruct *SiS_NoScaleData1600x1200; + const SiS_LCDDataStruct *SiS_StLCD1400x1050Data; + const SiS_LCDDataStruct *SiS_StLCD1600x1200Data; + const SiS_LCDDataStruct *SiS_ExtLCD1400x1050Data; + const SiS_LCDDataStruct *SiS_ExtLCD1600x1200Data; + const SiS_TVDataStruct *SiS_StPALData; + const SiS_TVDataStruct *SiS_ExtPALData; + const SiS_TVDataStruct *SiS_StNTSCData; + const SiS_TVDataStruct *SiS_ExtNTSCData; +#ifdef oldHV + const SiS_TVDataStruct *SiS_St1HiTVData; + const SiS_TVDataStruct *SiS_St2HiTVData; + const SiS_TVDataStruct *SiS_ExtHiTVData; +#endif + const UCHAR *SiS_NTSCTiming; + const UCHAR *SiS_PALTiming; +#ifdef oldHV + const UCHAR *SiS_HiTVExtTiming; + const UCHAR *SiS_HiTVSt1Timing; + const UCHAR *SiS_HiTVSt2Timing; + const UCHAR *SiS_HiTVTextTiming; + const UCHAR *SiS_HiTVGroup3Data; + const UCHAR *SiS_HiTVGroup3Simu; + const UCHAR *SiS_HiTVGroup3Text; +#endif + const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl; + const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS; + const SiS_LVDSDataStruct *SiS_LVDS800x600Data_1; + const SiS_LVDSDataStruct *SiS_LVDS800x600Data_2; + const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_1; + const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_2; + const SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_1; + const SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_2; + const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_1; + const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_2; + const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_1; + const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_2; + const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_1; + const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_2; + const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_1; + const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_2; + const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_1; + const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_2; + const SiS_LVDSDataStruct *SiS_LVDS640x480Data_1; + const SiS_LVDSDataStruct *SiS_LVDS320x480Data_1; + const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_1; + const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_2; + const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_1; + const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_2; + const SiS_LVDSDataStruct *SiS_LVDSXXXxXXXData_1; + const SiS_LVDSDataStruct *SiS_CHTVUNTSCData; + const SiS_LVDSDataStruct *SiS_CHTVONTSCData; + const SiS_LVDSDataStruct *SiS_CHTVUPALData; + const SiS_LVDSDataStruct *SiS_CHTVOPALData; + const SiS_LVDSDataStruct *SiS_CHTVUPALMData; + const SiS_LVDSDataStruct *SiS_CHTVOPALMData; + const SiS_LVDSDataStruct *SiS_CHTVUPALNData; + const SiS_LVDSDataStruct *SiS_CHTVOPALNData; + const SiS_LVDSDataStruct *SiS_CHTVSOPALData; + const SiS_LVDSDesStruct *SiS_PanelType00_1; + const SiS_LVDSDesStruct *SiS_PanelType01_1; + const SiS_LVDSDesStruct *SiS_PanelType02_1; + const SiS_LVDSDesStruct *SiS_PanelType03_1; + const SiS_LVDSDesStruct *SiS_PanelType04_1; + const SiS_LVDSDesStruct *SiS_PanelType05_1; + const SiS_LVDSDesStruct *SiS_PanelType06_1; + const SiS_LVDSDesStruct *SiS_PanelType07_1; + const SiS_LVDSDesStruct *SiS_PanelType08_1; + const SiS_LVDSDesStruct *SiS_PanelType09_1; + const SiS_LVDSDesStruct *SiS_PanelType0a_1; + const SiS_LVDSDesStruct *SiS_PanelType0b_1; + const SiS_LVDSDesStruct *SiS_PanelType0c_1; + const SiS_LVDSDesStruct *SiS_PanelType0d_1; + const SiS_LVDSDesStruct *SiS_PanelType0e_1; + const SiS_LVDSDesStruct *SiS_PanelType0f_1; + const SiS_LVDSDesStruct *SiS_PanelType00_2; + const SiS_LVDSDesStruct *SiS_PanelType01_2; + const SiS_LVDSDesStruct *SiS_PanelType02_2; + const SiS_LVDSDesStruct *SiS_PanelType03_2; + const SiS_LVDSDesStruct *SiS_PanelType04_2; + const SiS_LVDSDesStruct *SiS_PanelType05_2; + const SiS_LVDSDesStruct *SiS_PanelType06_2; + const SiS_LVDSDesStruct *SiS_PanelType07_2; + const SiS_LVDSDesStruct *SiS_PanelType08_2; + const SiS_LVDSDesStruct *SiS_PanelType09_2; + const SiS_LVDSDesStruct *SiS_PanelType0a_2; + const SiS_LVDSDesStruct *SiS_PanelType0b_2; + const SiS_LVDSDesStruct *SiS_PanelType0c_2; + const SiS_LVDSDesStruct *SiS_PanelType0d_2; + const SiS_LVDSDesStruct *SiS_PanelType0e_2; + const SiS_LVDSDesStruct *SiS_PanelType0f_2; + + const SiS_LVDSDesStruct *LVDS1024x768Des_1; + const SiS_LVDSDesStruct *LVDS1280x1024Des_1; + const SiS_LVDSDesStruct *LVDS1400x1050Des_1; + const SiS_LVDSDesStruct *LVDS1600x1200Des_1; + const SiS_LVDSDesStruct *LVDS1024x768Des_2; + const SiS_LVDSDesStruct *LVDS1280x1024Des_2; + const SiS_LVDSDesStruct *LVDS1400x1050Des_2; + const SiS_LVDSDesStruct *LVDS1600x1200Des_2; + + const SiS_LVDSDesStruct *SiS_CHTVUNTSCDesData; + const SiS_LVDSDesStruct *SiS_CHTVONTSCDesData; + const SiS_LVDSDesStruct *SiS_CHTVUPALDesData; + const SiS_LVDSDesStruct *SiS_CHTVOPALDesData; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_1_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2_H; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1; + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1_H; + const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC; + const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC; + const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL; + const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1OPAL; + const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1SOPAL; + + const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1320x480_1; + + const SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_1; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_1; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_1; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_1_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_1_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_1_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_2; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_2; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_2; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT1800x600_2_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_2_H; + const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_2_H; + + /* TW: New for 650/301LV */ + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_1; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_2; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_2; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_3; + const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_3; + + const SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC; + const SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC; + const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL; + const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPAL; + const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALM; + const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALM; + const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALN; + const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALN; + const SiS_CHTVRegDataStruct *SiS_CHTVReg_SOPAL; + const UCHAR *SiS_CHTVVCLKUNTSC; + const UCHAR *SiS_CHTVVCLKONTSC; + const UCHAR *SiS_CHTVVCLKUPAL; + const UCHAR *SiS_CHTVVCLKOPAL; + const UCHAR *SiS_CHTVVCLKUPALM; + const UCHAR *SiS_CHTVVCLKOPALM; + const UCHAR *SiS_CHTVVCLKUPALN; + const UCHAR *SiS_CHTVVCLKOPALN; + const UCHAR *SiS_CHTVVCLKSOPAL; + + BOOLEAN UseCustomMode; + BOOLEAN CRT1UsesCustomMode; + USHORT CHDisplay; + USHORT CHSyncStart; + USHORT CHSyncEnd; + USHORT CHTotal; + USHORT CHBlankStart; + USHORT CHBlankEnd; + USHORT CVDisplay; + USHORT CVSyncStart; + USHORT CVSyncEnd; + USHORT CVTotal; + USHORT CVBlankStart; + USHORT CVBlankEnd; + ULONG CDClock; + ULONG CFlags; + UCHAR CCRT1CRTC[17]; + UCHAR CSR2B; + UCHAR CSR2C; + USHORT CSRClock; + USHORT CModeFlag; + USHORT CInfoFlag; + BOOLEAN SiS_CHPALM; + BOOLEAN SiS_CHPALN; +} SiS_Private; + +#endif + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c index 74284bbc3..bf9a33370 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c @@ -20,7 +20,7 @@ * 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. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c,v 1.6 2001/05/16 06:48:11 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c,v 1.7 2002/12/06 16:44:38 tsi Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -658,10 +658,26 @@ CG6ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) /* Mandatory */ static Bool CG6SaveScreen(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 */ { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); + unsigned int tmp = pCg6->thc->thc_misc; + + switch(mode) + { + case SCREEN_SAVER_ON: + case SCREEN_SAVER_CYCLE: + tmp &= ~CG6_THC_MISC_SYNC_ENAB; + break; + case SCREEN_SAVER_OFF: + case SCREEN_SAVER_FORCER: + tmp |= CG6_THC_MISC_SYNC_ENAB; + break; + default: + return FALSE; + } + + pCg6->thc->thc_misc = tmp; return TRUE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb.h b/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb.h index 13838959b..af54db25c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb.h @@ -24,7 +24,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb.h,v 1.7 2001/05/04 19:05:46 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb.h,v 1.8 2002/12/06 02:44:03 tsi Exp $ */ #ifndef FFB_H #define FFB_H @@ -43,6 +43,11 @@ #include "xf86drm.h" #include "ffb_drishare.h" #endif +#ifndef DPMS_SERVER +#define DPMS_SERVER +#endif /* DPMS_SERVER */ +#include "extensions/dpms.h" + /* Various offsets in virtual (ie. mmap()) spaces Linux and Solaris support. */ /* Note: do not mmap FFB_DFB8R_VOFF and following mappings using one mmap together @@ -233,6 +238,8 @@ extern Bool FFBDacInit(FFBPtr); extern void FFBDacFini(FFBPtr); extern void FFBDacEnterVT(FFBPtr); extern void FFBDacLeaveVT(FFBPtr); +extern Bool FFBDacSaveScreen(FFBPtr, int); +extern void FFBDacDPMSMode(FFBPtr, int, int); /* Exported WID layer routines. */ extern void FFBWidPoolInit(FFBPtr); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_driver.c index 901389e75..8921955a2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_driver.c @@ -20,7 +20,7 @@ * 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. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_driver.c,v 1.10 2002/09/16 18:06:01 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_driver.c,v 1.11 2002/12/06 02:44:04 tsi Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -60,7 +60,7 @@ static void FFBAdjustFrame(int scrnIndex, int x, int y, int flags); static void FFBFreeScreen(int scrnIndex, int flags); static int FFBValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); - +static void FFBDPMSMode(ScrnInfoPtr pScrn, int DPMSMode, int flags); /* ffb_dga.c */ extern void FFB_InitDGA(ScreenPtr pScreen); @@ -942,6 +942,8 @@ FFBScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScreen->CloseScreen = FFBCloseScreen; pScreen->SaveScreen = FFBSaveScreen; + (void) xf86DPMSInit(pScreen, FFBDPMSMode, 0); + /* Report any unused options (only for the first generation) */ if (serverGeneration == 1) { xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -1090,11 +1092,14 @@ FFBValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) /* Mandatory */ static Bool FFBSaveScreen(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 */ + /* This function blanks the screen when mode=SCREEN_SAVER_ON and + unblanks it when mode=SCREEN_SAVER_OFF. It is used internally in the + FFBScreenInit code `for aesthetic reasons,' and it is used for + blanking if you set "xset s on s blank." The work (such as it is) is + done in "ffb_dac.c" `for aesthetic reasons.' + */ { - return TRUE; + return FFBDacSaveScreen(GET_FFB_FROM_SCREEN(pScreen), mode); } /* @@ -1105,3 +1110,13 @@ FFBSync(ScrnInfoPtr pScrn) { return; } + +/* + Hook for DPMS Mode. +*/ + +static void +FFBDPMSMode(ScrnInfoPtr pScrn, int DPMSMode, int flags) +{ + FFBDacDPMSMode(GET_FFB_FROM_SCRN(pScrn), DPMSMode, flags); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile index 983303642..be482e80a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile,v 1.21 2001/05/21 21:43:55 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile,v 1.22 2003/02/17 17:06:44 dawes Exp $ XCOMM XCOMM This is the Imakefile for the TDFX driver. XCOMM @@ -36,7 +36,7 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ -I$(XF86SRC)/xaa -I$(XF86SRC)/rac -I$(XF86SRC)/int10 \ -I$(SERVERSRC)/fb -I$(XF86SRC)/xaa -I$(XF86SRC)/ramdac \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ - -I$(XF86SRC)/ddc -I$(XF86OSSRC)/vbe -I$(SERVERSRC)/Xext \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/vbe -I$(SERVERSRC)/Xext \ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ -I$(EXTINCSRC) -I$(SERVERSRC)/render \ $(DRIINCLUDES) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c index bca90b412..0df0b4396 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c,v 1.24 2002/10/17 01:02:08 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c,v 1.25 2003/02/08 21:26:59 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c index 9742a79fa..0c0ce8060 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c @@ -27,7 +27,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c,v 1.91 2002/08/15 02:16:30 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c,v 1.92 2002/11/25 14:05:00 eich Exp $ */ /* * Authors: @@ -758,15 +758,16 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) #endif #endif -#if 0 +#if 1 /* * I'm sure we don't need to set these. All resources * for these operations are exclusive. */ - if (pTDFX->usePIO) - pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; - else - pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + if (pTDFX->usePIO) { + pScrn->racMemFlags = RAC_FB; + pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + } else + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; #endif /* Set pScrn->monitor */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c b/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c index 3a746fd36..f54becce5 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c @@ -28,7 +28,7 @@ * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br> * David Dawes <dawes@xfree86.org> * - * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c,v 1.34 2002/10/16 17:51:34 dawes Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c,v 1.36 2003/01/23 17:20:46 tsi Exp $ */ #include "vesa.h" @@ -173,17 +173,21 @@ static const char *shadowSymbols[] = { static const char *vbeSymbols[] = { "VBEBankSwitch", - "VBEFreeModeInfo", + "VBEExtendedInit", + "VBEFindSupportedDepths", "VBEGetModeInfo", "VBEGetVBEInfo", "VBEGetVBEMode", - "VBEInit", + "VBEPrintModes", "VBESaveRestore", "VBESetDisplayStart", "VBESetGetDACPaletteFormat", "VBESetGetLogicalScanlineLength", "VBESetGetPaletteData", + "VBESetModeNames", + "VBESetModeParameters", "VBESetVBEMode", + "VBEValidateModes", "vbeDoEDID", "vbeFree", NULL @@ -480,7 +484,8 @@ VESAPreInit(ScrnInfoPtr pScrn, int flags) pScrn->progClock = TRUE; pScrn->rgbBits = 8; - vbe = VBEGetVBEInfo(pVesa->pVbe); + if ((vbe = VBEGetVBEInfo(pVesa->pVbe)) == NULL) + return (FALSE); pVesa->major = (unsigned)(vbe->VESAVersion >> 8); pVesa->minor = vbe->VESAVersion & 0xff; pVesa->vbeInfo = vbe; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.h b/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.h index bea904796..cc448eb37 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.h @@ -26,7 +26,7 @@ * * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br> * - * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.h,v 1.13 2002/09/19 02:57:03 dawes Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.h,v 1.14 2003/01/16 16:09:10 eich Exp $ */ #ifndef _VESA_H_ @@ -98,7 +98,7 @@ typedef struct _VESARec miBankInfoRec bank; int curBank, bankSwitchWindowB; CARD16 maxBytesPerScanline; - int mapPhys, mapOff, mapSize; /* video memory */ + unsigned long mapPhys, mapOff, mapSize; /* video memory */ void *base, *VGAbase; CARD8 *state, *pstate; /* SVGA state */ int statePage, stateSize, stateMode; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.c b/xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.c new file mode 100644 index 000000000..68c8632aa --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.c @@ -0,0 +1,132 @@ +/* ********************************************************** + * Copyright (C) 1998-2002 VMware, Inc. + * All Rights Reserved + * **********************************************************/ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.c,v 1.2 2002/12/11 17:07:58 dawes Exp $ */ + +#include "vmware.h" + +struct _Heap { + CARD8* ptr; + CARD32 size; + CARD32 maxSlots; + CARD32 startOffset; + SVGASurface* frontBuffer; + SVGASurface* slotsStart; + Bool clear; +}; + +static SVGASurface* FillInSurface(Heap* heap, SVGASurface* surface, + CARD32 width, CARD32 height, + CARD32 bpp, CARD32 pitch, CARD32 size, + CARD32 sizeUsed); + +Heap* +vmwareHeap_Create(CARD8* ptr, CARD32 size, CARD32 maxSlots, CARD32 startOffset, + CARD32 sWidth, CARD32 sHeight, CARD32 sBPP, CARD32 sPitch, + CARD32 sFbOffset) +{ + Heap* newHeap = malloc(sizeof (Heap)); + + newHeap->ptr = ptr; + newHeap->size = size - sizeof(SVGASurface); /* leave room for frontbuffer */ + newHeap->maxSlots = maxSlots; + newHeap->startOffset = startOffset; + + newHeap->frontBuffer = FillInSurface(newHeap, + (SVGASurface*)(ptr + newHeap->size), + sWidth, sHeight, sBPP, sPitch, + sHeight * sPitch, 0); + newHeap->frontBuffer->dataOffset = sFbOffset; + newHeap->frontBuffer->numQueued = newHeap->frontBuffer->numDequeued = 0; + + newHeap->slotsStart = (SVGASurface*)(newHeap->ptr + newHeap->size) - + newHeap->maxSlots; + newHeap->clear = FALSE; + vmwareHeap_Clear(newHeap); + + return newHeap; +} + +void +vmwareHeap_Destroy(Heap* heap) +{ + free(heap); +} + +void +vmwareHeap_Clear(Heap* heap) +{ + if (!heap->clear) { + memset(heap->slotsStart, 0, heap->maxSlots * sizeof (SVGASurface)); + heap->clear = TRUE; + } +} + +static SVGASurface* +FillInSurface(Heap* heap, SVGASurface* surface, CARD32 width, CARD32 height, + CARD32 bpp, CARD32 pitch, CARD32 size, CARD32 offset) +{ + surface->size = sizeof (SVGASurface); + surface->version = SVGA_SURFACE_VERSION_1; + surface->bpp = bpp; + surface->width = width; + surface->height = height; + surface->pitch = pitch; + if (surface->userData == 0) { + /* + * We allocate exactly what we need the first time we use a slot, so + * all reuses of this slot will be equal or smaller. + */ + surface->userData = size; + } + surface->dataOffset = offset + heap->startOffset; + + return surface; +} + +SVGASurface* +vmwareHeap_GetFrontBuffer(Heap* heap) +{ + return heap->frontBuffer; +} + +SVGASurface* +vmwareHeap_AllocSurface(Heap* heap, CARD32 width, CARD32 height, + CARD32 pitch, CARD32 bpp) +{ + CARD32 size = pitch * height; + CARD32 sizeUsed = 0; + SVGASurface* surface = heap->slotsStart; + int i; + + /* + * NOTE: we use SVGASurface::userData to store the largest this slot's + * size has ever been, since we don't ever compact anything. + */ + + /* find a free slot that's big enough */ + for (i = 0; i < heap->maxSlots; i++) { + if (surface[i].userData == 0) { /* this surface has never been used */ + if ((CARD8*)heap->slotsStart - heap->ptr - sizeUsed < size) { + /* no room left for data*/ + return NULL; + } + + heap->clear = FALSE; + return FillInSurface(heap, surface + i, width, height, bpp, + pitch, size, sizeUsed); + } + + if (surface[i].numQueued == surface[i].numDequeued && + surface[i].userData >= size) { /* free and big enough, sweet! */ + heap->clear = FALSE; + return FillInSurface(heap, surface + i, width, height, bpp, + pitch, size, sizeUsed); + } + + sizeUsed += surface[i].userData; + } + + return NULL; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.h b/xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.h new file mode 100644 index 000000000..e948da9d2 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.h @@ -0,0 +1,25 @@ +/* ********************************************************** + * Copyright (C) 1998-2002 VMware, Inc. + * All Rights Reserved + * **********************************************************/ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.h,v 1.2 2002/12/11 17:07:58 dawes Exp $ */ + +#ifndef OFFSCREEN_MANAGER_H +#define OFFSCREEN_MANAGER_H + +struct _Heap; +typedef struct _Heap Heap; + +extern Heap* vmwareHeap_Create(CARD8* ptr, CARD32 size, CARD32 maxSlots, + CARD32 startOffset, CARD32 sWidth, CARD32 sHeight, + CARD32 sBPP, CARD32 sPitch, CARD32 sFbOffset); +extern void vmwareHeap_Destroy(Heap* heap); + +extern void vmwareHeap_Clear(Heap* heap); + +extern SVGASurface* vmwareHeap_GetFrontBuffer(Heap* heap); + +extern SVGASurface* vmwareHeap_AllocSurface(Heap* heap, CARD32 width, CARD32 height, + CARD32 pitch, CARD32 bpp); + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_reg.h index ef0dbaf42..3bb5b4981 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_reg.h @@ -1,7 +1,7 @@ /* ********************************************************** * Copyright (C) 1998-2001 VMware, Inc. * All Rights Reserved - * $Id: svga_reg.h,v 1.4 2002/11/25 19:58:54 brianp Exp $ + * $Id: svga_reg.h,v 1.5 2003/03/25 11:23:42 alanh Exp $ * **********************************************************/ /* @@ -9,6 +9,7 @@ * * SVGA hardware definitions */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_reg.h,v 1.8 2003/02/04 01:39:53 dawes Exp $ */ #ifndef _SVGA_REG_H_ #define _SVGA_REG_H_ @@ -31,10 +32,7 @@ #define SVGA_MAX_HEIGHT 1770 #define SVGA_MAX_BITS_PER_PIXEL 32 -#ifndef PAGE_SHIFT #define PAGE_SHIFT 12 -#endif - #define SVGA_FB_MAX_SIZE \ ((((SVGA_MAX_WIDTH * SVGA_MAX_HEIGHT * \ SVGA_MAX_BITS_PER_PIXEL / 8) >> PAGE_SHIFT) + 1) << PAGE_SHIFT) @@ -143,6 +141,7 @@ enum { #define SVGA_CAP_GLYPH 0x0400 #define SVGA_CAP_GLYPH_CLIPPING 0x0800 #define SVGA_CAP_OFFSCREEN_1 0x1000 +#define SVGA_CAP_ALPHA_BLEND 0x2000 /* @@ -172,6 +171,71 @@ enum { #define SVGA_IS_VALID_ROP(rop) (rop >= 0 && rop < SVGA_NUM_SUPPORTED_ROPS) /* + * Ops + * For each pixel, the four channels of the image are computed with: + * + * C = Ca * Fa + Cb * Fb + * + * where C, Ca, Cb are the values of the respective channels and Fa + * and Fb come from the following table: + * + * BlendOp Fa Fb + * ------------------------------------------ + * Clear 0 0 + * Src 1 0 + * Dst 0 1 + * Over 1 1-Aa + * OverReverse 1-Ab 1 + * In Ab 0 + * InReverse 0 Aa + * Out 1-Ab 0 + * OutReverse 0 1-Aa + * Atop Ab 1-Aa + * AtopReverse 1-Ab Aa + * Xor 1-Ab 1-Aa + * Add 1 1 + * Saturate min(1,(1-Ab)/Aa) 1 + * + * Flags + * You can use the following flags to achieve additional affects: + * + * Flag Effect + * ------------------------------------------ + * ConstantSourceAlpha Ca = Ca * Param0 + * ConstantDestAlpha Cb = Cb * Param1 + * + * Flag effects resolve before the op. For example + * BlendOp == Add && Flags == ConstantSourceAlpha | + * ConstantDestAlpha results in: + * + * C = (Ca * Param0) + (Cb * Param1) + */ + +#define SVGA_BLENDOP_CLEAR 0 +#define SVGA_BLENDOP_SRC 1 +#define SVGA_BLENDOP_DST 2 +#define SVGA_BLENDOP_OVER 3 +#define SVGA_BLENDOP_OVER_REVERSE 4 +#define SVGA_BLENDOP_IN 5 +#define SVGA_BLENDOP_IN_REVERSE 6 +#define SVGA_BLENDOP_OUT 7 +#define SVGA_BLENDOP_OUT_REVERSE 8 +#define SVGA_BLENDOP_ATOP 9 +#define SVGA_BLENDOP_ATOP_REVERSE 10 +#define SVGA_BLENDOP_XOR 11 +#define SVGA_BLENDOP_ADD 12 +#define SVGA_BLENDOP_SATURATE 13 + +#define SVGA_NUM_BLENDOPS 14 +#define SVGA_IS_VALID_BLENDOP(op) (op >= 0 && op < SVGA_NUM_BLENDOPS) + +#define SVGA_BLENDFLAG_CONSTANT_SOURCE_ALPHA 0x01 +#define SVGA_BLENDFLAG_CONSTANT_DEST_ALPHA 0x02 +#define SVGA_NUM_BLENDFLAGS 2 +#define SVGA_BLENDFLAG_ALL (MASK(SVGA_NUM_BLENDFLAGS)) +#define SVGA_IS_VALID_BLENDFLAG(flag) ((flag & ~SVGA_BLENDFLAG_ALL) == 0) + +/* * Memory area offsets (viewed as an array of 32-bit words) */ @@ -205,12 +269,27 @@ enum { #define SVGA_GLYPH_SCANLINE_SIZE(w) (((w) + 7) >> 3) /* + * Get the width and height of VRAM in the current mode (for offscreen memory) + */ +#define SVGA_VRAM_WIDTH_HEIGHT(width /* out */, height /* out */) { \ + uint32 pitch = svga->reg[SVGA_REG_BYTES_PER_LINE]; \ + width = (pitch * 8) / ((svga->reg[SVGA_REG_BITS_PER_PIXEL] + 7) & ~7); \ + height = (svga->reg[SVGA_REG_VRAM_SIZE] - \ + svga->reg[SVGA_REG_FB_OFFSET]) / pitch; \ +} + +/* * Increment from one scanline to the next of a bitmap or pixmap */ #define SVGA_BITMAP_INCREMENT(w) ((( (w)+31 ) >> 5) * sizeof (uint32)) #define SVGA_PIXMAP_INCREMENT(w,bpp) ((( ((w)*(bpp))+31 ) >> 5) * sizeof (uint32)) /* + * Transparent color for DRAW_GLYPH_CLIPPED + */ +#define SVGA_COLOR_TRANSPARENT (~0) + +/* * Commands in the command FIFO */ @@ -317,7 +396,8 @@ enum { #define SVGA_CMD_DRAW_GLYPH_CLIPPED 24 /* FIFO layout: - X, Y, W, H, FGCOLOR, <cliprect>, <stencil buffer> */ + X, Y, W, H, FGCOLOR, BGCOLOR, <cliprect>, <stencil buffer> + Transparent color expands are done by setting BGCOLOR to ~0 */ #define SVGA_CMD_UPDATE_VERBOSE 25 /* FIFO layout: @@ -332,10 +412,16 @@ enum { srcSurfaceOffset, dstSurfaceOffset, srcX, srcY, destX, destY, w, h, rop */ -#define SVGA_CMD_MAX 28 +#define SVGA_CMD_SURFACE_ALPHA_BLEND 28 + /* FIFO layout: + srcSurfaceOffset, dstSurfaceOffset, srcX, srcY, + destX, destY, w, h, op (SVGA_BLENDOP*), flags (SVGA_BLENDFLAGS*), + param1, param2 */ + +#define SVGA_CMD_MAX 29 -/* RECT_ROP_BITMAP_COPY currently has the most (non-data) arguments: 10 */ -#define SVGA_CMD_MAX_ARGS 10 +/* SURFACE_ALPHA_BLEND currently has the most (non-data) arguments: 12 */ +#define SVGA_CMD_MAX_ARGS 12 /* diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_struct.h b/xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_struct.h new file mode 100644 index 000000000..fe4f0bfc5 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_struct.h @@ -0,0 +1,40 @@ +/* ********************************************************** + * Copyright (C) 1998-2000 VMware, Inc. + * All Rights Reserved + * **********************************************************/ + +#ifndef _SVGA_STRUCT_H_ +#define _SVGA_STRUCT_H_ + +#define INCLUDE_ALLOW_USERLEVEL +#define INCLUDE_ALLOW_MONITOR +#include "includeCheck.h" + + /* + * Offscreen memory surface structure + * + */ + +enum SVGASurfaceVersion { + SVGA_SURFACE_VERSION_1 = 1 /* Initial version... */ +}; + +typedef struct _SVGASurface { + uint32 size; /* Size of the structure */ + uint32 version; /* Version of this surface structure. */ + uint32 bpp; /* Format of the surface */ + uint32 width; /* Width of the surface */ + uint32 height; /* Height of the surface */ + uint32 pitch; /* Pitch of the surface */ + volatile uint32 numQueued; /* Number of times this bitmap has been queued */ + volatile uint32 numDequeued; /* Number of times this bitmap has been dequeued */ + uint32 userData; /* Driver defined data */ + uint32 dataOffset; /* Offset to the data */ +} SVGASurface; + +typedef struct SVGAPoint { + int16 x; + int16 y; +} SVGAPoint; + +#endif |