summaryrefslogtreecommitdiff
path: root/src/drivers/xgi
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/xgi')
-rw-r--r--src/drivers/xgi/Kconfig2
-rw-r--r--src/drivers/xgi/Makefile.inc1
-rw-r--r--src/drivers/xgi/common/Kconfig10
-rw-r--r--src/drivers/xgi/common/Makefile.inc1
-rw-r--r--src/drivers/xgi/common/XGI_main.c871
-rw-r--r--src/drivers/xgi/common/XGI_main.h395
-rw-r--r--src/drivers/xgi/common/XGIfb.h153
-rw-r--r--src/drivers/xgi/common/initdef.h708
-rw-r--r--src/drivers/xgi/common/vb_def.h276
-rw-r--r--src/drivers/xgi/common/vb_init.c1289
-rw-r--r--src/drivers/xgi/common/vb_init.h25
-rw-r--r--src/drivers/xgi/common/vb_setmode.c5576
-rw-r--r--src/drivers/xgi/common/vb_setmode.h42
-rw-r--r--src/drivers/xgi/common/vb_struct.h184
-rw-r--r--src/drivers/xgi/common/vb_table.h2510
-rw-r--r--src/drivers/xgi/common/vb_util.c67
-rw-r--r--src/drivers/xgi/common/vb_util.h28
-rw-r--r--src/drivers/xgi/common/vgatypes.h64
-rw-r--r--src/drivers/xgi/common/vstruct.h551
-rwxr-xr-xsrc/drivers/xgi/common/xgi_coreboot.c436
-rw-r--r--src/drivers/xgi/common/xgi_coreboot.h289
-rw-r--r--src/drivers/xgi/z9s/Kconfig14
-rw-r--r--src/drivers/xgi/z9s/Makefile.inc1
-rw-r--r--src/drivers/xgi/z9s/z9s.c59
24 files changed, 13552 insertions, 0 deletions
diff --git a/src/drivers/xgi/Kconfig b/src/drivers/xgi/Kconfig
new file mode 100644
index 0000000000..3e083d6e0c
--- /dev/null
+++ b/src/drivers/xgi/Kconfig
@@ -0,0 +1,2 @@
+source src/drivers/xgi/common/Kconfig
+source src/drivers/xgi/z9s/Kconfig \ No newline at end of file
diff --git a/src/drivers/xgi/Makefile.inc b/src/drivers/xgi/Makefile.inc
new file mode 100644
index 0000000000..ce83d7a3ea
--- /dev/null
+++ b/src/drivers/xgi/Makefile.inc
@@ -0,0 +1 @@
+subdirs-y += common z9s \ No newline at end of file
diff --git a/src/drivers/xgi/common/Kconfig b/src/drivers/xgi/common/Kconfig
new file mode 100644
index 0000000000..e0ed9d6baa
--- /dev/null
+++ b/src/drivers/xgi/common/Kconfig
@@ -0,0 +1,10 @@
+config DRIVERS_XGI_Z79_COMMON
+ bool
+
+if !MAINBOARD_DO_NATIVE_VGA_INIT
+
+config DEVICE_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select VGA
+
+endif # MAINBOARD_DO_NATIVE_VGA_INIT
diff --git a/src/drivers/xgi/common/Makefile.inc b/src/drivers/xgi/common/Makefile.inc
new file mode 100644
index 0000000000..2bb35a8731
--- /dev/null
+++ b/src/drivers/xgi/common/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_XGI_Z79_COMMON) += vb_init.c vb_util.c vb_setmode.c xgi_coreboot.c
diff --git a/src/drivers/xgi/common/XGI_main.c b/src/drivers/xgi/common/XGI_main.c
new file mode 100644
index 0000000000..c76ebf76c1
--- /dev/null
+++ b/src/drivers/xgi/common/XGI_main.c
@@ -0,0 +1,871 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Code taken from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Select functions taken from the Linux xgifb driver file XGI_main_26.c
+ *
+ * Original file header:
+ * XG20, XG21, XG40, XG42 frame buffer device
+ * for Linux kernels 2.5.x, 2.6.x
+ * Base on TW's sis fbdev code.
+ */
+
+
+#define Index_CR_GPIO_Reg1 0x48
+#define Index_CR_GPIO_Reg3 0x4a
+
+#define GPIOG_EN (1<<6)
+#define GPIOG_READ (1<<1)
+
+// static char *mode;
+static int vesa = -1;
+static unsigned int refresh_rate;
+
+/* ---------------- Chip generation dependent routines ---------------- */
+
+/* for XGI 315/550/650/740/330 */
+
+static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
+{
+
+ u8 ChannelNum, tmp;
+ u8 reg = 0;
+
+ /* xorg driver sets 32MB * 1 channel */
+ if (xgifb_info->chip == XG27)
+ xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51);
+
+ reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE);
+ if (!reg)
+ return -1;
+
+ switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
+ case XGI_DRAM_SIZE_1MB:
+ xgifb_info->video_size = 0x100000;
+ break;
+ case XGI_DRAM_SIZE_2MB:
+ xgifb_info->video_size = 0x200000;
+ break;
+ case XGI_DRAM_SIZE_4MB:
+ xgifb_info->video_size = 0x400000;
+ break;
+ case XGI_DRAM_SIZE_8MB:
+ xgifb_info->video_size = 0x800000;
+ break;
+ case XGI_DRAM_SIZE_16MB:
+ xgifb_info->video_size = 0x1000000;
+ break;
+ case XGI_DRAM_SIZE_32MB:
+ xgifb_info->video_size = 0x2000000;
+ break;
+ case XGI_DRAM_SIZE_64MB:
+ xgifb_info->video_size = 0x4000000;
+ break;
+ case XGI_DRAM_SIZE_128MB:
+ xgifb_info->video_size = 0x8000000;
+ break;
+ case XGI_DRAM_SIZE_256MB:
+ xgifb_info->video_size = 0x10000000;
+ break;
+ default:
+ return -1;
+ }
+
+ tmp = (reg & 0x0c) >> 2;
+ switch (xgifb_info->chip) {
+ case XG20:
+ case XG21:
+ case XG27:
+ ChannelNum = 1;
+ break;
+
+ case XG42:
+ if (reg & 0x04)
+ ChannelNum = 2;
+ else
+ ChannelNum = 1;
+ break;
+
+ case XG40:
+ default:
+ if (tmp == 2)
+ ChannelNum = 2;
+ else if (tmp == 3)
+ ChannelNum = 3;
+ else
+ ChannelNum = 1;
+ break;
+ }
+
+ xgifb_info->video_size = xgifb_info->video_size * ChannelNum;
+
+ pr_info("SR14=%x DramSzie %x ChannelNum %x\n",
+ reg,
+ xgifb_info->video_size, ChannelNum);
+ return 0;
+
+}
+
+void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
+{
+ XGI_Pr->P3c4 = BaseAddr + 0x14;
+ XGI_Pr->P3d4 = BaseAddr + 0x24;
+ XGI_Pr->P3c0 = BaseAddr + 0x10;
+ XGI_Pr->P3ce = BaseAddr + 0x1e;
+ XGI_Pr->P3c2 = BaseAddr + 0x12;
+ XGI_Pr->P3cc = BaseAddr + 0x1c;
+ XGI_Pr->P3ca = BaseAddr + 0x1a;
+ XGI_Pr->P3c6 = BaseAddr + 0x16;
+ XGI_Pr->P3c7 = BaseAddr + 0x17;
+ XGI_Pr->P3c8 = BaseAddr + 0x18;
+ XGI_Pr->P3c9 = BaseAddr + 0x19;
+ XGI_Pr->P3da = BaseAddr + 0x2A;
+ XGI_Pr->Part0Port = BaseAddr + XGI_CRT2_PORT_00;
+ /* Digital video interface registers (LCD) */
+ XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04;
+ /* 301 TV Encoder registers */
+ XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+ /* 301 Macrovision registers */
+ XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12;
+ /* 301 VGA2 (and LCD) registers */
+ XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14;
+ /* 301 palette address port registers */
+ XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
+
+}
+
+/* ------------------ Internal helper routines ----------------- */
+
+static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info)
+{
+ int i = 0;
+
+ while ((XGIbios_mode[i].mode_no != 0)
+ && (XGIbios_mode[i].xres <= xgifb_info->lvds_data.LVDSHDE)) {
+ if ((XGIbios_mode[i].xres == xgifb_info->lvds_data.LVDSHDE)
+ && (XGIbios_mode[i].yres == xgifb_info->lvds_data.LVDSVDE)
+ && (XGIbios_mode[i].bpp == 8)) {
+ return i;
+ }
+ i++;
+ }
+
+ return -1;
+}
+
+static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info,
+ unsigned int rate)
+{
+ u16 xres, yres;
+ int i = 0;
+
+ xres = XGIbios_mode[xgifb_info->mode_idx].xres;
+ yres = XGIbios_mode[xgifb_info->mode_idx].yres;
+
+ xgifb_info->rate_idx = 0;
+ while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
+ if ((XGIfb_vrate[i].xres == xres) &&
+ (XGIfb_vrate[i].yres == yres)) {
+ if (XGIfb_vrate[i].refresh == rate) {
+ xgifb_info->rate_idx = XGIfb_vrate[i].idx;
+ break;
+ } else if (XGIfb_vrate[i].refresh > rate) {
+ if ((XGIfb_vrate[i].refresh - rate) <= 3) {
+ pr_debug("Adjusting rate from %d up to %d\n",
+ rate, XGIfb_vrate[i].refresh);
+ xgifb_info->rate_idx =
+ XGIfb_vrate[i].idx;
+ xgifb_info->refresh_rate =
+ XGIfb_vrate[i].refresh;
+ } else if (((rate - XGIfb_vrate[i - 1].refresh)
+ <= 2) && (XGIfb_vrate[i].idx
+ != 1)) {
+ pr_debug("Adjusting rate from %d down to %d\n",
+ rate,
+ XGIfb_vrate[i-1].refresh);
+ xgifb_info->rate_idx =
+ XGIfb_vrate[i - 1].idx;
+ xgifb_info->refresh_rate =
+ XGIfb_vrate[i - 1].refresh;
+ }
+ break;
+ } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
+ pr_debug("Adjusting rate from %d down to %d\n",
+ rate, XGIfb_vrate[i].refresh);
+ xgifb_info->rate_idx = XGIfb_vrate[i].idx;
+ break;
+ }
+ }
+ i++;
+ }
+ if (xgifb_info->rate_idx > 0)
+ return xgifb_info->rate_idx;
+ pr_info("Unsupported rate %d for %dx%d\n",
+ rate, xres, yres);
+ return 0;
+}
+
+static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
+{
+ u8 cr32, temp = 0;
+
+ xgifb_info->TV_plug = xgifb_info->TV_type = 0;
+
+ cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
+
+ if ((cr32 & SIS_CRT1) && !XGIfb_crt1off)
+ XGIfb_crt1off = 0;
+ else {
+ if (cr32 & 0x5F)
+ XGIfb_crt1off = 1;
+ else
+ XGIfb_crt1off = 0;
+ }
+
+ if (!xgifb_info->display2_force) {
+ if (cr32 & SIS_VB_TV)
+ xgifb_info->display2 = XGIFB_DISP_TV;
+ else if (cr32 & SIS_VB_LCD)
+ xgifb_info->display2 = XGIFB_DISP_LCD;
+ else if (cr32 & SIS_VB_CRT2)
+ xgifb_info->display2 = XGIFB_DISP_CRT;
+ else
+ xgifb_info->display2 = XGIFB_DISP_NONE;
+ }
+
+ if (XGIfb_tvplug != -1)
+ /* Override with option */
+ xgifb_info->TV_plug = XGIfb_tvplug;
+ else if (cr32 & SIS_VB_HIVISION) {
+ xgifb_info->TV_type = TVMODE_HIVISION;
+ xgifb_info->TV_plug = TVPLUG_SVIDEO;
+ } else if (cr32 & SIS_VB_SVIDEO)
+ xgifb_info->TV_plug = TVPLUG_SVIDEO;
+ else if (cr32 & SIS_VB_COMPOSITE)
+ xgifb_info->TV_plug = TVPLUG_COMPOSITE;
+ else if (cr32 & SIS_VB_SCART)
+ xgifb_info->TV_plug = TVPLUG_SCART;
+
+ if (xgifb_info->TV_type == 0) {
+ temp = xgifb_reg_get(XGICR, 0x38);
+ if (temp & 0x10)
+ xgifb_info->TV_type = TVMODE_PAL;
+ else
+ xgifb_info->TV_type = TVMODE_NTSC;
+ }
+
+ /* Copy forceCRT1 option to CRT1off if option is given */
+ if (XGIfb_forcecrt1 != -1) {
+ if (XGIfb_forcecrt1)
+ XGIfb_crt1off = 0;
+ else
+ XGIfb_crt1off = 1;
+ }
+}
+
+static int XGIfb_has_VB(struct xgifb_video_info *xgifb_info)
+{
+ u8 vb_chipid;
+
+ vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
+ switch (vb_chipid) {
+ case 0x01:
+ xgifb_info->hasVB = HASVB_301;
+ break;
+ case 0x02:
+ xgifb_info->hasVB = HASVB_302;
+ break;
+ default:
+ xgifb_info->hasVB = HASVB_NONE;
+ return 0;
+ }
+ return 1;
+}
+
+static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info)
+{
+ u8 reg;
+
+ if (!XGIfb_has_VB(xgifb_info)) {
+ reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
+ switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+ case SIS_EXTERNAL_CHIP_LVDS:
+ xgifb_info->hasVB = HASVB_LVDS;
+ break;
+ case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+ xgifb_info->hasVB = HASVB_LVDS_CHRONTEL;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+#if 0
+static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info,
+ const char *name)
+{
+ unsigned int xres;
+ unsigned int yres;
+ unsigned int bpp;
+ int i;
+
+ if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3)
+ goto invalid_mode;
+
+ if (bpp == 24)
+ bpp = 32; /* That's for people who mix up color and fb depth. */
+
+ for (i = 0; XGIbios_mode[i].mode_no != 0; i++)
+ if (XGIbios_mode[i].xres == xres &&
+ XGIbios_mode[i].yres == yres &&
+ XGIbios_mode[i].bpp == bpp) {
+ xgifb_info->mode_idx = i;
+ return;
+ }
+invalid_mode:
+ pr_info("Invalid mode '%s'\n", name);
+}
+#endif
+
+static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info,
+ unsigned int vesamode)
+{
+ int i = 0;
+
+ if (vesamode == 0)
+ goto invalid;
+
+ vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
+
+ while (XGIbios_mode[i].mode_no != 0) {
+ if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
+ (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
+ xgifb_info->mode_idx = i;
+ return;
+ }
+ i++;
+ }
+
+invalid:
+ pr_info("Invalid VESA mode 0x%x'\n", vesamode);
+}
+
+static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
+{
+ u16 xres, yres;
+ struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
+ unsigned long required_mem;
+
+ if (xgifb_info->chip == XG21) {
+ if (xgifb_info->display2 == XGIFB_DISP_LCD) {
+ xres = xgifb_info->lvds_data.LVDSHDE;
+ yres = xgifb_info->lvds_data.LVDSVDE;
+ if (XGIbios_mode[myindex].xres > xres)
+ return -1;
+ if (XGIbios_mode[myindex].yres > yres)
+ return -1;
+ if ((XGIbios_mode[myindex].xres < xres) &&
+ (XGIbios_mode[myindex].yres < yres)) {
+ if (XGIbios_mode[myindex].bpp > 8)
+ return -1;
+ }
+
+ }
+ goto check_memory;
+
+ }
+
+ /* FIXME: for now, all is valid on XG27 */
+ if (xgifb_info->chip == XG27)
+ goto check_memory;
+
+ if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
+ return -1;
+
+ switch (xgifb_info->display2) {
+ case XGIFB_DISP_LCD:
+ switch (hw_info->ulCRT2LCDType) {
+ case LCD_640x480:
+ xres = 640;
+ yres = 480;
+ break;
+ case LCD_800x600:
+ xres = 800;
+ yres = 600;
+ break;
+ case LCD_1024x600:
+ xres = 1024;
+ yres = 600;
+ break;
+ case LCD_1024x768:
+ xres = 1024;
+ yres = 768;
+ break;
+ case LCD_1152x768:
+ xres = 1152;
+ yres = 768;
+ break;
+ case LCD_1280x960:
+ xres = 1280;
+ yres = 960;
+ break;
+ case LCD_1280x768:
+ xres = 1280;
+ yres = 768;
+ break;
+ case LCD_1280x1024:
+ xres = 1280;
+ yres = 1024;
+ break;
+ case LCD_1400x1050:
+ xres = 1400;
+ yres = 1050;
+ break;
+ case LCD_1600x1200:
+ xres = 1600;
+ yres = 1200;
+ break;
+ default:
+ xres = 0;
+ yres = 0;
+ break;
+ }
+ if (XGIbios_mode[myindex].xres > xres)
+ return -1;
+ if (XGIbios_mode[myindex].yres > yres)
+ return -1;
+ if ((hw_info->ulExternalChip == 0x01) || /* LVDS */
+ (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */
+ switch (XGIbios_mode[myindex].xres) {
+ case 512:
+ if (XGIbios_mode[myindex].yres != 512)
+ return -1;
+ if (hw_info->ulCRT2LCDType == LCD_1024x600)
+ return -1;
+ break;
+ case 640:
+ if ((XGIbios_mode[myindex].yres != 400)
+ && (XGIbios_mode[myindex].yres
+ != 480))
+ return -1;
+ break;
+ case 800:
+ if (XGIbios_mode[myindex].yres != 600)
+ return -1;
+ break;
+ case 1024:
+ if ((XGIbios_mode[myindex].yres != 600) &&
+ (XGIbios_mode[myindex].yres != 768))
+ return -1;
+ if ((XGIbios_mode[myindex].yres == 600) &&
+ (hw_info->ulCRT2LCDType != LCD_1024x600))
+ return -1;
+ break;
+ case 1152:
+ if ((XGIbios_mode[myindex].yres) != 768)
+ return -1;
+ if (hw_info->ulCRT2LCDType != LCD_1152x768)
+ return -1;
+ break;
+ case 1280:
+ if ((XGIbios_mode[myindex].yres != 768) &&
+ (XGIbios_mode[myindex].yres != 1024))
+ return -1;
+ if ((XGIbios_mode[myindex].yres == 768) &&
+ (hw_info->ulCRT2LCDType != LCD_1280x768))
+ return -1;
+ break;
+ case 1400:
+ if (XGIbios_mode[myindex].yres != 1050)
+ return -1;
+ break;
+ case 1600:
+ if (XGIbios_mode[myindex].yres != 1200)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ } else {
+ switch (XGIbios_mode[myindex].xres) {
+ case 512:
+ if (XGIbios_mode[myindex].yres != 512)
+ return -1;
+ break;
+ case 640:
+ if ((XGIbios_mode[myindex].yres != 400) &&
+ (XGIbios_mode[myindex].yres != 480))
+ return -1;
+ break;
+ case 800:
+ if (XGIbios_mode[myindex].yres != 600)
+ return -1;
+ break;
+ case 1024:
+ if (XGIbios_mode[myindex].yres != 768)
+ return -1;
+ break;
+ case 1280:
+ if ((XGIbios_mode[myindex].yres != 960) &&
+ (XGIbios_mode[myindex].yres != 1024))
+ return -1;
+ if (XGIbios_mode[myindex].yres == 960) {
+ if (hw_info->ulCRT2LCDType ==
+ LCD_1400x1050)
+ return -1;
+ }
+ break;
+ case 1400:
+ if (XGIbios_mode[myindex].yres != 1050)
+ return -1;
+ break;
+ case 1600:
+ if (XGIbios_mode[myindex].yres != 1200)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ }
+ break;
+ case XGIFB_DISP_TV:
+ switch (XGIbios_mode[myindex].xres) {
+ case 512:
+ case 640:
+ case 800:
+ break;
+ case 720:
+ if (xgifb_info->TV_type == TVMODE_NTSC) {
+ if (XGIbios_mode[myindex].yres != 480)
+ return -1;
+ } else if (xgifb_info->TV_type == TVMODE_PAL) {
+ if (XGIbios_mode[myindex].yres != 576)
+ return -1;
+ }
+ /* LVDS/CHRONTEL does not support 720 */
+ if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL ||
+ xgifb_info->hasVB == HASVB_CHRONTEL) {
+ return -1;
+ }
+ break;
+ case 1024:
+ if (xgifb_info->TV_type == TVMODE_NTSC) {
+ if (XGIbios_mode[myindex].bpp == 32)
+ return -1;
+ }
+ break;
+ default:
+ return -1;
+ }
+ break;
+ case XGIFB_DISP_CRT:
+ if (XGIbios_mode[myindex].xres > 1280)
+ return -1;
+ break;
+ case XGIFB_DISP_NONE:
+ break;
+ }
+
+check_memory:
+ required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres *
+ XGIbios_mode[myindex].bpp / 8;
+ if (required_mem > xgifb_info->video_size)
+ return -1;
+ return myindex;
+
+}
+
+/* --------------------- SetMode routines ------------------------- */
+
+#if IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT)
+
+static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info)
+{
+ u8 cr30 = 0, cr31 = 0;
+
+ cr31 = xgifb_reg_get(XGICR, 0x31);
+ cr31 &= ~0x60;
+
+ switch (xgifb_info->display2) {
+ case XGIFB_DISP_CRT:
+ cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ cr31 |= SIS_DRIVER_MODE;
+ break;
+ case XGIFB_DISP_LCD:
+ cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ cr31 |= SIS_DRIVER_MODE;
+ break;
+ case XGIFB_DISP_TV:
+ if (xgifb_info->TV_type == TVMODE_HIVISION)
+ cr30 = (SIS_VB_OUTPUT_HIVISION
+ | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ else if (xgifb_info->TV_plug == TVPLUG_SVIDEO)
+ cr30 = (SIS_VB_OUTPUT_SVIDEO
+ | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE)
+ cr30 = (SIS_VB_OUTPUT_COMPOSITE
+ | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ else if (xgifb_info->TV_plug == TVPLUG_SCART)
+ cr30 = (SIS_VB_OUTPUT_SCART
+ | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ cr31 |= SIS_DRIVER_MODE;
+
+ if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL)
+ cr31 |= 0x01;
+ else
+ cr31 &= ~0x01;
+ break;
+ default: /* disable CRT2 */
+ cr30 = 0x00;
+ cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
+ }
+
+ xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
+ xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
+ xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33,
+ (xgifb_info->rate_idx & 0x0F));
+}
+
+static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
+{
+ u8 reg;
+ unsigned char doit = 1;
+
+ if (xgifb_info->video_bpp == 8) {
+ /*
+ * We can't switch off CRT1 on LVDS/Chrontel
+ * in 8bpp Modes
+ */
+ if ((xgifb_info->hasVB == HASVB_LVDS) ||
+ (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) {
+ doit = 0;
+ }
+ /*
+ * We can't switch off CRT1 on 301B-DH
+ * in 8bpp Modes if using LCD
+ */
+ if (xgifb_info->display2 == XGIFB_DISP_LCD)
+ doit = 0;
+ }
+
+ /* We can't switch off CRT1 if bridge is in slave mode */
+ if (xgifb_info->hasVB != HASVB_NONE) {
+ reg = xgifb_reg_get(XGIPART1, 0x00);
+
+ if ((reg & 0x50) == 0x10)
+ doit = 0;
+
+ } else {
+ XGIfb_crt1off = 0;
+ }
+
+ reg = xgifb_reg_get(XGICR, 0x17);
+ if ((XGIfb_crt1off) && (doit))
+ reg &= ~0x80;
+ else
+ reg |= 0x80;
+ xgifb_reg_set(XGICR, 0x17, reg);
+
+ xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04);
+
+ if (xgifb_info->display2 == XGIFB_DISP_TV &&
+ xgifb_info->hasVB == HASVB_301) {
+
+ reg = xgifb_reg_get(XGIPART4, 0x01);
+
+ if (reg < 0xB0) { /* Set filter for XGI301 */
+ int filter_tb;
+
+ switch (xgifb_info->video_width) {
+ case 320:
+ filter_tb = (xgifb_info->TV_type ==
+ TVMODE_NTSC) ? 4 : 12;
+ break;
+ case 640:
+ filter_tb = (xgifb_info->TV_type ==
+ TVMODE_NTSC) ? 5 : 13;
+ break;
+ case 720:
+ filter_tb = (xgifb_info->TV_type ==
+ TVMODE_NTSC) ? 6 : 14;
+ break;
+ case 800:
+ filter_tb = (xgifb_info->TV_type ==
+ TVMODE_NTSC) ? 7 : 15;
+ break;
+ default:
+ filter_tb = 0;
+ filter = -1;
+ break;
+ }
+ xgifb_reg_or(XGIPART1,
+ SIS_CRT2_WENABLE_315,
+ 0x01);
+
+ if (xgifb_info->TV_type == TVMODE_NTSC) {
+
+ xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
+
+ if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
+
+ xgifb_reg_and(XGIPART2, 0x30, 0xdf);
+
+ } else if (xgifb_info->TV_plug
+ == TVPLUG_COMPOSITE) {
+
+ xgifb_reg_or(XGIPART2, 0x30, 0x20);
+
+ switch (xgifb_info->video_width) {
+ case 640:
+ xgifb_reg_set(XGIPART2,
+ 0x35,
+ 0xEB);
+ xgifb_reg_set(XGIPART2,
+ 0x36,
+ 0x04);
+ xgifb_reg_set(XGIPART2,
+ 0x37,
+ 0x25);
+ xgifb_reg_set(XGIPART2,
+ 0x38,
+ 0x18);
+ break;
+ case 720:
+ xgifb_reg_set(XGIPART2,
+ 0x35,
+ 0xEE);
+ xgifb_reg_set(XGIPART2,
+ 0x36,
+ 0x0C);
+ xgifb_reg_set(XGIPART2,
+ 0x37,
+ 0x22);
+ xgifb_reg_set(XGIPART2,
+ 0x38,
+ 0x08);
+ break;
+ case 800:
+ xgifb_reg_set(XGIPART2,
+ 0x35,
+ 0xEB);
+ xgifb_reg_set(XGIPART2,
+ 0x36,
+ 0x15);
+ xgifb_reg_set(XGIPART2,
+ 0x37,
+ 0x25);
+ xgifb_reg_set(XGIPART2,
+ 0x38,
+ 0xF6);
+ break;
+ }
+ }
+
+ } else if (xgifb_info->TV_type == TVMODE_PAL) {
+
+ xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
+
+ if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
+
+ xgifb_reg_and(XGIPART2, 0x30, 0xDF);
+
+ } else if (xgifb_info->TV_plug
+ == TVPLUG_COMPOSITE) {
+
+ xgifb_reg_or(XGIPART2, 0x30, 0x20);
+
+ switch (xgifb_info->video_width) {
+ case 640:
+ xgifb_reg_set(XGIPART2,
+ 0x35,
+ 0xF1);
+ xgifb_reg_set(XGIPART2,
+ 0x36,
+ 0xF7);
+ xgifb_reg_set(XGIPART2,
+ 0x37,
+ 0x1F);
+ xgifb_reg_set(XGIPART2,
+ 0x38,
+ 0x32);
+ break;
+ case 720:
+ xgifb_reg_set(XGIPART2,
+ 0x35,
+ 0xF3);
+ xgifb_reg_set(XGIPART2,
+ 0x36,
+ 0x00);
+ xgifb_reg_set(XGIPART2,
+ 0x37,
+ 0x1D);
+ xgifb_reg_set(XGIPART2,
+ 0x38,
+ 0x20);
+ break;
+ case 800:
+ xgifb_reg_set(XGIPART2,
+ 0x35,
+ 0xFC);
+ xgifb_reg_set(XGIPART2,
+ 0x36,
+ 0xFB);
+ xgifb_reg_set(XGIPART2,
+ 0x37,
+ 0x14);
+ xgifb_reg_set(XGIPART2,
+ 0x38,
+ 0x2A);
+ break;
+ }
+ }
+ }
+
+ if ((filter >= 0) && (filter <= 7)) {
+ pr_debug("FilterTable[%d]-%d: %*ph\n",
+ filter_tb, filter,
+ 4, XGI_TV_filter[filter_tb].
+ filter[filter]);
+ xgifb_reg_set(
+ XGIPART2,
+ 0x35,
+ (XGI_TV_filter[filter_tb].
+ filter[filter][0]));
+ xgifb_reg_set(
+ XGIPART2,
+ 0x36,
+ (XGI_TV_filter[filter_tb].
+ filter[filter][1]));
+ xgifb_reg_set(
+ XGIPART2,
+ 0x37,
+ (XGI_TV_filter[filter_tb].
+ filter[filter][2]));
+ xgifb_reg_set(
+ XGIPART2,
+ 0x38,
+ (XGI_TV_filter[filter_tb].
+ filter[filter][3]));
+ }
+ }
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/drivers/xgi/common/XGI_main.h b/src/drivers/xgi/common/XGI_main.h
new file mode 100644
index 0000000000..cd9b84a71c
--- /dev/null
+++ b/src/drivers/xgi/common/XGI_main.h
@@ -0,0 +1,395 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken from the Linux xgifb driver (v3.18.5)
+ * Coreboot-specific includes added at top
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _XGIFB_MAIN
+#define _XGIFB_MAIN
+
+/* coreboot includes */
+#include "xgi_coreboot.h"
+
+/* ------------------- Constant Definitions ------------------------- */
+#include "XGIfb.h"
+#include "vb_def.h"
+
+#define PCI_DEVICE_ID_XGI_42 0x042
+#define PCI_DEVICE_ID_XGI_27 0x027
+
+/* To be included in fb.h */
+#define XGISR (xgifb_info->dev_info.P3c4)
+#define XGICR (xgifb_info->dev_info.P3d4)
+#define XGIDACA (xgifb_info->dev_info.P3c8)
+#define XGIDACD (xgifb_info->dev_info.P3c9)
+#define XGIPART1 (xgifb_info->dev_info.Part1Port)
+#define XGIPART2 (xgifb_info->dev_info.Part2Port)
+#define XGIPART3 (xgifb_info->dev_info.Part3Port)
+#define XGIPART4 (xgifb_info->dev_info.Part4Port)
+#define XGIPART5 (xgifb_info->dev_info.Part5Port)
+#define XGIDAC2A XGIPART5
+#define XGIDAC2D (XGIPART5 + 1)
+
+#define IND_XGI_SCRATCH_REG_CR30 0x30 /* CRs */
+#define IND_XGI_SCRATCH_REG_CR31 0x31
+#define IND_XGI_SCRATCH_REG_CR32 0x32
+#define IND_XGI_SCRATCH_REG_CR33 0x33
+#define IND_XGI_LCD_PANEL 0x36
+#define IND_XGI_SCRATCH_REG_CR37 0x37
+
+#define XGI_DRAM_SIZE_MASK 0xF0 /*SR14 */
+#define XGI_DRAM_SIZE_1MB 0x00
+#define XGI_DRAM_SIZE_2MB 0x01
+#define XGI_DRAM_SIZE_4MB 0x02
+#define XGI_DRAM_SIZE_8MB 0x03
+#define XGI_DRAM_SIZE_16MB 0x04
+#define XGI_DRAM_SIZE_32MB 0x05
+#define XGI_DRAM_SIZE_64MB 0x06
+#define XGI_DRAM_SIZE_128MB 0x07
+#define XGI_DRAM_SIZE_256MB 0x08
+
+/* ------------------- Global Variables ----------------------------- */
+
+/* display status */
+static int XGIfb_crt1off;
+static int XGIfb_forcecrt1 = -1;
+
+/* global flags */
+#if IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT)
+static int XGIfb_tvmode;
+#endif
+static int enable_dstn;
+// static int XGIfb_ypan = -1;
+
+/* TW: CRT2 type (for overriding autodetection) */
+static int XGIfb_crt2type = -1;
+/* PR: Tv plug type (for overriding autodetection) */
+static int XGIfb_tvplug = -1;
+
+#define MD_XGI315 1
+
+/* mode table */
+static const struct _XGIbios_mode {
+ u8 mode_no;
+ u16 vesa_mode_no_1; /* "XGI defined" VESA mode number */
+ u16 vesa_mode_no_2; /* Real VESA mode numbers */
+ u16 xres;
+ u16 yres;
+ u16 bpp;
+ u8 chipset;
+} XGIbios_mode[] = {
+ { 0x56, 0x0000, 0x0000, 320, 240, 16, MD_XGI315 },
+ { 0x5A, 0x0000, 0x0000, 320, 480, 8, MD_XGI315 },
+ { 0x5B, 0x0000, 0x0000, 320, 480, 16, MD_XGI315 },
+ { 0x2E, 0x0101, 0x0101, 640, 480, 8, MD_XGI315 },
+ { 0x44, 0x0111, 0x0111, 640, 480, 16, MD_XGI315 },
+ { 0x62, 0x013a, 0x0112, 640, 480, 32, MD_XGI315 },
+ { 0x31, 0x0000, 0x0000, 720, 480, 8, MD_XGI315 },
+ { 0x33, 0x0000, 0x0000, 720, 480, 16, MD_XGI315 },
+ { 0x35, 0x0000, 0x0000, 720, 480, 32, MD_XGI315 },
+ { 0x32, 0x0000, 0x0000, 720, 576, 8, MD_XGI315 },
+ { 0x34, 0x0000, 0x0000, 720, 576, 16, MD_XGI315 },
+ { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 },
+ { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 },
+ { 0x70, 0x0000, 0x0000, 800, 480, 8, MD_XGI315 },
+ { 0x7a, 0x0000, 0x0000, 800, 480, 16, MD_XGI315 },
+ { 0x76, 0x0000, 0x0000, 800, 480, 32, MD_XGI315 },
+ { 0x30, 0x0103, 0x0103, 800, 600, 8, MD_XGI315 },
+#define DEFAULT_MODE 17 /* index for 800x600x16 */
+ { 0x47, 0x0114, 0x0114, 800, 600, 16, MD_XGI315 },
+ { 0x63, 0x013b, 0x0115, 800, 600, 32, MD_XGI315 },
+ { 0x71, 0x0000, 0x0000, 1024, 576, 8, MD_XGI315 },
+ { 0x74, 0x0000, 0x0000, 1024, 576, 16, MD_XGI315 },
+ { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 },
+ { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 },
+ { 0x20, 0x0000, 0x0000, 1024, 600, 8, },
+ { 0x21, 0x0000, 0x0000, 1024, 600, 16, },
+ { 0x22, 0x0000, 0x0000, 1024, 600, 32, },
+ { 0x38, 0x0105, 0x0105, 1024, 768, 8, MD_XGI315 },
+ { 0x4A, 0x0117, 0x0117, 1024, 768, 16, MD_XGI315 },
+ { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 },
+ { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 },
+ { 0x23, 0x0000, 0x0000, 1152, 768, 8, },
+ { 0x24, 0x0000, 0x0000, 1152, 768, 16, },
+ { 0x25, 0x0000, 0x0000, 1152, 768, 32, },
+ { 0x79, 0x0000, 0x0000, 1280, 720, 8, MD_XGI315 },
+ { 0x75, 0x0000, 0x0000, 1280, 720, 16, MD_XGI315 },
+ { 0x78, 0x0000, 0x0000, 1280, 720, 32, MD_XGI315 },
+ { 0x23, 0x0000, 0x0000, 1280, 768, 8, MD_XGI315 },
+ { 0x24, 0x0000, 0x0000, 1280, 768, 16, MD_XGI315 },
+ { 0x25, 0x0000, 0x0000, 1280, 768, 32, MD_XGI315 },
+ { 0x7C, 0x0000, 0x0000, 1280, 960, 8, MD_XGI315 },
+ { 0x7D, 0x0000, 0x0000, 1280, 960, 16, MD_XGI315 },
+ { 0x7E, 0x0000, 0x0000, 1280, 960, 32, MD_XGI315 },
+ { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, MD_XGI315 },
+ { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, MD_XGI315 },
+ { 0x65, 0x013d, 0x011b, 1280, 1024, 32, MD_XGI315 },
+ { 0x26, 0x0000, 0x0000, 1400, 1050, 8, MD_XGI315 },
+ { 0x27, 0x0000, 0x0000, 1400, 1050, 16, MD_XGI315 },
+ { 0x28, 0x0000, 0x0000, 1400, 1050, 32, MD_XGI315 },
+ { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, MD_XGI315 },
+ { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, MD_XGI315 },
+ { 0x66, 0x013e, 0x011f, 1600, 1200, 32, MD_XGI315 },
+ { 0x68, 0x013f, 0x0000, 1920, 1440, 8, MD_XGI315 },
+ { 0x69, 0x0140, 0x0000, 1920, 1440, 16, MD_XGI315 },
+ { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, MD_XGI315 },
+ { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, MD_XGI315 },
+ { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, MD_XGI315 },
+ { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, MD_XGI315 },
+ { 0 },
+};
+
+static const unsigned short XGI310paneltype[] = {
+ LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
+ LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
+ LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
+ LCD_1024x768, LCD_1024x768, LCD_1024x768};
+
+static const struct _XGI_crt2type {
+ char name[10];
+ int type_no;
+ int tvplug_no;
+} XGI_crt2type[] = {
+ {"NONE", 0, -1},
+ {"LCD", XGIFB_DISP_LCD, -1},
+ {"TV", XGIFB_DISP_TV, -1},
+ {"VGA", XGIFB_DISP_CRT, -1},
+ {"SVIDEO", XGIFB_DISP_TV, TVPLUG_SVIDEO},
+ {"COMPOSITE", XGIFB_DISP_TV, TVPLUG_COMPOSITE},
+ {"SCART", XGIFB_DISP_TV, TVPLUG_SCART},
+ {"none", 0, -1},
+ {"lcd", XGIFB_DISP_LCD, -1},
+ {"tv", XGIFB_DISP_TV, -1},
+ {"vga", XGIFB_DISP_CRT, -1},
+ {"svideo", XGIFB_DISP_TV, TVPLUG_SVIDEO},
+ {"composite", XGIFB_DISP_TV, TVPLUG_COMPOSITE},
+ {"scart", XGIFB_DISP_TV, TVPLUG_SCART},
+ {"\0", -1, -1}
+};
+
+/* TV standard */
+static const struct _XGI_tvtype {
+ char name[6];
+ int type_no;
+} XGI_tvtype[] = {
+ {"PAL", 1},
+ {"NTSC", 2},
+ {"pal", 1},
+ {"ntsc", 2},
+ {"\0", -1}
+};
+
+static const struct _XGI_vrate {
+ u16 idx;
+ u16 xres;
+ u16 yres;
+ u16 refresh;
+} XGIfb_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, 58},
+ {1, 800, 480, 60}, {2, 800, 480, 75}, {3, 800, 480, 85},
+ {1, 800, 600, 60}, {2, 800, 600, 72}, {3, 800, 600, 75},
+ {4, 800, 600, 85}, {5, 800, 600, 100},
+ {6, 800, 600, 120}, {7, 800, 600, 160},
+
+ {1, 1024, 768, 60}, {2, 1024, 768, 70}, {3, 1024, 768, 75},
+ {4, 1024, 768, 85}, {5, 1024, 768, 100}, {6, 1024, 768, 120},
+ {1, 1024, 576, 60}, {2, 1024, 576, 75}, {3, 1024, 576, 85},
+ {1, 1024, 600, 60},
+ {1, 1152, 768, 60},
+ {1, 1280, 720, 60}, {2, 1280, 720, 75}, {3, 1280, 720, 85},
+ {1, 1280, 768, 60},
+ {1, 1280, 1024, 60}, {2, 1280, 1024, 75}, {3, 1280, 1024, 85},
+ {1, 1280, 960, 70},
+ {1, 1400, 1050, 60},
+ {1, 1600, 1200, 60}, {2, 1600, 1200, 65},
+ {3, 1600, 1200, 70}, {4, 1600, 1200, 75},
+
+ {5, 1600, 1200, 85}, {6, 1600, 1200, 100},
+ {7, 1600, 1200, 120},
+
+ {1, 1920, 1440, 60}, {2, 1920, 1440, 65},
+ {3, 1920, 1440, 70}, {4, 1920, 1440, 75},
+
+ {5, 1920, 1440, 85}, {6, 1920, 1440, 100},
+ {1, 2048, 1536, 60}, {2, 2048, 1536, 65},
+ {3, 2048, 1536, 70}, {4, 2048, 1536, 75},
+
+ {5, 2048, 1536, 85},
+ {0, 0, 0, 0}
+};
+
+static const struct _XGI_TV_filter {
+ u8 filter[9][4];
+} XGI_TV_filter[] = {
+ { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_0 */
+ {0x00, 0xE0, 0x10, 0x60},
+ {0x00, 0xEE, 0x10, 0x44},
+ {0x00, 0xF4, 0x10, 0x38},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xFC, 0xFB, 0x14, 0x2A},
+ {0x00, 0x00, 0x10, 0x20},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_1 */
+ {0x00, 0xE0, 0x10, 0x60},
+ {0x00, 0xEE, 0x10, 0x44},
+ {0x00, 0xF4, 0x10, 0x38},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xFC, 0xFB, 0x14, 0x2A},
+ {0x00, 0x00, 0x10, 0x20},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_2 */
+ {0xF5, 0xEE, 0x1B, 0x44},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xEB, 0x04, 0x25, 0x18},
+ {0xF1, 0x05, 0x1F, 0x16},
+ {0xF6, 0x06, 0x1A, 0x14},
+ {0xFA, 0x06, 0x16, 0x14},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_3 */
+ {0xF1, 0x04, 0x1F, 0x18},
+ {0xEE, 0x0D, 0x22, 0x06},
+ {0xF7, 0x06, 0x19, 0x14},
+ {0xF4, 0x0B, 0x1C, 0x0A},
+ {0xFA, 0x07, 0x16, 0x12},
+ {0xF9, 0x0A, 0x17, 0x0C},
+ {0x00, 0x07, 0x10, 0x12},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_4 */
+ {0x00, 0xE0, 0x10, 0x60},
+ {0x00, 0xEE, 0x10, 0x44},
+ {0x00, 0xF4, 0x10, 0x38},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xFC, 0xFB, 0x14, 0x2A},
+ {0x00, 0x00, 0x10, 0x20},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_5 */
+ {0xF5, 0xEE, 0x1B, 0x44},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xEB, 0x04, 0x25, 0x18},
+ {0xF1, 0x05, 0x1F, 0x16},
+ {0xF6, 0x06, 0x1A, 0x14},
+ {0xFA, 0x06, 0x16, 0x14},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_6 */
+ {0xEB, 0x04, 0x25, 0x18},
+ {0xE7, 0x0E, 0x29, 0x04},
+ {0xEE, 0x0C, 0x22, 0x08},
+ {0xF6, 0x0B, 0x1A, 0x0A},
+ {0xF9, 0x0A, 0x17, 0x0C},
+ {0xFC, 0x0A, 0x14, 0x0C},
+ {0x00, 0x08, 0x10, 0x10},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* NTSCFilter_7 */
+ {0xEC, 0x02, 0x24, 0x1C},
+ {0xF2, 0x04, 0x1E, 0x18},
+ {0xEB, 0x15, 0x25, 0xF6},
+ {0xF4, 0x10, 0x1C, 0x00},
+ {0xF8, 0x0F, 0x18, 0x02},
+ {0x00, 0x04, 0x10, 0x18},
+ {0x01, 0x06, 0x0F, 0x14},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_0 */
+ {0x00, 0xE0, 0x10, 0x60},
+ {0x00, 0xEE, 0x10, 0x44},
+ {0x00, 0xF4, 0x10, 0x38},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xFC, 0xFB, 0x14, 0x2A},
+ {0x00, 0x00, 0x10, 0x20},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_1 */
+ {0x00, 0xE0, 0x10, 0x60},
+ {0x00, 0xEE, 0x10, 0x44},
+ {0x00, 0xF4, 0x10, 0x38},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xFC, 0xFB, 0x14, 0x2A},
+ {0x00, 0x00, 0x10, 0x20},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_2 */
+ {0xF5, 0xEE, 0x1B, 0x44},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xF1, 0xF7, 0x01, 0x32},
+ {0xF5, 0xFB, 0x1B, 0x2A},
+ {0xF9, 0xFF, 0x17, 0x22},
+ {0xFB, 0x01, 0x15, 0x1E},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_3 */
+ {0xF5, 0xFB, 0x1B, 0x2A},
+ {0xEE, 0xFE, 0x22, 0x24},
+ {0xF3, 0x00, 0x1D, 0x20},
+ {0xF9, 0x03, 0x17, 0x1A},
+ {0xFB, 0x02, 0x14, 0x1E},
+ {0xFB, 0x04, 0x15, 0x18},
+ {0x00, 0x06, 0x10, 0x14},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_4 */
+ {0x00, 0xE0, 0x10, 0x60},
+ {0x00, 0xEE, 0x10, 0x44},
+ {0x00, 0xF4, 0x10, 0x38},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xFC, 0xFB, 0x14, 0x2A},
+ {0x00, 0x00, 0x10, 0x20},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_5 */
+ {0xF5, 0xEE, 0x1B, 0x44},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xF1, 0xF7, 0x1F, 0x32},
+ {0xF5, 0xFB, 0x1B, 0x2A},
+ {0xF9, 0xFF, 0x17, 0x22},
+ {0xFB, 0x01, 0x15, 0x1E},
+ {0x00, 0x04, 0x10, 0x18},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_6 */
+ {0xF5, 0xEE, 0x1B, 0x2A},
+ {0xEE, 0xFE, 0x22, 0x24},
+ {0xF3, 0x00, 0x1D, 0x20},
+ {0xF9, 0x03, 0x17, 0x1A},
+ {0xFB, 0x02, 0x14, 0x1E},
+ {0xFB, 0x04, 0x15, 0x18},
+ {0x00, 0x06, 0x10, 0x14},
+ {0xFF, 0xFF, 0xFF, 0xFF} } },
+ { { {0x00, 0x00, 0x00, 0x40}, /* PALFilter_7 */
+ {0xF5, 0xEE, 0x1B, 0x44},
+ {0xF8, 0xF4, 0x18, 0x38},
+ {0xFC, 0xFB, 0x14, 0x2A},
+ {0xEB, 0x05, 0x25, 0x16},
+ {0xF1, 0x05, 0x1F, 0x16},
+ {0xFA, 0x07, 0x16, 0x12},
+ {0x00, 0x07, 0x10, 0x12},
+ {0xFF, 0xFF, 0xFF, 0xFF} } }
+};
+
+#if IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT)
+static int filter = -1;
+#endif
+
+#endif
diff --git a/src/drivers/xgi/common/XGIfb.h b/src/drivers/xgi/common/XGIfb.h
new file mode 100644
index 0000000000..f05adc74e1
--- /dev/null
+++ b/src/drivers/xgi/common/XGIfb.h
@@ -0,0 +1,153 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken verbatim from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _LINUX_XGIFB
+#define _LINUX_XGIFB
+#include "vgatypes.h"
+#include "vb_struct.h"
+
+enum xgifb_display_type {
+ XGIFB_DISP_NONE = 0,
+ XGIFB_DISP_CRT,
+ XGIFB_DISP_LCD,
+ XGIFB_DISP_TV,
+};
+
+#define HASVB_NONE 0x00
+#define HASVB_301 0x01
+#define HASVB_LVDS 0x02
+#define HASVB_TRUMPION 0x04
+#define HASVB_LVDS_CHRONTEL 0x10
+#define HASVB_302 0x20
+#define HASVB_CHRONTEL 0x80
+
+enum XGI_CHIP_TYPE {
+ XG40 = 32,
+ XG42,
+ XG20 = 48,
+ XG21,
+ XG27,
+};
+
+enum xgi_tvtype {
+ TVMODE_NTSC = 0,
+ TVMODE_PAL,
+ TVMODE_HIVISION,
+ TVTYPE_PALM,
+ TVTYPE_PALN,
+ TVTYPE_NTSCJ,
+ TVMODE_TOTAL
+};
+
+enum xgi_tv_plug {
+ TVPLUG_UNKNOWN = 0,
+ TVPLUG_COMPOSITE = 1,
+ TVPLUG_SVIDEO = 2,
+ TVPLUG_COMPOSITE_AND_SVIDEO = 3,
+ TVPLUG_SCART = 4,
+ TVPLUG_YPBPR_525i = 5,
+ TVPLUG_YPBPR_525P = 6,
+ TVPLUG_YPBPR_750P = 7,
+ TVPLUG_YPBPR_1080i = 8,
+ TVPLUG_TOTAL
+};
+
+struct XGIfb_info {
+ unsigned long XGIfb_id;
+ int chip_id; /* PCI ID of detected chip */
+ int memory; /* video memory in KB which XGIfb manages */
+ int heapstart; /* heap start (= XGIfb "mem" argument) in KB */
+ unsigned char fbvidmode; /* current XGIfb mode */
+
+ unsigned char XGIfb_version;
+ unsigned char XGIfb_revision;
+ unsigned char XGIfb_patchlevel;
+
+ unsigned char XGIfb_caps; /* XGIfb capabilities */
+
+ int XGIfb_tqlen; /* turbo queue length (in KB) */
+
+ unsigned int XGIfb_pcibus; /* The card's PCI ID */
+ unsigned int XGIfb_pcislot;
+ unsigned int XGIfb_pcifunc;
+
+ unsigned char XGIfb_lcdpdc; /* PanelDelayCompensation */
+
+ unsigned char XGIfb_lcda; /* Detected status of LCDA for low res/text modes */
+
+ char reserved[235]; /* for future use */
+};
+
+struct xgifb_video_info {
+ struct fb_info *fb_info;
+ struct xgi_hw_device_info hw_info;
+ struct vb_device_info dev_info;
+
+ int mode_idx;
+ int rate_idx;
+
+ u32 pseudo_palette[17];
+
+ int chip_id;
+ unsigned int video_size;
+ phys_addr_t video_base;
+ void __iomem *video_vbase;
+ phys_addr_t mmio_base;
+ unsigned long mmio_size;
+ void __iomem *mmio_vbase;
+ unsigned long vga_base;
+ int mtrr;
+
+ int video_bpp;
+ int video_cmap_len;
+ int video_width;
+ int video_height;
+ int video_vwidth;
+ int video_vheight;
+ int org_x;
+ int org_y;
+ int video_linelength;
+ unsigned int refresh_rate;
+
+ enum xgifb_display_type display2; /* the second display output type */
+ bool display2_force;
+ unsigned char hasVB;
+ unsigned char TV_type;
+ unsigned char TV_plug;
+
+ struct XGI21_LVDSCapStruct lvds_data;
+
+ enum XGI_CHIP_TYPE chip;
+ unsigned char revision_id;
+
+ unsigned short DstColor;
+ unsigned long XGI310_AccelDepth;
+ unsigned long CommandReg;
+
+ unsigned int pcibus;
+ unsigned int pcislot;
+ unsigned int pcifunc;
+
+ unsigned short subsysvendor;
+ unsigned short subsysdevice;
+
+ char reserved[236];
+};
+
+#endif
diff --git a/src/drivers/xgi/common/initdef.h b/src/drivers/xgi/common/initdef.h
new file mode 100644
index 0000000000..264b55a594
--- /dev/null
+++ b/src/drivers/xgi/common/initdef.h
@@ -0,0 +1,708 @@
+/* $XFree86$ */
+/* $XdotOrg$ */
+/*
+ * Global definitions for init.c and init301.c
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) 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.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _INITDEF_
+#define _INITDEF_
+
+#define IS_SIS330 (SiS_Pr->ChipType == SIS_330)
+#define IS_SIS550 (SiS_Pr->ChipType == SIS_550)
+#define IS_SIS650 (SiS_Pr->ChipType == SIS_650) /* All versions, incl 651, M65x */
+#define IS_SIS740 (SiS_Pr->ChipType == SIS_740)
+#define IS_SIS651 (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
+#define IS_SISM650 (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
+#define IS_SIS65x (IS_SIS651 || IS_SISM650) /* Only special versions of 65x */
+#define IS_SIS661 (SiS_Pr->ChipType == SIS_661)
+#define IS_SIS741 (SiS_Pr->ChipType == SIS_741)
+#define IS_SIS660 (SiS_Pr->ChipType == SIS_660)
+#define IS_SIS760 (SiS_Pr->ChipType == SIS_760)
+#define IS_SIS761 (SiS_Pr->ChipType == SIS_761)
+#define IS_SIS661741660760 (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760 || IS_SIS761)
+#define IS_SIS650740 ((SiS_Pr->ChipType >= SIS_650) && (SiS_Pr->ChipType < SIS_330))
+#define IS_SIS550650740 (IS_SIS550 || IS_SIS650740)
+#define IS_SIS650740660 (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
+#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650740660)
+
+#define SISGETROMW(x) (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8))
+
+/* SiS_VBType */
+#define VB_SIS301 0x0001
+#define VB_SIS301B 0x0002
+#define VB_SIS302B 0x0004
+#define VB_SIS301LV 0x0008
+#define VB_SIS302LV 0x0010
+#define VB_SIS302ELV 0x0020
+#define VB_SIS301C 0x0040
+#define VB_SIS307T 0x0080
+#define VB_SIS307LV 0x0100
+#define VB_UMC 0x4000
+#define VB_NoLCD 0x8000
+#define VB_SIS30xB (VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
+#define VB_SIS30xC (VB_SIS301C | VB_SIS307T)
+#define VB_SISTMDS (VB_SIS301 | VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
+#define VB_SISLVDS (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SIS30xBLV (VB_SIS30xB | VB_SISLVDS)
+#define VB_SIS30xCLV (VB_SIS30xC | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISVB (VB_SIS301 | VB_SIS30xBLV)
+#define VB_SISLCDA (VB_SIS302B | VB_SIS301C | VB_SIS307T | VB_SISLVDS)
+#define VB_SISTMDSLCDA (VB_SIS301C | VB_SIS307T)
+#define VB_SISPART4SCALER (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISHIVISION (VB_SIS301 | VB_SIS301B | VB_SIS302B)
+#define VB_SISYPBPR (VB_SIS301C | VB_SIS307T | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISTAP4SCALER (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPART4OVERFLOW (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPWD (VB_SIS301C | VB_SIS307T | VB_SISLVDS)
+#define VB_SISEMI (VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPOWER (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISDUALLINK (VB_SIS302LV | VB_SIS302ELV | VB_SIS307T | VB_SIS307LV)
+#define VB_SISVGA2 VB_SISTMDS
+#define VB_SISRAMDAC202 (VB_SIS301C | VB_SIS307T)
+
+/* VBInfo */
+#define SetSimuScanMode 0x0001 /* CR 30 */
+#define SwitchCRT2 0x0002
+#define SetCRT2ToAVIDEO 0x0004
+#define SetCRT2ToSVIDEO 0x0008
+#define SetCRT2ToSCART 0x0010
+#define SetCRT2ToLCD 0x0020
+#define SetCRT2ToRAMDAC 0x0040
+#define SetCRT2ToHiVision 0x0080 /* for SiS bridge */
+#define SetCRT2ToCHYPbPr SetCRT2ToHiVision /* for Chrontel */
+#define SetNTSCTV 0x0000 /* CR 31 */
+#define SetPALTV 0x0100 /* Deprecated here, now in TVMode */
+#define SetInSlaveMode 0x0200
+#define SetNotSimuMode 0x0400
+#define SetNotSimuTVMode SetNotSimuMode
+#define SetDispDevSwitch 0x0800
+#define SetCRT2ToYPbPr525750 0x0800
+#define LoadDACFlag 0x1000
+#define DisableCRT2Display 0x2000
+#define DriverMode 0x4000
+#define HotKeySwitch 0x8000
+#define SetCRT2ToLCDA 0x8000
+
+/* v-- Needs change in sis_vga.c if changed (GPIO) --v */
+#define SetCRT2ToTV (SetCRT2ToYPbPr525750|SetCRT2ToHiVision|SetCRT2ToSCART|SetCRT2ToSVIDEO|SetCRT2ToAVIDEO)
+#define SetCRT2ToTVNoYPbPrHiVision (SetCRT2ToSCART | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)
+#define SetCRT2ToTVNoHiVision (SetCRT2ToYPbPr525750 | SetCRT2ToSCART | SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)
+
+/* SiS_ModeType */
+#define ModeText 0x00
+#define ModeCGA 0x01
+#define ModeEGA 0x02
+#define ModeVGA 0x03
+#define Mode15Bpp 0x04
+#define Mode16Bpp 0x05
+#define Mode24Bpp 0x06
+#define Mode32Bpp 0x07
+
+#define ModeTypeMask 0x07
+#define IsTextMode 0x07
+
+#define DACInfoFlag 0x0018
+#define MemoryInfoFlag 0x01E0
+#define MemorySizeShift 5
+
+/* modeflag */
+#define Charx8Dot 0x0200
+#define LineCompareOff 0x0400
+#define CRT2Mode 0x0800
+#define HalfDCLK 0x1000
+#define NoSupportSimuTV 0x2000
+#define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */
+#define DoubleScanMode 0x8000
+
+/* Infoflag */
+#define SupportTV 0x0008
+#define SupportTV1024 0x0800
+#define SupportCHTV 0x0800
+#define Support64048060Hz 0x0800 /* Special for 640x480 LCD */
+#define SupportHiVision 0x0010
+#define SupportYPbPr750p 0x1000
+#define SupportLCD 0x0020
+#define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */
+#define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */
+#define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */
+#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */
+#define InterlaceMode 0x0080
+#define SyncPP 0x0000
+#define HaveWideTiming 0x2000 /* Have specific wide- and non-wide timing */
+#define SyncPN 0x4000
+#define SyncNP 0x8000
+#define SyncNN 0xc000
+
+/* SetFlag */
+#define ProgrammingCRT2 0x0001
+#define LowModeTests 0x0002
+/* #define TVSimuMode 0x0002 - deprecated */
+/* #define RPLLDIV2XO 0x0004 - deprecated */
+#define LCDVESATiming 0x0008
+#define EnableLVDSDDA 0x0010
+#define SetDispDevSwitchFlag 0x0020
+#define CheckWinDos 0x0040
+#define SetDOSMode 0x0080
+
+/* TVMode flag */
+#define TVSetPAL 0x0001
+#define TVSetNTSCJ 0x0002
+#define TVSetPALM 0x0004
+#define TVSetPALN 0x0008
+#define TVSetCHOverScan 0x0010
+#define TVSetYPbPr525i 0x0020 /* new 0x10 */
+#define TVSetYPbPr525p 0x0040 /* new 0x20 */
+#define TVSetYPbPr750p 0x0080 /* new 0x40 */
+#define TVSetHiVision 0x0100 /* new 0x80; = 1080i, software-wise identical */
+#define TVSetTVSimuMode 0x0200 /* new 0x200, prev. 0x800 */
+#define TVRPLLDIV2XO 0x0400 /* prev 0x1000 */
+#define TVSetNTSC1024 0x0800 /* new 0x100, prev. 0x2000 */
+#define TVSet525p1024 0x1000 /* TW */
+#define TVAspect43 0x2000
+#define TVAspect169 0x4000
+#define TVAspect43LB 0x8000
+
+/* YPbPr flag (>=315, <661; converted to TVMode) */
+#define YPbPr525p 0x0001
+#define YPbPr750p 0x0002
+#define YPbPr525i 0x0004
+#define YPbPrHiVision 0x0008
+#define YPbPrModeMask (YPbPr750p | YPbPr525p | YPbPr525i | YPbPrHiVision)
+
+/* SysFlags (to identify special versions) */
+#define SF_Is651 0x0001
+#define SF_IsM650 0x0002
+#define SF_Is652 0x0004
+#define SF_IsM652 0x0008
+#define SF_IsM653 0x0010
+#define SF_IsM661 0x0020
+#define SF_IsM741 0x0040
+#define SF_IsM760 0x0080
+#define SF_760UMA 0x4000 /* 76x: We have UMA */
+#define SF_760LFB 0x8000 /* 76x: We have LFB */
+
+/* CR32 (Newer 630, and 315 series)
+
+ [0] VB connected with CVBS
+ [1] VB connected with SVHS
+ [2] VB connected with SCART
+ [3] VB connected with LCD
+ [4] VB connected with CRT2 (secondary VGA)
+ [5] CRT1 monitor is connected
+ [6] VB connected with Hi-Vision TV
+ [7] <= 330: VB connected with DVI combo connector
+ >= 661: VB connected to YPbPr
+*/
+
+/* CR35 (300 series only) */
+#define TVOverScan 0x10
+#define TVOverScanShift 4
+
+/* CR35 (661 series only)
+ [0] 1 = PAL, 0 = NTSC
+ [1] 1 = NTSC-J (if D0 = 0)
+ [2] 1 = PALM (if D0 = 1)
+ [3] 1 = PALN (if D0 = 1)
+ [4] 1 = Overscan (Chrontel only)
+ [7:5] (only if D2 in CR38 is set)
+ 000 525i
+ 001 525p
+ 010 750p
+ 011 1080i (or HiVision on 301, 301B)
+*/
+
+/* CR37
+ [0] Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
+ [3:1] External chip
+ 300 series:
+ 001 SiS301 (never seen)
+ 010 LVDS
+ 011 LVDS + Tumpion Zurac
+ 100 LVDS + Chrontel 7005
+ 110 Chrontel 7005
+ 315/330 series
+ 001 SiS30x (never seen)
+ 010 LVDS
+ 011 LVDS + Chrontel 7019
+ 660 series [2:1] only:
+ reserved (chip type now in CR38)
+ All other combinations reserved
+ [3] 661 only: Pass 1:1 data
+ [4] LVDS: 0: Panel Link expands / 1: Panel Link does not expand
+ 30x: 0: Bridge scales / 1: Bridge does not scale = Panel scales (if possible)
+ [5] LCD polarity select
+ 0: VESA DMT Standard
+ 1: EDID 2.x defined
+ [6] LCD horizontal polarity select
+ 0: High active
+ 1: Low active
+ [7] LCD vertical polarity select
+ 0: High active
+ 1: Low active
+*/
+
+/* CR37: LCDInfo */
+#define LCDRGB18Bit 0x0001
+#define LCDNonExpanding 0x0010
+#define LCDSync 0x0020
+#define LCDPass11 0x0100 /* 0: center screen, 1: Pass 1:1 data */
+#define LCDDualLink 0x0200
+
+#define DontExpandLCD LCDNonExpanding
+#define LCDNonExpandingShift 4
+#define DontExpandLCDShift LCDNonExpandingShift
+#define LCDSyncBit 0x00e0
+#define LCDSyncShift 6
+
+/* CR38 (315 series) */
+#define EnableDualEdge 0x01
+#define SetToLCDA 0x02 /* LCD channel A (301C/302B/30x(E)LV and 650+LVDS only) */
+#define EnableCHScart 0x04 /* Scart on Ch7019 (unofficial definition - TW) */
+#define EnableCHYPbPr 0x08 /* YPbPr on Ch7019 (480i HDTV); only on 650/Ch7019 systems */
+#define EnableSiSYPbPr 0x08 /* Enable YPbPr mode (30xLV/301C only) */
+#define EnableYPbPr525i 0x00 /* Enable 525i YPbPr mode (30xLV/301C only) (mask 0x30) */
+#define EnableYPbPr525p 0x10 /* Enable 525p YPbPr mode (30xLV/301C only) (mask 0x30) */
+#define EnableYPbPr750p 0x20 /* Enable 750p YPbPr mode (30xLV/301C only) (mask 0x30) */
+#define EnableYPbPr1080i 0x30 /* Enable 1080i YPbPr mode (30xLV/301C only) (mask 0x30) */
+#define EnablePALM 0x40 /* 1 = Set PALM */
+#define EnablePALN 0x80 /* 1 = Set PALN */
+#define EnableNTSCJ EnablePALM /* Not BIOS */
+
+/* CR38 (661 and later)
+ D[7:5] 000 No VB
+ 001 301 series VB
+ 010 LVDS
+ 011 Chrontel 7019
+ 100 Conexant
+ D2 Enable YPbPr output (see CR35)
+ D[1:0] LCDA (like before)
+*/
+
+#define EnablePALMN 0x40 /* Romflag: 1 = Allow PALM/PALN */
+
+/* CR39 (650 only) */
+#define LCDPass1_1 0x01 /* 0: center screen, 1: pass 1:1 data output */
+#define Enable302LV_DualLink 0x04 /* 302LV only; enable dual link */
+
+/* CR39 (661 and later)
+ D[7] LVDS (SiS or third party)
+ D[1:0] YPbPr Aspect Ratio
+ 00 4:3 letterbox
+ 01 4:3
+ 10 16:9
+ 11 4:3
+*/
+
+/* CR3B (651+301C)
+ D[1:0] YPbPr Aspect Ratio
+ ?
+*/
+
+/* CR79 (315/330 series only; not 661 and later)
+ [3-0] Notify driver
+ 0001 Mode Switch event (set by BIOS)
+ 0010 Epansion On/Off event
+ 0011 TV UnderScan/OverScan event
+ 0100 Set Brightness event
+ 0101 Set Contrast event
+ 0110 Set Mute event
+ 0111 Set Volume Up/Down event
+ [4] Enable Backlight Control by BIOS/driver
+ (set by driver; set means that the BIOS should
+ not touch the backlight registers because eg.
+ the driver already switched off the backlight)
+ [5] PAL/NTSC (set by BIOS)
+ [6] Expansion On/Off (set by BIOS; copied to CR32[4])
+ [7] TV UnderScan/OverScan (set by BIOS)
+*/
+
+/* CR7C - 661 and later
+ [7] DualEdge enabled (or: to be enabled)
+ [6] CRT2 = TV/LCD/VGA enabled (or: to be enabled)
+ [5] Init done (set at end of SiS_Init)
+ {4] LVDS LCD capabilities
+ [3] LVDS LCD capabilities
+ [2] LVDS LCD capabilities (PWD)
+ [1] LVDS LCD capabilities (PWD)
+ [0] LVDS=1, TMDS=0 (SiS or third party)
+*/
+
+/* CR7E - 661 and later
+ VBType:
+ [7] LVDS (third party)
+ [3] 301C
+ [2] 302LV
+ [1] 301LV
+ [0] 301B
+*/
+
+/* LCDResInfo */
+#define Panel300_800x600 0x01 /* CR36 */
+#define Panel300_1024x768 0x02
+#define Panel300_1280x1024 0x03
+#define Panel300_1280x960 0x04
+#define Panel300_640x480 0x05
+#define Panel300_1024x600 0x06
+#define Panel300_1152x768 0x07
+#define Panel300_1280x768 0x0a
+#define Panel300_Custom 0x0f
+#define Panel300_Barco1366 0x10
+
+#define Panel310_800x600 0x01
+#define Panel310_1024x768 0x02
+#define Panel310_1280x1024 0x03
+#define Panel310_640x480 0x04
+#define Panel310_1024x600 0x05
+#define Panel310_1152x864 0x06
+#define Panel310_1280x960 0x07
+#define Panel310_1152x768 0x08 /* LVDS only */
+#define Panel310_1400x1050 0x09
+#define Panel310_1280x768 0x0a
+#define Panel310_1600x1200 0x0b
+#define Panel310_320x240_2 0x0c /* xSTN */
+#define Panel310_320x240_3 0x0d /* xSTN */
+#define Panel310_320x240_1 0x0e /* xSTN - This is fake, can be any */
+#define Panel310_Custom 0x0f
+
+#define Panel661_800x600 0x01
+#define Panel661_1024x768 0x02
+#define Panel661_1280x1024 0x03
+#define Panel661_640x480 0x04
+#define Panel661_1024x600 0x05
+#define Panel661_1152x864 0x06
+#define Panel661_1280x960 0x07
+#define Panel661_1280x854 0x08
+#define Panel661_1400x1050 0x09
+#define Panel661_1280x768 0x0a
+#define Panel661_1600x1200 0x0b
+#define Panel661_1280x800 0x0c
+#define Panel661_1680x1050 0x0d
+#define Panel661_1280x720 0x0e
+#define Panel661_Custom 0x0f
+
+#define Panel_800x600 0x01 /* Unified values */
+#define Panel_1024x768 0x02 /* MUST match BIOS values from 0-e */
+#define Panel_1280x1024 0x03
+#define Panel_640x480 0x04
+#define Panel_1024x600 0x05
+#define Panel_1152x864 0x06
+#define Panel_1280x960 0x07
+#define Panel_1152x768 0x08 /* LVDS only */
+#define Panel_1400x1050 0x09
+#define Panel_1280x768 0x0a /* 30xB/C and LVDS only (BIOS: all) */
+#define Panel_1600x1200 0x0b
+#define Panel_1280x800 0x0c /* 661etc (TMDS) */
+#define Panel_1680x1050 0x0d /* 661etc */
+#define Panel_1280x720 0x0e /* 661etc */
+#define Panel_Custom 0x0f /* MUST BE 0x0f (for DVI DDC detection) */
+#define Panel_320x240_1 0x10 /* SiS 550 xSTN */
+#define Panel_Barco1366 0x11
+#define Panel_848x480 0x12
+#define Panel_320x240_2 0x13 /* SiS 550 xSTN */
+#define Panel_320x240_3 0x14 /* SiS 550 xSTN */
+#define Panel_1280x768_2 0x15 /* 30xLV */
+#define Panel_1280x768_3 0x16 /* (unused) */
+#define Panel_1280x800_2 0x17 /* 30xLV */
+#define Panel_856x480 0x18
+#define Panel_1280x854 0x19 /* 661etc */
+
+/* Index in ModeResInfo table */
+#define SIS_RI_320x200 0
+#define SIS_RI_320x240 1
+#define SIS_RI_320x400 2
+#define SIS_RI_400x300 3
+#define SIS_RI_512x384 4
+#define SIS_RI_640x400 5
+#define SIS_RI_640x480 6
+#define SIS_RI_800x600 7
+#define SIS_RI_1024x768 8
+#define SIS_RI_1280x1024 9
+#define SIS_RI_1600x1200 10
+#define SIS_RI_1920x1440 11
+#define SIS_RI_2048x1536 12
+#define SIS_RI_720x480 13
+#define SIS_RI_720x576 14
+#define SIS_RI_1280x960 15
+#define SIS_RI_800x480 16
+#define SIS_RI_1024x576 17
+#define SIS_RI_1280x720 18
+#define SIS_RI_856x480 19
+#define SIS_RI_1280x768 20
+#define SIS_RI_1400x1050 21
+#define SIS_RI_1152x864 22 /* Up to here SiS conforming */
+#define SIS_RI_848x480 23
+#define SIS_RI_1360x768 24
+#define SIS_RI_1024x600 25
+#define SIS_RI_1152x768 26
+#define SIS_RI_768x576 27
+#define SIS_RI_1360x1024 28
+#define SIS_RI_1680x1050 29
+#define SIS_RI_1280x800 30
+#define SIS_RI_1920x1080 31
+#define SIS_RI_960x540 32
+#define SIS_RI_960x600 33
+#define SIS_RI_1280x854 34
+
+/* CR5F */
+#define IsM650 0x80
+
+/* Timing data */
+#define NTSCHT 1716
+#define NTSC2HT 1920
+#define NTSCVT 525
+#define PALHT 1728
+#define PALVT 625
+#define StHiTVHT 892
+#define StHiTVVT 1126
+#define StHiTextTVHT 1000
+#define StHiTextTVVT 1126
+#define ExtHiTVHT 2100
+#define ExtHiTVVT 1125
+
+/* Indices in (VB)VCLKData tables */
+
+#define VCLK28 0x00 /* Index in VCLKData table (300 and 315) */
+#define VCLK40 0x04 /* Index in VCLKData table (300 and 315) */
+#define VCLK65_300 0x09 /* Index in VCLKData table (300) */
+#define VCLK108_2_300 0x14 /* Index in VCLKData table (300) */
+#define VCLK81_300 0x3f /* Index in VCLKData table (300) */
+#define VCLK108_3_300 0x42 /* Index in VCLKData table (300) */
+#define VCLK100_300 0x43 /* Index in VCLKData table (300) */
+#define VCLK34_300 0x3d /* Index in VCLKData table (300) */
+#define VCLK_CUSTOM_300 0x47
+
+#define VCLK65_315 0x0b /* Indices in (VB)VCLKData table (315) */
+#define VCLK108_2_315 0x19
+#define VCLK81_315 0x5b
+#define VCLK162_315 0x5e
+#define VCLK108_3_315 0x45
+#define VCLK100_315 0x46
+#define VCLK34_315 0x55
+#define VCLK68_315 0x0d
+#define VCLK_1280x800_315_2 0x5c
+#define VCLK121_315 0x5d
+#define VCLK130_315 0x72
+#define VCLK_1280x720 0x5f
+#define VCLK_1280x768_2 0x60
+#define VCLK_1280x768_3 0x61 /* (unused?) */
+#define VCLK_CUSTOM_315 0x62
+#define VCLK_1280x720_2 0x63
+#define VCLK_720x480 0x67
+#define VCLK_720x576 0x68
+#define VCLK_768x576 0x68
+#define VCLK_848x480 0x65
+#define VCLK_856x480 0x66
+#define VCLK_800x480 0x65
+#define VCLK_1024x576 0x51
+#define VCLK_1152x864 0x64
+#define VCLK_1360x768 0x58
+#define VCLK_1280x800_315 0x6c
+#define VCLK_1280x854 0x76
+
+#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */
+#define TVCLKBASE_315 0x3a /* Indices on TV clocks in (VB)VCLKData table (315) */
+#define TVVCLKDIV2 0x00 /* Index relative to TVCLKBASE */
+#define TVVCLK 0x01 /* Index relative to TVCLKBASE */
+#define HiTVVCLKDIV2 0x02 /* Index relative to TVCLKBASE */
+#define HiTVVCLK 0x03 /* Index relative to TVCLKBASE */
+#define HiTVSimuVCLK 0x04 /* Index relative to TVCLKBASE */
+#define HiTVTextVCLK 0x05 /* Index relative to TVCLKBASE */
+#define YPbPr750pVCLK 0x25 /* Index relative to TVCLKBASE; was 0x0f NOT relative */
+
+/* ------------------------------ */
+
+#define SetSCARTOutput 0x01
+
+#define HotPlugFunction 0x08
+
+#define StStructSize 0x06
+
+#define SIS_VIDEO_CAPTURE 0x00 - 0x30
+#define SIS_VIDEO_PLAYBACK 0x02 - 0x30
+#define SIS_CRT2_PORT_04 0x04 - 0x30
+#define SIS_CRT2_PORT_10 0x10 - 0x30
+#define SIS_CRT2_PORT_12 0x12 - 0x30
+#define SIS_CRT2_PORT_14 0x14 - 0x30
+
+#define ADR_CRT2PtrData 0x20E
+#define offset_Zurac 0x210 /* TW: Trumpion Zurac data pointer */
+#define ADR_LVDSDesPtrData 0x212
+#define ADR_LVDSCRT1DataPtr 0x214
+#define ADR_CHTVVCLKPtr 0x216
+#define ADR_CHTVRegDataPtr 0x218
+
+#define LCDDataLen 8
+#define HiTVDataLen 12
+#define TVDataLen 16
+
+#define LVDSDataLen 6
+#define LVDSDesDataLen 3
+#define ActiveNonExpanding 0x40
+#define ActiveNonExpandingShift 6
+#define ActivePAL 0x20
+#define ActivePALShift 5
+#define ModeSwitchStatus 0x0F
+#define SoftTVType 0x40
+#define SoftSettingAddr 0x52
+#define ModeSettingAddr 0x53
+
+#define _PanelType00 0x00
+#define _PanelType01 0x08
+#define _PanelType02 0x10
+#define _PanelType03 0x18
+#define _PanelType04 0x20
+#define _PanelType05 0x28
+#define _PanelType06 0x30
+#define _PanelType07 0x38
+#define _PanelType08 0x40
+#define _PanelType09 0x48
+#define _PanelType0A 0x50
+#define _PanelType0B 0x58
+#define _PanelType0C 0x60
+#define _PanelType0D 0x68
+#define _PanelType0E 0x70
+#define _PanelType0F 0x78
+
+#define PRIMARY_VGA 0 /* 1: SiS is primary vga 0:SiS is secondary vga */
+
+#define BIOSIDCodeAddr 0x235 /* Offsets to ptrs in BIOS image */
+#define OEMUtilIDCodeAddr 0x237
+#define VBModeIDTableAddr 0x239
+#define OEMTVPtrAddr 0x241
+#define PhaseTableAddr 0x243
+#define NTSCFilterTableAddr 0x245
+#define PALFilterTableAddr 0x247
+#define OEMLCDPtr_1Addr 0x249
+#define OEMLCDPtr_2Addr 0x24B
+#define LCDHPosTable_1Addr 0x24D
+#define LCDHPosTable_2Addr 0x24F
+#define LCDVPosTable_1Addr 0x251
+#define LCDVPosTable_2Addr 0x253
+#define OEMLCDPIDTableAddr 0x255
+
+#define VBModeStructSize 5
+#define PhaseTableSize 4
+#define FilterTableSize 4
+#define LCDHPosTableSize 7
+#define LCDVPosTableSize 5
+#define OEMLVDSPIDTableSize 4
+#define LVDSHPosTableSize 4
+#define LVDSVPosTableSize 6
+
+#define VB_ModeID 0
+#define VB_TVTableIndex 1
+#define VB_LCDTableIndex 2
+#define VB_LCDHIndex 3
+#define VB_LCDVIndex 4
+
+#define OEMLCDEnable 0x0001
+#define OEMLCDDelayEnable 0x0002
+#define OEMLCDPOSEnable 0x0004
+#define OEMTVEnable 0x0100
+#define OEMTVDelayEnable 0x0200
+#define OEMTVFlickerEnable 0x0400
+#define OEMTVPhaseEnable 0x0800
+#define OEMTVFilterEnable 0x1000
+
+#define OEMLCDPanelIDSupport 0x0080
+
+/*
+ =============================================================
+ for 315 series (old data layout)
+ =============================================================
+*/
+#define SoftDRAMType 0x80
+#define SoftSetting_OFFSET 0x52
+#define SR07_OFFSET 0x7C
+#define SR15_OFFSET 0x7D
+#define SR16_OFFSET 0x81
+#define SR17_OFFSET 0x85
+#define SR19_OFFSET 0x8D
+#define SR1F_OFFSET 0x99
+#define SR21_OFFSET 0x9A
+#define SR22_OFFSET 0x9B
+#define SR23_OFFSET 0x9C
+#define SR24_OFFSET 0x9D
+#define SR25_OFFSET 0x9E
+#define SR31_OFFSET 0x9F
+#define SR32_OFFSET 0xA0
+#define SR33_OFFSET 0xA1
+
+#define CR40_OFFSET 0xA2
+#define SR25_1_OFFSET 0xF6
+#define CR49_OFFSET 0xF7
+
+#define VB310Data_1_2_Offset 0xB6
+#define VB310Data_4_D_Offset 0xB7
+#define VB310Data_4_E_Offset 0xB8
+#define VB310Data_4_10_Offset 0xBB
+
+#define RGBSenseDataOffset 0xBD
+#define YCSenseDataOffset 0xBF
+#define VideoSenseDataOffset 0xC1
+#define OutputSelectOffset 0xF3
+
+#define ECLK_MCLK_DISTANCE 0x14
+#define VBIOSTablePointerStart 0x100
+#define StandTablePtrOffset VBIOSTablePointerStart+0x02
+#define EModeIDTablePtrOffset VBIOSTablePointerStart+0x04
+#define CRT1TablePtrOffset VBIOSTablePointerStart+0x06
+#define ScreenOffsetPtrOffset VBIOSTablePointerStart+0x08
+#define VCLKDataPtrOffset VBIOSTablePointerStart+0x0A
+#define MCLKDataPtrOffset VBIOSTablePointerStart+0x0E
+#define CRT2PtrDataPtrOffset VBIOSTablePointerStart+0x10
+#define TVAntiFlickPtrOffset VBIOSTablePointerStart+0x12
+#define TVDelayPtr1Offset VBIOSTablePointerStart+0x14
+#define TVPhaseIncrPtr1Offset VBIOSTablePointerStart+0x16
+#define TVYFilterPtr1Offset VBIOSTablePointerStart+0x18
+#define LCDDelayPtr1Offset VBIOSTablePointerStart+0x20
+#define TVEdgePtr1Offset VBIOSTablePointerStart+0x24
+#define CRT2Delay1Offset VBIOSTablePointerStart+0x28
+
+#endif
diff --git a/src/drivers/xgi/common/vb_def.h b/src/drivers/xgi/common/vb_def.h
new file mode 100644
index 0000000000..2d3075e90f
--- /dev/null
+++ b/src/drivers/xgi/common/vb_def.h
@@ -0,0 +1,276 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken verbatim from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VB_DEF_
+#define _VB_DEF_
+
+#define VB_XGI301C 0x0020 /* for 301C */
+
+#define SupportCRT2in301C 0x0100 /* for 301C */
+#define SetCHTVOverScan 0x8000
+
+#define Panel_320x480 0x07 /*fstn*/
+#define PanelResInfo 0x1F /* CR36 Panel Type/LCDResInfo */
+#define Panel_1024x768x75 0x22
+#define Panel_1280x1024x75 0x23
+
+#define PanelRef60Hz 0x00
+#define PanelRef75Hz 0x20
+
+#define YPbPr525iVCLK 0x03B
+#define YPbPr525iVCLK_2 0x03A
+
+#define XGI_CRT2_PORT_00 (0x00 - 0x030)
+
+#define SupportAllCRT2 0x0078
+#define NoSupportTV 0x0070
+#define NoSupportHiVisionTV 0x0060
+#define NoSupportLCD 0x0058
+
+/* -------------- SetMode Stack/Scratch */
+#define XGI_SetCRT2ToLCDA 0x0100
+#define SetCRT2ToDualEdge 0x8000
+
+#define ReserveTVOption 0x0008
+
+#define SetTVLowResolution 0x0400
+#define TVSimuMode 0x0800
+#define RPLLDIV2XO 0x1000
+#define NTSC1024x768 0x2000
+#define SetTVLockMode 0x4000
+
+#define XGI_LCDVESATiming 0x0001 /* LCD Info/CR37 */
+#define XGI_EnableLVDSDDA 0x0002
+#define EnableScalingLCD 0x0008
+#define SetPWDEnable 0x0004
+#define SetLCDtoNonExpanding 0x0010
+#define SetLCDDualLink 0x0100
+#define SetLCDLowResolution 0x0200
+
+/* LCD Capability shampoo */
+#define DefaultLCDCap 0x80ea
+#define EnableLCD24bpp 0x0004 /* default */
+#define LCDPolarity 0x00c0 /* default: SyncNN */
+#define XGI_LCDDualLink 0x0100
+#define EnableSpectrum 0x0200
+#define PWDEnable 0x0400
+#define EnableVBCLKDRVLOW 0x4000
+#define EnablePLLSPLOW 0x8000
+
+#define AVIDEOSense 0x01 /* CR32 */
+#define SVIDEOSense 0x02
+#define SCARTSense 0x04
+#define LCDSense 0x08
+#define Monitor2Sense 0x10
+#define Monitor1Sense 0x20
+#define HiTVSense 0x40
+
+#define YPbPrSense 0x80 /* NEW SCRATCH */
+
+#define TVSense 0xc7
+
+#define YPbPrMode 0xe0
+#define YPbPrMode525i 0x00
+#define YPbPrMode525p 0x20
+#define YPbPrMode750p 0x40
+#define YPbPrMode1080i 0x60
+
+#define ScalingLCD 0x08
+
+#define SetYPbPr 0x04
+
+/* ---------------------- VUMA Information */
+#define DisplayDeviceFromCMOS 0x10
+
+/* ---------------------- HK Evnet Definition */
+#define XGI_ModeSwitchStatus 0xf0
+#define ActiveCRT1 0x10
+#define ActiveLCD 0x0020
+#define ActiveTV 0x40
+#define ActiveCRT2 0x80
+
+#define ActiveAVideo 0x01
+#define ActiveSVideo 0x02
+#define ActiveSCART 0x04
+#define ActiveHiTV 0x08
+#define ActiveYPbPr 0x10
+
+#define NTSC1024x768HT 1908
+
+#define YPbPrTV525iHT 1716 /* YPbPr */
+#define YPbPrTV525iVT 525
+#define YPbPrTV525pHT 1716
+#define YPbPrTV525pVT 525
+#define YPbPrTV750pHT 1650
+#define YPbPrTV750pVT 750
+
+#define VCLK25_175 0x00
+#define VCLK28_322 0x01
+#define VCLK31_5 0x02
+#define VCLK36 0x03
+#define VCLK43_163 0x05
+#define VCLK44_9 0x06
+#define VCLK49_5 0x07
+#define VCLK50 0x08
+#define VCLK52_406 0x09
+#define VCLK56_25 0x0A
+#define VCLK68_179 0x0D
+#define VCLK72_852 0x0E
+#define VCLK75 0x0F
+#define VCLK78_75 0x11
+#define VCLK79_411 0x12
+#define VCLK83_95 0x13
+#define VCLK86_6 0x15
+#define VCLK94_5 0x16
+#define VCLK113_309 0x1B
+#define VCLK116_406 0x1C
+#define VCLK135_5 0x1E
+#define VCLK139_054 0x1F
+#define VCLK157_5 0x20
+#define VCLK162 0x21
+#define VCLK175 0x22
+#define VCLK189 0x23
+#define VCLK202_5 0x25
+#define VCLK229_5 0x26
+#define VCLK234 0x27
+#define VCLK254_817 0x29
+#define VCLK266_952 0x2B
+#define VCLK269_655 0x2C
+#define VCLK277_015 0x2E
+#define VCLK291_132 0x30
+#define VCLK291_766 0x31
+#define VCLK315_195 0x33
+#define VCLK323_586 0x34
+#define VCLK330_615 0x35
+#define VCLK340_477 0x37
+#define VCLK375_847 0x38
+#define VCLK388_631 0x39
+#define VCLK125_999 0x51
+#define VCLK148_5 0x52
+#define VCLK217_325 0x55
+#define XGI_YPbPr750pVCLK 0x57
+
+#define VCLK39_77 0x40
+#define YPbPr525pVCLK 0x3A
+#define NTSC1024VCLK 0x41
+#define VCLK35_2 0x49 /* ; 800x480 */
+#define VCLK122_61 0x4A
+#define VCLK80_350 0x4B
+#define VCLK107_385 0x4C
+
+#define RES320x200 0x00
+#define RES320x240 0x01
+#define RES400x300 0x02
+#define RES512x384 0x03
+#define RES640x400 0x04
+#define RES640x480x60 0x05
+#define RES640x480x72 0x06
+#define RES640x480x75 0x07
+#define RES640x480x85 0x08
+#define RES640x480x100 0x09
+#define RES640x480x120 0x0A
+#define RES640x480x160 0x0B
+#define RES640x480x200 0x0C
+#define RES800x600x56 0x0D
+#define RES800x600x60 0x0E
+#define RES800x600x72 0x0F
+#define RES800x600x75 0x10
+#define RES800x600x85 0x11
+#define RES800x600x100 0x12
+#define RES800x600x120 0x13
+#define RES800x600x160 0x14
+#define RES1024x768x43 0x15
+#define RES1024x768x60 0x16
+#define RES1024x768x70 0x17
+#define RES1024x768x75 0x18
+#define RES1024x768x85 0x19
+#define RES1024x768x100 0x1A
+#define RES1024x768x120 0x1B
+#define RES1280x1024x43 0x1C
+#define RES1280x1024x60 0x1D
+#define RES1280x1024x75 0x1E
+#define RES1280x1024x85 0x1F
+#define RES1600x1200x60 0x20
+#define RES1600x1200x65 0x21
+#define RES1600x1200x70 0x22
+#define RES1600x1200x75 0x23
+#define RES1600x1200x85 0x24
+#define RES1600x1200x100 0x25
+#define RES1600x1200x120 0x26
+#define RES1920x1440x60 0x27
+#define RES1920x1440x65 0x28
+#define RES1920x1440x70 0x29
+#define RES1920x1440x75 0x2A
+#define RES1920x1440x85 0x2B
+#define RES1920x1440x100 0x2C
+#define RES2048x1536x60 0x2D
+#define RES2048x1536x65 0x2E
+#define RES2048x1536x70 0x2F
+#define RES2048x1536x75 0x30
+#define RES2048x1536x85 0x31
+#define RES800x480x60 0x32
+#define RES800x480x75 0x33
+#define RES800x480x85 0x34
+#define RES1024x576x60 0x35
+#define RES1024x576x75 0x36
+#define RES1024x576x85 0x37
+#define RES1280x720x60 0x38
+#define RES1280x720x75 0x39
+#define RES1280x720x85 0x3A
+#define RES1280x960x60 0x3B
+#define RES720x480x60 0x3C
+#define RES720x576x56 0x3D
+#define RES856x480x79I 0x3E
+#define RES856x480x60 0x3F
+#define RES1280x768x60 0x40
+#define RES1400x1050x60 0x41
+#define RES1152x864x60 0x42
+#define RES1152x864x75 0x43
+#define RES1024x768x160 0x44
+#define RES1280x960x75 0x45
+#define RES1280x960x85 0x46
+#define RES1280x960x120 0x47
+
+
+#define XG27_CR8F 0x0C
+#define XG27_SR36 0x30
+#define XG27_SR40 0x04
+#define XG27_SR41 0x00
+#define XG40_CRCF 0x13
+#define XGI330_CRT2Data_1_2 0
+#define XGI330_CRT2Data_4_D 0
+#define XGI330_CRT2Data_4_E 0
+#define XGI330_CRT2Data_4_10 0x80
+#define XGI330_SR07 0x18
+#define XGI330_SR1F 0
+#define XGI330_SR23 0xf6
+#define XGI330_SR24 0x0d
+#define XGI330_SR31 0xc0
+#define XGI330_SR32 0x11
+#define XGI330_SR33 0
+
+extern const struct XGI_ExtStruct XGI330_EModeIDTable[];
+extern const struct XGI_Ext2Struct XGI330_RefIndex[];
+extern const struct XGI_CRT1TableStruct XGI_CRT1Table[];
+extern const struct XGI_ECLKDataStruct XGI340_ECLKData[];
+extern const struct SiS_VCLKData XGI_VCLKData[];
+extern const unsigned char XGI340_CR6B[][4];
+extern const unsigned char XGI340_AGPReg[];
+
+#endif
diff --git a/src/drivers/xgi/common/vb_init.c b/src/drivers/xgi/common/vb_init.c
new file mode 100644
index 0000000000..2b81605752
--- /dev/null
+++ b/src/drivers/xgi/common/vb_init.c
@@ -0,0 +1,1289 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken from the Linux xgifb driver (v3.18.5)
+ * Coreboot-specific includes added at top
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xgi_coreboot.h"
+#include "vstruct.h"
+
+#include "XGIfb.h"
+#include "vb_def.h"
+#include "vb_util.h"
+#include "vb_setmode.h"
+#include "vb_init.h"
+static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = {
+ { 16, 0x45},
+ { 8, 0x35},
+ { 4, 0x31},
+ { 2, 0x21} };
+
+static const unsigned short XGINew_DDRDRAM_TYPE20[12][2] = {
+ { 128, 0x5D},
+ { 64, 0x59},
+ { 64, 0x4D},
+ { 32, 0x55},
+ { 32, 0x49},
+ { 32, 0x3D},
+ { 16, 0x51},
+ { 16, 0x45},
+ { 16, 0x39},
+ { 8, 0x41},
+ { 8, 0x35},
+ { 4, 0x31} };
+
+#define XGIFB_ROM_SIZE 65536
+
+static unsigned char
+XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char data, temp;
+
+ if (HwDeviceExtension->jChipType < XG20) {
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02;
+ if (data == 0)
+ data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) &
+ 0x02) >> 1;
+ return data;
+ } else if (HwDeviceExtension->jChipType == XG27) {
+ temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
+ /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+ if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
+ data = 0; /* DDR */
+ else
+ data = 1; /* DDRII */
+ return data;
+ } else if (HwDeviceExtension->jChipType == XG21) {
+ /* Independent GPIO control */
+ xgifb_reg_and(pVBInfo->P3d4, 0xB4, ~0x02);
+ udelay(800);
+ xgifb_reg_or(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */
+ /* GPIOF 0:DVI 1:DVO */
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x48);
+ /* HOTPLUG_SUPPORT */
+ /* for current XG20 & XG21, GPIOH is floating, driver will
+ * fix DDR temporarily */
+ /* DVI read GPIOH */
+ data &= 0x01; /* 1=DDRII, 0=DDR */
+ /* ~HOTPLUG_SUPPORT */
+ xgifb_reg_or(pVBInfo->P3d4, 0xB4, 0x02);
+ return data;
+ }
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x97) & 0x01;
+
+ if (data == 1)
+ data++;
+
+ return data;
+}
+
+static void XGINew_DDR1x_MRS_340(unsigned long P3c4,
+ struct vb_device_info *pVBInfo)
+{
+ xgifb_reg_set(P3c4, 0x18, 0x01);
+ xgifb_reg_set(P3c4, 0x19, 0x20);
+ xgifb_reg_set(P3c4, 0x16, 0x00);
+ xgifb_reg_set(P3c4, 0x16, 0x80);
+
+ mdelay(3);
+ xgifb_reg_set(P3c4, 0x18, 0x00);
+ xgifb_reg_set(P3c4, 0x19, 0x20);
+ xgifb_reg_set(P3c4, 0x16, 0x00);
+ xgifb_reg_set(P3c4, 0x16, 0x80);
+
+ udelay(60);
+ xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
+ xgifb_reg_set(P3c4, 0x19, 0x01);
+ xgifb_reg_set(P3c4, 0x16, 0x03);
+ xgifb_reg_set(P3c4, 0x16, 0x83);
+ mdelay(1);
+ xgifb_reg_set(P3c4, 0x1B, 0x03);
+ udelay(500);
+ xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
+ xgifb_reg_set(P3c4, 0x19, 0x00);
+ xgifb_reg_set(P3c4, 0x16, 0x03);
+ xgifb_reg_set(P3c4, 0x16, 0x83);
+ xgifb_reg_set(P3c4, 0x1B, 0x00);
+}
+
+static void XGINew_SetMemoryClock(struct vb_device_info *pVBInfo)
+{
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x28,
+ pVBInfo->MCLKData[pVBInfo->ram_type].SR28);
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x29,
+ pVBInfo->MCLKData[pVBInfo->ram_type].SR29);
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x2A,
+ pVBInfo->MCLKData[pVBInfo->ram_type].SR2A);
+
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x2E,
+ XGI340_ECLKData[pVBInfo->ram_type].SR2E);
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x2F,
+ XGI340_ECLKData[pVBInfo->ram_type].SR2F);
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x30,
+ XGI340_ECLKData[pVBInfo->ram_type].SR30);
+}
+
+static void XGINew_DDRII_Bootup_XG27(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long P3c4, struct vb_device_info *pVBInfo)
+{
+ unsigned long P3d4 = P3c4 + 0x10;
+
+ pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+ XGINew_SetMemoryClock(pVBInfo);
+
+ /* Set Double Frequency */
+ xgifb_reg_set(P3d4, 0x97, pVBInfo->XGINew_CR97); /* CR97 */
+
+ udelay(200);
+
+ xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */
+ xgifb_reg_set(P3c4, 0x19, 0x80); /* Set SR19 */
+ xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
+ udelay(15);
+ xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
+ udelay(15);
+
+ xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */
+ xgifb_reg_set(P3c4, 0x19, 0xC0); /* Set SR19 */
+ xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
+ udelay(15);
+ xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
+ udelay(15);
+
+ xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */
+ xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */
+ xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
+ udelay(30);
+ xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
+ udelay(15);
+
+ xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */
+ xgifb_reg_set(P3c4, 0x19, 0x0A); /* Set SR19 */
+ xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
+ udelay(30);
+ xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
+ xgifb_reg_set(P3c4, 0x16, 0x80); /* Set SR16 */
+
+ xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B */
+ udelay(60);
+ xgifb_reg_set(P3c4, 0x1B, 0x00); /* Set SR1B */
+
+ xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */
+ xgifb_reg_set(P3c4, 0x19, 0x08); /* Set SR19 */
+ xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
+
+ udelay(30);
+ xgifb_reg_set(P3c4, 0x16, 0x83); /* Set SR16 */
+ udelay(15);
+
+ xgifb_reg_set(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */
+ xgifb_reg_set(P3c4, 0x19, 0x46); /* Set SR19 */
+ xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
+ udelay(30);
+ xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
+ udelay(15);
+
+ xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */
+ xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */
+ xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
+ udelay(30);
+ xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
+ udelay(15);
+
+ /* Set SR1B refresh control 000:close; 010:open */
+ xgifb_reg_set(P3c4, 0x1B, 0x04);
+ udelay(200);
+
+}
+
+static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long P3c4, struct vb_device_info *pVBInfo)
+{
+ unsigned long P3d4 = P3c4 + 0x10;
+
+ pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+ XGINew_SetMemoryClock(pVBInfo);
+
+ xgifb_reg_set(P3d4, 0x97, 0x11); /* CR97 */
+
+ udelay(200);
+ xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS2 */
+ xgifb_reg_set(P3c4, 0x19, 0x80);
+ xgifb_reg_set(P3c4, 0x16, 0x05);
+ xgifb_reg_set(P3c4, 0x16, 0x85);
+
+ xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS3 */
+ xgifb_reg_set(P3c4, 0x19, 0xC0);
+ xgifb_reg_set(P3c4, 0x16, 0x05);
+ xgifb_reg_set(P3c4, 0x16, 0x85);
+
+ xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS1 */
+ xgifb_reg_set(P3c4, 0x19, 0x40);
+ xgifb_reg_set(P3c4, 0x16, 0x05);
+ xgifb_reg_set(P3c4, 0x16, 0x85);
+
+ xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */
+ xgifb_reg_set(P3c4, 0x19, 0x02);
+ xgifb_reg_set(P3c4, 0x16, 0x05);
+ xgifb_reg_set(P3c4, 0x16, 0x85);
+
+ udelay(15);
+ xgifb_reg_set(P3c4, 0x1B, 0x04); /* SR1B */
+ udelay(30);
+ xgifb_reg_set(P3c4, 0x1B, 0x00); /* SR1B */
+ udelay(100);
+
+ xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */
+ xgifb_reg_set(P3c4, 0x19, 0x00);
+ xgifb_reg_set(P3c4, 0x16, 0x05);
+ xgifb_reg_set(P3c4, 0x16, 0x85);
+
+ udelay(200);
+}
+
+static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4,
+ struct vb_device_info *pVBInfo)
+{
+ xgifb_reg_set(P3c4, 0x18, 0x01);
+ xgifb_reg_set(P3c4, 0x19, 0x40);
+ xgifb_reg_set(P3c4, 0x16, 0x00);
+ xgifb_reg_set(P3c4, 0x16, 0x80);
+ udelay(60);
+
+ xgifb_reg_set(P3c4, 0x18, 0x00);
+ xgifb_reg_set(P3c4, 0x19, 0x40);
+ xgifb_reg_set(P3c4, 0x16, 0x00);
+ xgifb_reg_set(P3c4, 0x16, 0x80);
+ udelay(60);
+ xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
+ xgifb_reg_set(P3c4, 0x19, 0x01);
+ xgifb_reg_set(P3c4, 0x16, 0x03);
+ xgifb_reg_set(P3c4, 0x16, 0x83);
+ mdelay(1);
+ xgifb_reg_set(P3c4, 0x1B, 0x03);
+ udelay(500);
+ xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
+ xgifb_reg_set(P3c4, 0x19, 0x00);
+ xgifb_reg_set(P3c4, 0x16, 0x03);
+ xgifb_reg_set(P3c4, 0x16, 0x83);
+ xgifb_reg_set(P3c4, 0x1B, 0x00);
+}
+
+static void XGINew_DDR1x_DefaultRegister(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long Port, struct vb_device_info *pVBInfo)
+{
+ unsigned long P3d4 = Port, P3c4 = Port - 0x10;
+
+ if (HwDeviceExtension->jChipType >= XG20) {
+ XGINew_SetMemoryClock(pVBInfo);
+ xgifb_reg_set(P3d4,
+ 0x82,
+ pVBInfo->CR40[11][pVBInfo->ram_type]); /* CR82 */
+ xgifb_reg_set(P3d4,
+ 0x85,
+ pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */
+ xgifb_reg_set(P3d4,
+ 0x86,
+ pVBInfo->CR40[13][pVBInfo->ram_type]); /* CR86 */
+
+ xgifb_reg_set(P3d4, 0x98, 0x01);
+ xgifb_reg_set(P3d4, 0x9A, 0x02);
+
+ XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo);
+ } else {
+ XGINew_SetMemoryClock(pVBInfo);
+
+ switch (HwDeviceExtension->jChipType) {
+ case XG42:
+ /* CR82 */
+ xgifb_reg_set(P3d4,
+ 0x82,
+ pVBInfo->CR40[11][pVBInfo->ram_type]);
+ /* CR85 */
+ xgifb_reg_set(P3d4,
+ 0x85,
+ pVBInfo->CR40[12][pVBInfo->ram_type]);
+ /* CR86 */
+ xgifb_reg_set(P3d4,
+ 0x86,
+ pVBInfo->CR40[13][pVBInfo->ram_type]);
+ break;
+ default:
+ xgifb_reg_set(P3d4, 0x82, 0x88);
+ xgifb_reg_set(P3d4, 0x86, 0x00);
+ /* Insert read command for delay */
+ xgifb_reg_get(P3d4, 0x86);
+ xgifb_reg_set(P3d4, 0x86, 0x88);
+ xgifb_reg_get(P3d4, 0x86);
+ xgifb_reg_set(P3d4,
+ 0x86,
+ pVBInfo->CR40[13][pVBInfo->ram_type]);
+ xgifb_reg_set(P3d4, 0x82, 0x77);
+ xgifb_reg_set(P3d4, 0x85, 0x00);
+
+ /* Insert read command for delay */
+ xgifb_reg_get(P3d4, 0x85);
+ xgifb_reg_set(P3d4, 0x85, 0x88);
+
+ /* Insert read command for delay */
+ xgifb_reg_get(P3d4, 0x85);
+ /* CR85 */
+ xgifb_reg_set(P3d4,
+ 0x85,
+ pVBInfo->CR40[12][pVBInfo->ram_type]);
+ /* CR82 */
+ xgifb_reg_set(P3d4,
+ 0x82,
+ pVBInfo->CR40[11][pVBInfo->ram_type]);
+ break;
+ }
+
+ xgifb_reg_set(P3d4, 0x97, 0x00);
+ xgifb_reg_set(P3d4, 0x98, 0x01);
+ xgifb_reg_set(P3d4, 0x9A, 0x02);
+ XGINew_DDR1x_MRS_340(P3c4, pVBInfo);
+ }
+}
+
+static void XGINew_DDR2_DefaultRegister(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long Port, struct vb_device_info *pVBInfo)
+{
+ unsigned long P3d4 = Port, P3c4 = Port - 0x10;
+
+ /* keep following setting sequence, each setting in
+ * the same reg insert idle */
+ xgifb_reg_set(P3d4, 0x82, 0x77);
+ xgifb_reg_set(P3d4, 0x86, 0x00);
+ xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
+ xgifb_reg_set(P3d4, 0x86, 0x88);
+ xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
+ /* CR86 */
+ xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][pVBInfo->ram_type]);
+ xgifb_reg_set(P3d4, 0x82, 0x77);
+ xgifb_reg_set(P3d4, 0x85, 0x00);
+ xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
+ xgifb_reg_set(P3d4, 0x85, 0x88);
+ xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
+ xgifb_reg_set(P3d4,
+ 0x85,
+ pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */
+ if (HwDeviceExtension->jChipType == XG27)
+ /* CR82 */
+ xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][pVBInfo->ram_type]);
+ else
+ xgifb_reg_set(P3d4, 0x82, 0xA8); /* CR82 */
+
+ xgifb_reg_set(P3d4, 0x98, 0x01);
+ xgifb_reg_set(P3d4, 0x9A, 0x02);
+ if (HwDeviceExtension->jChipType == XG27)
+ XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo);
+ else
+ XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo);
+}
+
+static void XGI_SetDRAM_Helper(unsigned long P3d4, u8 seed, u8 temp2, u8 reg,
+ u8 shift_factor, u8 mask1, u8 mask2)
+{
+ u8 j;
+
+ for (j = 0; j < 4; j++) {
+ temp2 |= (((seed >> (2 * j)) & 0x03) << shift_factor);
+ xgifb_reg_set(P3d4, reg, temp2);
+ xgifb_reg_get(P3d4, reg);
+ temp2 &= mask1;
+ temp2 += mask2;
+ }
+}
+
+static void XGINew_SetDRAMDefaultRegister340(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long Port, struct vb_device_info *pVBInfo)
+{
+ unsigned char temp, temp1, temp2, temp3, j, k;
+
+ unsigned long P3d4 = Port, P3c4 = Port - 0x10;
+
+ xgifb_reg_set(P3d4, 0x6D, pVBInfo->CR40[8][pVBInfo->ram_type]);
+ xgifb_reg_set(P3d4, 0x68, pVBInfo->CR40[5][pVBInfo->ram_type]);
+ xgifb_reg_set(P3d4, 0x69, pVBInfo->CR40[6][pVBInfo->ram_type]);
+ xgifb_reg_set(P3d4, 0x6A, pVBInfo->CR40[7][pVBInfo->ram_type]);
+
+ /* CR6B DQS fine tune delay */
+ temp = 0xaa;
+ XGI_SetDRAM_Helper(P3d4, temp, 0, 0x6B, 2, 0xF0, 0x10);
+
+ /* CR6E DQM fine tune delay */
+ XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6E, 2, 0xF0, 0x10);
+
+ temp3 = 0;
+ for (k = 0; k < 4; k++) {
+ /* CR6E_D[1:0] select channel */
+ xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3);
+ XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6F, 0, 0xF8, 0x08);
+ temp3 += 0x01;
+ }
+
+ xgifb_reg_set(P3d4,
+ 0x80,
+ pVBInfo->CR40[9][pVBInfo->ram_type]); /* CR80 */
+ xgifb_reg_set(P3d4,
+ 0x81,
+ pVBInfo->CR40[10][pVBInfo->ram_type]); /* CR81 */
+
+ temp2 = 0x80;
+ /* CR89 terminator type select */
+ XGI_SetDRAM_Helper(P3d4, 0, temp2, 0x89, 0, 0xF0, 0x10);
+
+ temp = 0;
+ temp1 = temp & 0x03;
+ temp2 |= temp1;
+ xgifb_reg_set(P3d4, 0x89, temp2);
+
+ temp = pVBInfo->CR40[3][pVBInfo->ram_type];
+ temp1 = temp & 0x0F;
+ temp2 = (temp >> 4) & 0x07;
+ temp3 = temp & 0x80;
+ xgifb_reg_set(P3d4, 0x45, temp1); /* CR45 */
+ xgifb_reg_set(P3d4, 0x99, temp2); /* CR99 */
+ xgifb_reg_or(P3d4, 0x40, temp3); /* CR40_D[7] */
+ xgifb_reg_set(P3d4,
+ 0x41,
+ pVBInfo->CR40[0][pVBInfo->ram_type]); /* CR41 */
+
+ if (HwDeviceExtension->jChipType == XG27)
+ xgifb_reg_set(P3d4, 0x8F, XG27_CR8F); /* CR8F */
+
+ for (j = 0; j <= 6; j++) /* CR90 - CR96 */
+ xgifb_reg_set(P3d4, (0x90 + j),
+ pVBInfo->CR40[14 + j][pVBInfo->ram_type]);
+
+ for (j = 0; j <= 2; j++) /* CRC3 - CRC5 */
+ xgifb_reg_set(P3d4, (0xC3 + j),
+ pVBInfo->CR40[21 + j][pVBInfo->ram_type]);
+
+ for (j = 0; j < 2; j++) /* CR8A - CR8B */
+ xgifb_reg_set(P3d4, (0x8A + j),
+ pVBInfo->CR40[1 + j][pVBInfo->ram_type]);
+
+ if (HwDeviceExtension->jChipType == XG42)
+ xgifb_reg_set(P3d4, 0x8C, 0x87);
+
+ xgifb_reg_set(P3d4,
+ 0x59,
+ pVBInfo->CR40[4][pVBInfo->ram_type]); /* CR59 */
+
+ xgifb_reg_set(P3d4, 0x83, 0x09); /* CR83 */
+ xgifb_reg_set(P3d4, 0x87, 0x00); /* CR87 */
+ xgifb_reg_set(P3d4, 0xCF, XG40_CRCF); /* CRCF */
+ if (pVBInfo->ram_type) {
+ xgifb_reg_set(P3c4, 0x17, 0x80); /* SR17 DDRII */
+ if (HwDeviceExtension->jChipType == XG27)
+ xgifb_reg_set(P3c4, 0x17, 0x02); /* SR17 DDRII */
+
+ } else {
+ xgifb_reg_set(P3c4, 0x17, 0x00); /* SR17 DDR */
+ }
+ xgifb_reg_set(P3c4, 0x1A, 0x87); /* SR1A */
+
+ temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+ if (temp == 0) {
+ XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
+ } else {
+ xgifb_reg_set(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */
+ XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
+ }
+ xgifb_reg_set(P3c4, 0x1B, 0x03); /* SR1B */
+}
+
+
+static unsigned short XGINew_SetDRAMSize20Reg(
+ unsigned short dram_size,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data = 0, memsize = 0;
+ int RankSize;
+ unsigned char ChannelNo;
+
+ RankSize = dram_size * pVBInfo->ram_bus / 8;
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x13);
+ data &= 0x80;
+
+ if (data == 0x80)
+ RankSize *= 2;
+
+ data = 0;
+
+ if (pVBInfo->ram_channel == 3)
+ ChannelNo = 4;
+ else
+ ChannelNo = pVBInfo->ram_channel;
+
+ if (ChannelNo * RankSize <= 256) {
+ while ((RankSize >>= 1) > 0)
+ data += 0x10;
+
+ memsize = data >> 4;
+
+ /* Fix DRAM Sizing Error */
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x14,
+ (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) |
+ (data & 0xF0));
+ udelay(15);
+ }
+ return memsize;
+}
+
+static int XGINew_ReadWriteRest(unsigned short StopAddr,
+ unsigned short StartAddr, struct vb_device_info *pVBInfo)
+{
+ int i;
+ unsigned long Position = 0;
+ void __iomem *fbaddr = pVBInfo->FBAddr;
+
+ writel(Position, fbaddr + Position);
+
+ for (i = StartAddr; i <= StopAddr; i++) {
+ Position = 1 << i;
+ writel(Position, fbaddr + Position);
+ }
+
+ udelay(500); /* Fix #1759 Memory Size error in Multi-Adapter. */
+
+ Position = 0;
+
+ if (readl(fbaddr + Position) != Position)
+ return 0;
+
+ for (i = StartAddr; i <= StopAddr; i++) {
+ Position = 1 << i;
+ if (readl(fbaddr + Position) != Position)
+ return 0;
+ }
+ return 1;
+}
+
+static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
+{
+ unsigned char data;
+
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x97);
+
+ if ((data & 0x10) == 0) {
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x39);
+ data = (data & 0x02) >> 1;
+ return data;
+ }
+ return data & 0x01;
+}
+
+static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char data;
+
+ switch (HwDeviceExtension->jChipType) {
+ case XG20:
+ case XG21:
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x97);
+ data = data & 0x01;
+ pVBInfo->ram_channel = 1; /* XG20 "JUST" one channel */
+
+ if (data == 0) { /* Single_32_16 */
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1)
+ > 0x1000000) {
+
+ pVBInfo->ram_bus = 32; /* 32 bits */
+ /* 22bit + 2 rank + 32bit */
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52);
+ udelay(15);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+ 0x800000) {
+ /* 22bit + 1 rank + 32bit */
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x13,
+ 0x31);
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x14,
+ 0x42);
+ udelay(15);
+
+ if (XGINew_ReadWriteRest(23,
+ 23,
+ pVBInfo) == 1)
+ return;
+ }
+ }
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+ 0x800000) {
+ pVBInfo->ram_bus = 16; /* 16 bits */
+ /* 22bit + 2 rank + 16bit */
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41);
+ udelay(15);
+
+ if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+ return;
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x13,
+ 0x31);
+ udelay(15);
+ }
+
+ } else { /* Dual_16_8 */
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+ 0x800000) {
+ pVBInfo->ram_bus = 16; /* 16 bits */
+ /* (0x31:12x8x2) 22bit + 2 rank */
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
+ /* 0x41:16Mx16 bit*/
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41);
+ udelay(15);
+
+ if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+ return;
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+ 0x400000) {
+ /* (0x31:12x8x2) 22bit + 1 rank */
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x13,
+ 0x31);
+ /* 0x31:8Mx16 bit*/
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x14,
+ 0x31);
+ udelay(15);
+
+ if (XGINew_ReadWriteRest(22,
+ 22,
+ pVBInfo) == 1)
+ return;
+ }
+ }
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+ 0x400000) {
+ pVBInfo->ram_bus = 8; /* 8 bits */
+ /* (0x31:12x8x2) 22bit + 2 rank */
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
+ /* 0x30:8Mx8 bit*/
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30);
+ udelay(15);
+
+ if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1)
+ return;
+
+ /* (0x31:12x8x2) 22bit + 1 rank */
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x13,
+ 0x31);
+ udelay(15);
+ }
+ }
+ break;
+
+ case XG27:
+ pVBInfo->ram_bus = 16; /* 16 bits */
+ pVBInfo->ram_channel = 1; /* Single channel */
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/
+ break;
+ case XG42:
+ /*
+ XG42 SR14 D[3] Reserve
+ D[2] = 1, Dual Channel
+ = 0, Single Channel
+
+ It's Different from Other XG40 Series.
+ */
+ if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */
+ pVBInfo->ram_bus = 32; /* 32 bits */
+ pVBInfo->ram_channel = 2; /* 2 Channel */
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x44);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x34);
+ if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+ return;
+
+ pVBInfo->ram_channel = 1; /* Single Channel */
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x40);
+
+ if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+ return;
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30);
+ } else { /* DDR */
+ pVBInfo->ram_bus = 64; /* 64 bits */
+ pVBInfo->ram_channel = 1; /* 1 channels */
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42);
+ }
+
+ break;
+
+ default: /* XG40 */
+
+ if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */
+ pVBInfo->ram_bus = 32; /* 32 bits */
+ pVBInfo->ram_channel = 3;
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C);
+
+ if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
+ return;
+
+ pVBInfo->ram_channel = 2; /* 2 channels */
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) {
+ pVBInfo->ram_channel = 3; /* 4 channels */
+ } else {
+ pVBInfo->ram_channel = 2; /* 2 channels */
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38);
+ }
+ } else { /* DDR */
+ pVBInfo->ram_bus = 64; /* 64 bits */
+ pVBInfo->ram_channel = 2; /* 2 channels */
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A);
+
+ if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1)
+ return;
+ xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
+ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A);
+ }
+ break;
+ }
+}
+
+static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ u8 i, size;
+ unsigned short memsize, start_addr;
+ const unsigned short (*dram_table)[2];
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */
+ xgifb_reg_set(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */
+ XGINew_CheckChannel(HwDeviceExtension, pVBInfo);
+
+ if (HwDeviceExtension->jChipType >= XG20) {
+ dram_table = XGINew_DDRDRAM_TYPE20;
+ size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE20);
+ start_addr = 5;
+ } else {
+ dram_table = XGINew_DDRDRAM_TYPE340;
+ size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE340);
+ start_addr = 9;
+ }
+
+ for (i = 0; i < size; i++) {
+ /* SetDRAMSizingType */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, dram_table[i][1]);
+ udelay(15); /* should delay 50 ns */
+
+ memsize = XGINew_SetDRAMSize20Reg(dram_table[i][0], pVBInfo);
+
+ if (memsize == 0)
+ continue;
+
+ memsize += (pVBInfo->ram_channel - 2) + 20;
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) <
+ (unsigned long) (1 << memsize))
+ continue;
+
+ if (XGINew_ReadWriteRest(memsize, start_addr, pVBInfo) == 1)
+ return 1;
+ }
+ return 0;
+}
+
+static void XGINew_SetDRAMSize_340(struct xgifb_video_info *xgifb_info,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data;
+
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+
+ XGISetModeNew(xgifb_info, HwDeviceExtension, 0x2e);
+
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
+ /* disable read cache */
+ xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF));
+ XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
+
+ XGINew_DDRSizing340(HwDeviceExtension, pVBInfo);
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
+ /* enable read cache */
+ xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20));
+}
+
+static void XGINew_ChkSenseStatus(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx = 0, temp, tempcx, CR3CData;
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x32);
+
+ if (temp & Monitor1Sense)
+ tempbx |= ActiveCRT1;
+ if (temp & LCDSense)
+ tempbx |= ActiveLCD;
+ if (temp & Monitor2Sense)
+ tempbx |= ActiveCRT2;
+ if (temp & TVSense) {
+ tempbx |= ActiveTV;
+ if (temp & AVIDEOSense)
+ tempbx |= (ActiveAVideo << 8);
+ if (temp & SVIDEOSense)
+ tempbx |= (ActiveSVideo << 8);
+ if (temp & SCARTSense)
+ tempbx |= (ActiveSCART << 8);
+ if (temp & HiTVSense)
+ tempbx |= (ActiveHiTV << 8);
+ if (temp & YPbPrSense)
+ tempbx |= (ActiveYPbPr << 8);
+ }
+
+ tempcx = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
+ tempcx |= (xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8);
+
+ if (tempbx & tempcx) {
+ CR3CData = xgifb_reg_get(pVBInfo->P3d4, 0x3c);
+ if (!(CR3CData & DisplayDeviceFromCMOS))
+ tempcx = 0x1FF0;
+ } else {
+ tempcx = 0x1FF0;
+ }
+
+ tempbx &= tempcx;
+ xgifb_reg_set(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF));
+ xgifb_reg_set(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8));
+}
+
+static void XGINew_SetModeScratch(struct vb_device_info *pVBInfo)
+{
+ unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data;
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
+ temp |= xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8;
+ temp |= (xgifb_reg_get(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8;
+
+ if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
+ if (temp & ActiveCRT2)
+ tempcl = SetCRT2ToRAMDAC;
+ }
+
+ if (temp & ActiveLCD) {
+ tempcl |= SetCRT2ToLCD;
+ if (temp & DriverMode) {
+ if (temp & ActiveTV) {
+ tempch = SetToLCDA | EnableDualEdge;
+ temp ^= SetCRT2ToLCD;
+
+ if ((temp >> 8) & ActiveAVideo)
+ tempcl |= SetCRT2ToAVIDEO;
+ if ((temp >> 8) & ActiveSVideo)
+ tempcl |= SetCRT2ToSVIDEO;
+ if ((temp >> 8) & ActiveSCART)
+ tempcl |= SetCRT2ToSCART;
+
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ if ((temp >> 8) & ActiveHiTV)
+ tempcl |= SetCRT2ToHiVision;
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if ((temp >> 8) & ActiveYPbPr)
+ tempch |= SetYPbPr;
+ }
+ }
+ }
+ } else {
+ if ((temp >> 8) & ActiveAVideo)
+ tempcl |= SetCRT2ToAVIDEO;
+ if ((temp >> 8) & ActiveSVideo)
+ tempcl |= SetCRT2ToSVIDEO;
+ if ((temp >> 8) & ActiveSCART)
+ tempcl |= SetCRT2ToSCART;
+
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ if ((temp >> 8) & ActiveHiTV)
+ tempcl |= SetCRT2ToHiVision;
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if ((temp >> 8) & ActiveYPbPr)
+ tempch |= SetYPbPr;
+ }
+ }
+
+ tempcl |= SetSimuScanMode;
+ if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV)
+ || (temp & ActiveCRT2)))
+ tempcl ^= (SetSimuScanMode | SwitchCRT2);
+ if ((temp & ActiveLCD) && (temp & ActiveTV))
+ tempcl ^= (SetSimuScanMode | SwitchCRT2);
+ xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl);
+
+ CR31Data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
+ CR31Data &= ~(SetNotSimuMode >> 8);
+ if (!(temp & ActiveCRT1))
+ CR31Data |= (SetNotSimuMode >> 8);
+ CR31Data &= ~(DisableCRT2Display >> 8);
+ if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2)))
+ CR31Data |= (DisableCRT2Display >> 8);
+ xgifb_reg_set(pVBInfo->P3d4, 0x31, CR31Data);
+
+ CR38Data = xgifb_reg_get(pVBInfo->P3d4, 0x38);
+ CR38Data &= ~SetYPbPr;
+ CR38Data |= tempch;
+ xgifb_reg_set(pVBInfo->P3d4, 0x38, CR38Data);
+
+}
+
+static unsigned short XGINew_SenseLCD(struct xgi_hw_device_info
+ *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp = HwDeviceExtension->ulCRT2LCDType;
+
+ switch (HwDeviceExtension->ulCRT2LCDType) {
+ case LCD_640x480:
+ case LCD_1024x600:
+ case LCD_1152x864:
+ case LCD_1280x960:
+ case LCD_1152x768:
+ case LCD_1920x1440:
+ case LCD_2048x1536:
+ temp = 0; /* overwrite used ulCRT2LCDType */
+ break;
+ case LCD_UNKNOWN: /* unknown lcd, do nothing */
+ return 0;
+ }
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp);
+ return 1;
+}
+
+static void XGINew_GetXG21Sense(struct pci_dev *pdev,
+ struct vb_device_info *pVBInfo)
+{
+ struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
+ unsigned char Temp;
+
+ /* Enable GPIOA/B read */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
+ Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0;
+ if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
+ XGINew_SenseLCD(&xgifb_info->hw_info, pVBInfo);
+ xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
+ /* Enable read GPIOF */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20);
+ if (xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04)
+ Temp = 0xA0; /* Only DVO on chip */
+ else
+ Temp = 0x80; /* TMDS on chip */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, Temp);
+ /* Disable read GPIOF */
+ xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20);
+ }
+}
+
+static void XGINew_GetXG27Sense(struct vb_device_info *pVBInfo)
+{
+ unsigned char Temp, bCR4A;
+
+ bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+ /* Enable GPIOA/B/C read */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07);
+ Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07;
+ xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A);
+
+ if (Temp <= 0x02) {
+ /* LVDS setting */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
+ xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21);
+ } else {
+ /* TMDS/DVO setting */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0);
+ }
+ xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
+
+}
+
+static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
+{
+ unsigned char CR38, CR4A, temp;
+
+ CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+ /* enable GPIOE read */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10);
+ CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38);
+ temp = 0;
+ if ((CR38 & 0xE0) > 0x80) {
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
+ temp &= 0x08;
+ temp >>= 3;
+ }
+
+ xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
+
+ return temp;
+}
+
+static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
+{
+ unsigned char CR4A, temp;
+
+ CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+ /* enable GPIOA/B/C read */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
+ if (temp > 2)
+ temp = ((temp & 0x04) >> 1) | ((~temp) & 0x01);
+
+ xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
+
+ return temp;
+}
+
+static bool xgifb_bridge_is_on(struct vb_device_info *vb_info)
+{
+ u8 flag;
+
+ flag = xgifb_reg_get(vb_info->Part4Port, 0x00);
+ return flag == 1 || flag == 2;
+}
+
+unsigned char XGIInitNew(struct pci_dev *pdev)
+{
+ struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
+ struct xgi_hw_device_info *HwDeviceExtension = &xgifb_info->hw_info;
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+ unsigned char i, temp = 0, temp1;
+
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+
+ if (pVBInfo->FBAddr == NULL) {
+ dev_dbg(&pdev->dev, "pVBInfo->FBAddr == 0\n");
+ return 0;
+ }
+
+ XGIRegInit(pVBInfo, xgifb_info->vga_base);
+
+ outb(0x67, pVBInfo->P3c2);
+
+ InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+
+ /* Openkey */
+ xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
+
+ /* GetXG21Sense (GPIO) */
+ if (HwDeviceExtension->jChipType == XG21)
+ XGINew_GetXG21Sense(pdev, pVBInfo);
+
+ if (HwDeviceExtension->jChipType == XG27)
+ XGINew_GetXG27Sense(pVBInfo);
+
+ /* Reset Extended register */
+
+ for (i = 0x06; i < 0x20; i++)
+ xgifb_reg_set(pVBInfo->P3c4, i, 0);
+
+ for (i = 0x21; i <= 0x27; i++)
+ xgifb_reg_set(pVBInfo->P3c4, i, 0);
+
+ for (i = 0x31; i <= 0x3B; i++)
+ xgifb_reg_set(pVBInfo->P3c4, i, 0);
+
+ /* Auto over driver for XG42 */
+ if (HwDeviceExtension->jChipType == XG42)
+ xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0);
+
+ for (i = 0x79; i <= 0x7C; i++)
+ xgifb_reg_set(pVBInfo->P3d4, i, 0);
+
+ if (HwDeviceExtension->jChipType >= XG20)
+ xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97);
+
+ /* SetDefExt1Regs begin */
+ xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07);
+ if (HwDeviceExtension->jChipType == XG27) {
+ xgifb_reg_set(pVBInfo->P3c4, 0x40, XG27_SR40);
+ xgifb_reg_set(pVBInfo->P3c4, 0x41, XG27_SR41);
+ }
+ xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F);
+ xgifb_reg_set(pVBInfo->P3c4, 0x1F, XGI330_SR1F);
+ /* Frame buffer can read/write SR20 */
+ xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0);
+ /* H/W request for slow corner chip */
+ xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70);
+ if (HwDeviceExtension->jChipType == XG27)
+ xgifb_reg_set(pVBInfo->P3c4, 0x36, XG27_SR36);
+
+ if (HwDeviceExtension->jChipType < XG20) {
+ u32 Temp;
+
+ /* Set AGP customize registers (in SetDefAGPRegs) Start */
+ for (i = 0x47; i <= 0x4C; i++)
+ xgifb_reg_set(pVBInfo->P3d4,
+ i,
+ XGI340_AGPReg[i - 0x47]);
+
+ for (i = 0x70; i <= 0x71; i++)
+ xgifb_reg_set(pVBInfo->P3d4,
+ i,
+ XGI340_AGPReg[6 + i - 0x70]);
+
+ for (i = 0x74; i <= 0x77; i++)
+ xgifb_reg_set(pVBInfo->P3d4,
+ i,
+ XGI340_AGPReg[8 + i - 0x74]);
+
+ pci_read_config_dword(pdev, 0x50, &Temp);
+ Temp >>= 20;
+ Temp &= 0xF;
+
+ if (Temp == 1)
+ xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
+ } /* != XG20 */
+
+ /* Set PCI */
+ xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23);
+ xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24);
+ xgifb_reg_set(pVBInfo->P3c4, 0x25, 0);
+
+ if (HwDeviceExtension->jChipType < XG20) {
+ /* Set VB */
+ XGI_UnLockCRT2(pVBInfo);
+ /* disable VideoCapture */
+ xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00);
+ /* chk if BCLK>=100MHz */
+ temp1 = xgifb_reg_get(pVBInfo->P3d4, 0x7B);
+
+ xgifb_reg_set(pVBInfo->Part1Port,
+ 0x02, XGI330_CRT2Data_1_2);
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
+ } /* != XG20 */
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F);
+
+ if ((HwDeviceExtension->jChipType == XG42) &&
+ XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) {
+ /* Not DDR */
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x31,
+ (XGI330_SR31 & 0x3F) | 0x40);
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x32,
+ (XGI330_SR32 & 0xFC) | 0x01);
+ } else {
+ xgifb_reg_set(pVBInfo->P3c4, 0x31, XGI330_SR31);
+ xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32);
+ }
+ xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33);
+
+ if (HwDeviceExtension->jChipType < XG20) {
+ if (xgifb_bridge_is_on(pVBInfo)) {
+ xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C);
+ xgifb_reg_set(pVBInfo->Part4Port,
+ 0x0D, XGI330_CRT2Data_4_D);
+ xgifb_reg_set(pVBInfo->Part4Port,
+ 0x0E, XGI330_CRT2Data_4_E);
+ xgifb_reg_set(pVBInfo->Part4Port,
+ 0x10, XGI330_CRT2Data_4_10);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F);
+ XGI_LockCRT2(pVBInfo);
+ }
+ } /* != XG20 */
+
+ XGI_SenseCRT1(pVBInfo);
+
+ if (HwDeviceExtension->jChipType == XG21) {
+
+ xgifb_reg_and_or(pVBInfo->P3d4,
+ 0x32,
+ ~Monitor1Sense,
+ Monitor1Sense); /* Z9 default has CRT */
+ temp = GetXG21FPBits(pVBInfo);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp);
+
+ }
+ if (HwDeviceExtension->jChipType == XG27) {
+ xgifb_reg_and_or(pVBInfo->P3d4,
+ 0x32,
+ ~Monitor1Sense,
+ Monitor1Sense); /* Z9 default has CRT */
+ temp = GetXG27FPBits(pVBInfo);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp);
+ }
+
+ pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+
+ XGINew_SetDRAMDefaultRegister340(HwDeviceExtension,
+ pVBInfo->P3d4,
+ pVBInfo);
+
+ XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo);
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x22, 0xfa);
+ xgifb_reg_set(pVBInfo->P3c4, 0x21, 0xa3);
+
+ XGINew_ChkSenseStatus(pVBInfo);
+ XGINew_SetModeScratch(pVBInfo);
+
+ xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87);
+
+ return 1;
+} /* end of init */
diff --git a/src/drivers/xgi/common/vb_init.h b/src/drivers/xgi/common/vb_init.h
new file mode 100644
index 0000000000..4e24e73124
--- /dev/null
+++ b/src/drivers/xgi/common/vb_init.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken verbatim from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VBINIT_
+#define _VBINIT_
+extern unsigned char XGIInitNew(struct pci_dev *pdev);
+extern void XGIRegInit(struct vb_device_info *, unsigned long);
+#endif
+
diff --git a/src/drivers/xgi/common/vb_setmode.c b/src/drivers/xgi/common/vb_setmode.c
new file mode 100644
index 0000000000..8d0949a1fb
--- /dev/null
+++ b/src/drivers/xgi/common/vb_setmode.c
@@ -0,0 +1,5576 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken from the Linux xgifb driver (v3.18.5)
+ * Coreboot-specific includes added at top
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xgi_coreboot.h"
+#include "vstruct.h"
+
+#include "XGIfb.h"
+
+#include "vb_def.h"
+#include "vb_init.h"
+#include "vb_util.h"
+#include "vb_table.h"
+#include "vb_setmode.h"
+
+#define IndexMask 0xff
+#define TVCLKBASE_315_25 (TVCLKBASE_315 + 25)
+
+static const unsigned short XGINew_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 InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
+{
+ pVBInfo->MCLKData = XGI340New_MCLKData;
+
+ pVBInfo->LCDResInfo = 0;
+ pVBInfo->LCDTypeInfo = 0;
+ pVBInfo->LCDInfo = 0;
+ pVBInfo->VBInfo = 0;
+ pVBInfo->TVInfo = 0;
+
+ pVBInfo->SR18 = XGI340_SR18;
+ pVBInfo->CR40 = XGI340_cr41;
+
+ if (ChipType < XG20)
+ XGI_GetVBType(pVBInfo);
+
+ /* 310 customization related */
+ if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
+ pVBInfo->LCDCapList = XGI_LCDDLCapList;
+ else
+ pVBInfo->LCDCapList = XGI_LCDCapList;
+
+ if (ChipType >= XG20)
+ pVBInfo->XGINew_CR97 = 0x10;
+
+ if (ChipType == XG27) {
+ unsigned char temp;
+
+ pVBInfo->MCLKData = XGI27New_MCLKData;
+ pVBInfo->CR40 = XGI27_cr41;
+ pVBInfo->XGINew_CR97 = 0xc1;
+ pVBInfo->SR18 = XG27_SR18;
+
+ /*Z11m DDR*/
+ temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
+ /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+ if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
+ pVBInfo->XGINew_CR97 = 0x80;
+ }
+
+}
+
+static void XGI_SetSeqRegs(struct vb_device_info *pVBInfo)
+{
+ unsigned char SRdata, i;
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
+
+ for (i = 0; i < 4; i++) {
+ /* Get SR1,2,3,4 from file */
+ /* SR1 is with screen off 0x20 */
+ SRdata = XGI330_StandTable.SR[i];
+ xgifb_reg_set(pVBInfo->P3c4, i+1, SRdata); /* Set SR 1 2 3 4 */
+ }
+}
+
+static void XGI_SetCRTCRegs(struct vb_device_info *pVBInfo)
+{
+ unsigned char CRTCdata;
+ unsigned short i;
+
+ CRTCdata = xgifb_reg_get(pVBInfo->P3d4, 0x11);
+ CRTCdata &= 0x7f;
+ xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
+
+ for (i = 0; i <= 0x18; i++) {
+ /* Get CRTC from file */
+ CRTCdata = XGI330_StandTable.CRTC[i];
+ xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
+ }
+}
+
+static void XGI_SetATTRegs(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char ARdata;
+ unsigned short i, modeflag;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ for (i = 0; i <= 0x13; i++) {
+ ARdata = XGI330_StandTable.ATTR[i];
+
+ if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
+ ARdata = 0;
+ } else if ((pVBInfo->VBInfo &
+ (SetCRT2ToTV | SetCRT2ToLCD)) &&
+ (pVBInfo->VBInfo & SetInSlaveMode)) {
+ ARdata = 0;
+ }
+ }
+
+ inb(pVBInfo->P3da); /* reset 3da */
+ outb(i, pVBInfo->P3c0); /* set index */
+ outb(ARdata, pVBInfo->P3c0); /* set data */
+ }
+
+ inb(pVBInfo->P3da); /* reset 3da */
+ outb(0x14, pVBInfo->P3c0); /* set index */
+ outb(0x00, pVBInfo->P3c0); /* set data */
+ inb(pVBInfo->P3da); /* Enable Attribute */
+ outb(0x20, pVBInfo->P3c0);
+}
+
+static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo)
+{
+ unsigned char GRdata;
+ unsigned short i;
+
+ for (i = 0; i <= 0x08; i++) {
+ /* Get GR from file */
+ GRdata = XGI330_StandTable.GRC[i];
+ xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
+ }
+
+ if (pVBInfo->ModeType > ModeVGA) {
+ GRdata = xgifb_reg_get(pVBInfo->P3ce, 0x05);
+ GRdata &= 0xBF; /* 256 color disable */
+ xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata);
+ }
+}
+
+static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
+{
+ unsigned short i;
+
+ for (i = 0x0A; i <= 0x0E; i++)
+ xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
+}
+
+static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
+{
+
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[0].SR2B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[0].SR2C);
+
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[1].SR2B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[1].SR2C);
+
+ xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30);
+ return 0;
+}
+
+static unsigned char XGI_AjustCRT2Rate(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex, unsigned short *i,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+ tempax = 0;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempax |= SupportRAMDAC2;
+
+ if (pVBInfo->VBType & VB_XGI301C)
+ tempax |= SupportCRT2in301C;
+ }
+
+ /* 301b */
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+ tempax |= SupportLCD;
+
+ if (pVBInfo->LCDResInfo != Panel_1280x1024 &&
+ pVBInfo->LCDResInfo != Panel_1280x960 &&
+ (pVBInfo->LCDInfo & LCDNonExpanding) &&
+ resinfo >= 9)
+ return 0;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */
+ tempax |= SupportHiVision;
+ if ((pVBInfo->VBInfo & SetInSlaveMode) &&
+ ((resinfo == 4) ||
+ (resinfo == 3 && (pVBInfo->SetFlag & TVSimuMode)) ||
+ (resinfo > 7)))
+ return 0;
+ } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO |
+ SetCRT2ToSCART | SetCRT2ToYPbPr525750 |
+ SetCRT2ToHiVision)) {
+ tempax |= SupportTV;
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV |
+ VB_SIS302LV | VB_XGI301C))
+ tempax |= SupportTV1024;
+
+ if (!(pVBInfo->VBInfo & TVSetPAL) &&
+ (modeflag & NoSupportSimuTV) &&
+ (pVBInfo->VBInfo & SetInSlaveMode) &&
+ (!(pVBInfo->VBInfo & SetNotSimuMode)))
+ return 0;
+ }
+
+ for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
+ tempbx; (*i)--) {
+ infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].
+ Ext_InfoFlag;
+ if (infoflag & tempax)
+ return 1;
+
+ if ((*i) == 0)
+ break;
+ }
+
+ for ((*i) = 0;; (*i)++) {
+ infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].
+ Ext_InfoFlag;
+ if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID
+ != tempbx) {
+ return 0;
+ }
+
+ if (infoflag & tempax)
+ return 1;
+ }
+ return 1;
+}
+
+static void XGI_SetSync(unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short sync, temp;
+
+ /* di+0x00 */
+ sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+ sync &= 0xC0;
+ temp = 0x2F;
+ temp |= sync;
+ outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */
+}
+
+static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
+ struct xgi_hw_device_info *HwDeviceExtension)
+{
+ unsigned char data, data1, pushax;
+ unsigned short i, j;
+
+ /* unlock cr0-7 */
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
+ data &= 0x7F;
+ xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
+
+ data = pVBInfo->TimingH.data[0];
+ xgifb_reg_set(pVBInfo->P3d4, 0, data);
+
+ for (i = 0x01; i <= 0x04; i++) {
+ data = pVBInfo->TimingH.data[i];
+ xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data);
+ }
+
+ for (i = 0x05; i <= 0x06; i++) {
+ data = pVBInfo->TimingH.data[i];
+ xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data);
+ }
+
+ j = xgifb_reg_get(pVBInfo->P3c4, 0x0e);
+ j &= 0x1F;
+ data = pVBInfo->TimingH.data[7];
+ data &= 0xE0;
+ data |= j;
+ xgifb_reg_set(pVBInfo->P3c4, 0x0e, data);
+
+ if (HwDeviceExtension->jChipType >= XG20) {
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x04);
+ data = data - 1;
+ xgifb_reg_set(pVBInfo->P3d4, 0x04, data);
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x05);
+ data1 = data;
+ data1 &= 0xE0;
+ data &= 0x1F;
+ if (data == 0) {
+ pushax = data;
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x0c);
+ data &= 0xFB;
+ xgifb_reg_set(pVBInfo->P3c4, 0x0c, data);
+ data = pushax;
+ }
+ data = data - 1;
+ data |= data1;
+ xgifb_reg_set(pVBInfo->P3d4, 0x05, data);
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x0e);
+ data = data >> 5;
+ data = data + 3;
+ if (data > 7)
+ data = data - 7;
+ data = data << 5;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data);
+ }
+}
+
+static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char data;
+ unsigned short i, j;
+
+ for (i = 0x00; i <= 0x01; i++) {
+ data = pVBInfo->TimingV.data[i];
+ xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data);
+ }
+
+ for (i = 0x02; i <= 0x03; i++) {
+ data = pVBInfo->TimingV.data[i];
+ xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
+ }
+
+ for (i = 0x04; i <= 0x05; i++) {
+ data = pVBInfo->TimingV.data[i];
+ xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
+ }
+
+ j = xgifb_reg_get(pVBInfo->P3c4, 0x0a);
+ j &= 0xC0;
+ data = pVBInfo->TimingV.data[6];
+ data &= 0x3F;
+ data |= j;
+ xgifb_reg_set(pVBInfo->P3c4, 0x0a, data);
+
+ data = pVBInfo->TimingV.data[6];
+ data &= 0x80;
+ data = data >> 2;
+
+ i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ i &= DoubleScanMode;
+ if (i)
+ data |= 0x80;
+
+ j = xgifb_reg_get(pVBInfo->P3d4, 0x09);
+ j &= 0x5F;
+ data |= j;
+ xgifb_reg_set(pVBInfo->P3d4, 0x09, data);
+}
+
+static void XGI_SetCRT1CRTC(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo,
+ struct xgi_hw_device_info *HwDeviceExtension)
+{
+ unsigned char index, data;
+ unsigned short i;
+
+ /* Get index */
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ index = index & IndexMask;
+
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
+ data &= 0x7F;
+ xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+
+ for (i = 0; i < 8; i++)
+ pVBInfo->TimingH.data[i]
+ = XGI_CRT1Table[index].CR[i];
+
+ for (i = 0; i < 7; i++)
+ pVBInfo->TimingV.data[i]
+ = XGI_CRT1Table[index].CR[i + 8];
+
+ XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+
+ XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo);
+
+ if (pVBInfo->ModeType > 0x03)
+ xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F);
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetXG21CRTC */
+/* Input : Stand or enhance CRTC table */
+/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
+/* Description : Set LCD timing */
+/* --------------------------------------------------------------------- */
+static void XGI_SetXG21CRTC(unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char index, Tempax, Tempbx, Tempcx, Tempdx;
+ unsigned short Temp1, Temp2, Temp3;
+
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ /* Tempax: CR4 HRS */
+ Tempax = XGI_CRT1Table[index].CR[3];
+ Tempcx = Tempax; /* Tempcx: HRS */
+ /* SR2E[7:0]->HRS */
+ xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
+
+ Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */
+ Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
+ Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
+ Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
+ Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
+
+ Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
+ Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
+
+ Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */
+ Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
+ Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
+ Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
+
+ Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
+ Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
+
+ Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
+ if (Tempax < Tempcx) /* HRE < HRS */
+ Temp2 |= 0x40; /* Temp2 + 0x40 */
+
+ Temp2 &= 0xFF;
+ Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
+ Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
+ Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
+ Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
+ /* SR2F D[7:2]->HRE, D[1:0]->HRS */
+ xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
+
+ /* CR10 VRS */
+ Tempax = XGI_CRT1Table[index].CR[10];
+ Tempbx = Tempax; /* Tempbx: VRS */
+ Tempax &= 0x01; /* Tempax[0]: VRS[0] */
+ xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
+ /* CR7[2][7] VRE */
+ Tempax = XGI_CRT1Table[index].CR[9];
+ Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
+ Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
+ Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
+ Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
+ xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
+
+ Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
+ Temp1 <<= 1; /* Temp1[8]: VRS[8] */
+ Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
+ Tempax &= 0x80;
+ Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
+ Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
+ /* Tempax: SRA */
+ Tempax = XGI_CRT1Table[index].CR[14];
+ Tempax &= 0x08; /* Tempax[3]: VRS[3] */
+ Temp2 = Tempax;
+ Temp2 <<= 7; /* Temp2[10]: VRS[10] */
+ Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
+
+ /* Tempax: CR11 VRE */
+ Tempax = XGI_CRT1Table[index].CR[11];
+ Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
+ /* Tempbx: SRA */
+ Tempbx = XGI_CRT1Table[index].CR[14];
+ Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
+ Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
+ Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
+ Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
+ Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
+
+ Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
+ if (Tempax < Temp3) /* VRE < VRS */
+ Temp2 |= 0x20; /* VRE + 0x20 */
+
+ Temp2 &= 0xFF;
+ Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
+ Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
+ Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
+ Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
+ Tempbx = (unsigned char) Temp1;
+ Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
+ Tempax &= 0x7F;
+ /* SR3F D[7:2]->VRE D[1:0]->VRS */
+ xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
+}
+
+static void XGI_SetXG27CRTC(unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short index, Tempax, Tempbx, Tempcx;
+
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ /* Tempax: CR4 HRS */
+ Tempax = XGI_CRT1Table[index].CR[3];
+ Tempbx = Tempax; /* Tempbx: HRS[7:0] */
+ /* SR2E[7:0]->HRS */
+ xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
+
+ /* SR0B */
+ Tempax = XGI_CRT1Table[index].CR[5];
+ Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
+ Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
+
+ Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
+ Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
+ Tempcx = Tempax; /* Tempcx: HRE[4:0] */
+
+ Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */
+ Tempax &= 0x04; /* Tempax[2]: HRE[5] */
+ Tempax <<= 3; /* Tempax[5]: HRE[5] */
+ Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
+
+ Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
+ Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
+
+ /* Tempax: CR4 HRS */
+ Tempax = XGI_CRT1Table[index].CR[3];
+ Tempax &= 0x3F; /* Tempax: HRS[5:0] */
+ if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
+ Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
+
+ Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */
+ Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
+ Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
+ Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
+ /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
+ xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
+
+ /* CR10 VRS */
+ Tempax = XGI_CRT1Table[index].CR[10];
+ /* SR34[7:0]->VRS[7:0] */
+ xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
+
+ Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
+ /* CR7[7][2] VRS[9][8] */
+ Tempax = XGI_CRT1Table[index].CR[9];
+ Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
+ Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
+ Tempax >>= 2; /* Tempax[0]: VRS[8] */
+ /* SR35[0]: VRS[8] */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
+ Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
+ Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
+ /* Tempax: SR0A */
+ Tempax = XGI_CRT1Table[index].CR[14];
+ Tempax &= 0x08; /* SR0A[3] VRS[10] */
+ Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
+
+ /* Tempax: CR11 VRE */
+ Tempax = XGI_CRT1Table[index].CR[11];
+ Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
+ /* Tempbx: SR0A */
+ Tempbx = XGI_CRT1Table[index].CR[14];
+ Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
+ Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
+ Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
+ Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
+ Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
+ Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
+
+ if (Tempbx <= Tempcx) /* VRE <= VRS */
+ Tempbx |= 0x20; /* VRE + 0x20 */
+
+ /* Tempax: Tempax[7:0]; VRE[5:0]00 */
+ Tempax = (Tempbx << 2) & 0xFF;
+ /* SR3F[7:2]:VRE[5:0] */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
+ Tempax = Tempcx >> 8;
+ /* SR35[2:0]:VRS[10:8] */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax);
+}
+
+static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
+{
+ unsigned char temp;
+
+ /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
+ temp = (temp & 3) << 6;
+ /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
+ /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
+
+}
+
+static void xgifb_set_lcd(int chip_id,
+ struct vb_device_info *pVBInfo,
+ unsigned short RefreshRateTableIndex)
+{
+ unsigned short temp;
+
+ xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00);
+ xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00);
+ xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00);
+ xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00);
+
+ if (chip_id == XG27) {
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
+ if ((temp & 0x03) == 0) { /* dual 12 */
+ xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13);
+ xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13);
+ }
+ }
+
+ if (chip_id == XG27) {
+ XGI_SetXG27FPBits(pVBInfo);
+ } else {
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
+ if (temp & 0x01) {
+ /* 18 bits FP */
+ xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40);
+ xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40);
+ }
+ }
+
+ xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
+
+ xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
+ xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
+
+ temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ if (temp & 0x4000)
+ /* Hsync polarity */
+ xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
+ if (temp & 0x8000)
+ /* Vsync polarity */
+ xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_UpdateXG21CRTC */
+/* Input : */
+/* Output : CRT1 CRTC */
+/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
+/* --------------------------------------------------------------------- */
+static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
+ struct vb_device_info *pVBInfo,
+ unsigned short RefreshRateTableIndex)
+{
+ int index = -1;
+
+ xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
+ if (ModeNo == 0x2E &&
+ (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
+ RES640x480x60))
+ index = 12;
+ else if (ModeNo == 0x2E && (XGI330_RefIndex[RefreshRateTableIndex].
+ Ext_CRT1CRTC == RES640x480x72))
+ index = 13;
+ else if (ModeNo == 0x2F)
+ index = 14;
+ else if (ModeNo == 0x50)
+ index = 15;
+ else if (ModeNo == 0x59)
+ index = 16;
+
+ if (index != -1) {
+ xgifb_reg_set(pVBInfo->P3d4, 0x02,
+ XGI_UpdateCRT1Table[index].CR02);
+ xgifb_reg_set(pVBInfo->P3d4, 0x03,
+ XGI_UpdateCRT1Table[index].CR03);
+ xgifb_reg_set(pVBInfo->P3d4, 0x15,
+ XGI_UpdateCRT1Table[index].CR15);
+ xgifb_reg_set(pVBInfo->P3d4, 0x16,
+ XGI_UpdateCRT1Table[index].CR16);
+ }
+}
+
+static void XGI_SetCRT1DE(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
+
+ unsigned char data;
+
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempax = XGI330_ModeResInfo[resindex].HTotal;
+ tempbx = XGI330_ModeResInfo[resindex].VTotal;
+
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ if (modeflag & HalfDCLK)
+ tempax = tempax << 1;
+
+ temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+ if (temp & InterlaceMode)
+ tempbx = tempbx >> 1;
+
+ if (modeflag & DoubleScanMode)
+ tempbx = tempbx << 1;
+
+ tempcx = 8;
+
+ tempax /= tempcx;
+ tempax -= 1;
+ tempbx -= 1;
+ tempcx = tempax;
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x11);
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
+ data &= 0x7F;
+ xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+ xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c,
+ (unsigned short) ((tempcx & 0x0ff00) >> 10));
+ xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
+ tempax = 0;
+ tempbx = tempbx >> 8;
+
+ if (tempbx & 0x01)
+ tempax |= 0x02;
+
+ if (tempbx & 0x02)
+ tempax |= 0x40;
+
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax);
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x07);
+ tempax = 0;
+
+ if (tempbx & 0x04)
+ tempax |= 0x02;
+
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
+ xgifb_reg_set(pVBInfo->P3d4, 0x11, temp);
+}
+
+static void XGI_SetCRT1Offset(unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp, ah, al, temp2, i, DisplayUnit;
+
+ /* GetOffset */
+ temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+ temp = temp >> 8;
+ temp = XGI330_ScreenOffset[temp];
+
+ temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp2 &= InterlaceMode;
+
+ if (temp2)
+ temp = temp << 1;
+
+ temp2 = pVBInfo->ModeType - ModeEGA;
+
+ switch (temp2) {
+ case 0:
+ temp2 = 1;
+ break;
+ case 1:
+ temp2 = 2;
+ break;
+ case 2:
+ temp2 = 4;
+ break;
+ case 3:
+ temp2 = 4;
+ break;
+ case 4:
+ temp2 = 6;
+ break;
+ case 5:
+ temp2 = 8;
+ break;
+ default:
+ break;
+ }
+
+ if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
+ temp = temp * temp2 + temp2 / 2;
+ else
+ temp *= temp2;
+
+ /* SetOffset */
+ DisplayUnit = temp;
+ temp2 = temp;
+ temp = temp >> 8; /* ah */
+ temp &= 0x0F;
+ i = xgifb_reg_get(pVBInfo->P3c4, 0x0E);
+ i &= 0xF0;
+ i |= temp;
+ xgifb_reg_set(pVBInfo->P3c4, 0x0E, i);
+
+ temp = (unsigned char) temp2;
+ temp &= 0xFF; /* al */
+ xgifb_reg_set(pVBInfo->P3d4, 0x13, temp);
+
+ /* SetDisplayUnit */
+ temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp2 &= InterlaceMode;
+ if (temp2)
+ DisplayUnit >>= 1;
+
+ DisplayUnit = DisplayUnit << 5;
+ ah = (DisplayUnit & 0xff00) >> 8;
+ al = DisplayUnit & 0x00ff;
+ if (al == 0)
+ ah += 1;
+ else
+ ah += 2;
+
+ if (HwDeviceExtension->jChipType >= XG20)
+ if ((ModeNo == 0x4A) | (ModeNo == 0x49))
+ ah -= 1;
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x10, ah);
+}
+
+static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short VCLKIndex, modeflag;
+
+ /* si+Ext_ResInfo */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/
+ if (pVBInfo->LCDResInfo != Panel_1024x768)
+ /* LCDXlat2VCLK */
+ VCLKIndex = VCLK108_2_315 + 5;
+ else
+ VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */
+ } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ if (pVBInfo->SetFlag & RPLLDIV2XO)
+ VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2;
+ else
+ VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK;
+
+ if (pVBInfo->SetFlag & TVSimuMode) {
+ if (modeflag & Charx8Dot)
+ VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK;
+ else
+ VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK;
+ }
+
+ /* 301lv */
+ if (pVBInfo->VBType & VB_SIS301LV) {
+ if (pVBInfo->SetFlag & RPLLDIV2XO)
+ VCLKIndex = YPbPr525iVCLK_2;
+ else
+ VCLKIndex = YPbPr525iVCLK;
+ }
+ } else if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->SetFlag & RPLLDIV2XO)
+ VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2;
+ else
+ VCLKIndex = TVCLKBASE_315_25 + TVVCLK;
+ } else { /* for CRT2 */
+ /* di+Ext_CRTVCLK */
+ VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ VCLKIndex &= IndexMask;
+ }
+
+ return VCLKIndex;
+}
+
+static void XGI_SetCRT1VCLK(unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char index, data;
+ unsigned short vclkindex;
+
+ if ((pVBInfo->IF_DEF_LVDS == 0) &&
+ (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV |
+ VB_SIS302LV | VB_XGI301C)) &&
+ (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) {
+ vclkindex = XGI_GetVCLK2Ptr(ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
+ xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
+ data = XGI_VBVCLKData[vclkindex].Part4_A;
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
+ data = XGI_VBVCLKData[vclkindex].Part4_B;
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
+ } else {
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
+ xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
+ }
+
+ if (HwDeviceExtension->jChipType >= XG20) {
+ if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag &
+ HalfDCLK) {
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x2C);
+ index = data;
+ index &= 0xE0;
+ data &= 0x1F;
+ data = data << 1;
+ data += 1;
+ data |= index;
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
+ }
+ }
+}
+
+static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
+{
+ unsigned char temp;
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
+ temp = (temp & 1) << 6;
+ /* SR06[6] 18bit Dither */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp);
+ /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
+
+}
+
+static void XGI_SetCRT1FIFO(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data;
+
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
+ data &= 0xfe;
+ xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34);
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
+ data &= 0xC0;
+ xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30);
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
+ data |= 0x01;
+ xgifb_reg_set(pVBInfo->P3c4, 0x3D, data);
+
+ if (HwDeviceExtension->jChipType == XG21)
+ XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
+}
+
+static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data, data2 = 0;
+ short VCLK;
+
+ unsigned char index;
+
+ index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ index &= IndexMask;
+ VCLK = XGI_VCLKData[index].CLOCK;
+
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x32);
+ data &= 0xf3;
+ if (VCLK >= 200)
+ data |= 0x0c; /* VCLK > 200 */
+
+ if (HwDeviceExtension->jChipType >= XG20)
+ data &= ~0x04; /* 2 pixel mode */
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x32, data);
+
+ if (HwDeviceExtension->jChipType < XG20) {
+ data = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
+ data &= 0xE7;
+ if (VCLK < 200)
+ data |= 0x10;
+ xgifb_reg_set(pVBInfo->P3c4, 0x1F, data);
+ }
+
+ data2 = 0x00;
+
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2);
+ if (HwDeviceExtension->jChipType >= XG27)
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
+
+}
+
+static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
+ xres;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+ if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
+
+ data = infoflag;
+ data2 = 0;
+ data2 |= 0x02;
+ data3 = pVBInfo->ModeType - ModeVGA;
+ data3 = data3 << 2;
+ data2 |= data3;
+ data &= InterlaceMode;
+
+ if (data)
+ data2 |= 0x20;
+
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
+
+ data = 0x0000;
+ if (infoflag & InterlaceMode) {
+ if (xres == 1024)
+ data = 0x0035;
+ else if (xres == 1280)
+ data = 0x0048;
+ }
+
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, 0);
+
+ if (modeflag & HalfDCLK)
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
+
+ data2 = 0;
+
+ if (modeflag & LineCompareOff)
+ data2 |= 0x08;
+
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2);
+ data = 0x60;
+ data = data ^ 0x60;
+ data = data ^ 0xA0;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data);
+
+ XGI_SetVCLKState(HwDeviceExtension, RefreshRateTableIndex, pVBInfo);
+
+ data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
+
+ if (HwDeviceExtension->jChipType == XG27) {
+ if (data & 0x40)
+ data = 0x2c;
+ else
+ data = 0x6c;
+ xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
+ xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10);
+ } else if (HwDeviceExtension->jChipType >= XG20) {
+ if (data & 0x40)
+ data = 0x33;
+ else
+ data = 0x73;
+ xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
+ xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02);
+ } else {
+ if (data & 0x40)
+ data = 0x2c;
+ else
+ data = 0x6c;
+ xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
+ }
+
+}
+
+static void XGI_WriteDAC(unsigned short dl,
+ unsigned short ah,
+ unsigned short al,
+ unsigned short dh,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp, 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;
+ }
+ }
+ outb((unsigned short) dh, pVBInfo->P3c9);
+ outb((unsigned short) bh, pVBInfo->P3c9);
+ outb((unsigned short) bl, pVBInfo->P3c9);
+}
+
+static void XGI_LoadDAC(struct vb_device_info *pVBInfo)
+{
+ unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh;
+ const unsigned short *table = XGINew_VGA_DAC;
+
+ outb(0xFF, pVBInfo->P3c6);
+ outb(0x00, pVBInfo->P3c8);
+
+ for (i = 0; i < 16; i++) {
+ data = table[i];
+
+ for (k = 0; k < 3; k++) {
+ data2 = 0;
+
+ if (data & 0x01)
+ data2 = 0x2A;
+
+ if (data & 0x02)
+ data2 += 0x15;
+
+ outb(data2, pVBInfo->P3c9);
+ data = data >> 2;
+ }
+ }
+
+ for (i = 16; i < 32; i++) {
+ data = table[i];
+
+ for (k = 0; k < 3; k++)
+ outb(data, pVBInfo->P3c9);
+ }
+
+ si = 32;
+
+ for (m = 0; m < 9; m++) {
+ di = si;
+ bx = si + 0x04;
+ dl = 0;
+
+ for (n = 0; n < 3; n++) {
+ for (o = 0; o < 5; o++) {
+ dh = table[si];
+ ah = table[di];
+ al = table[bx];
+ si++;
+ XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
+ }
+
+ si -= 2;
+
+ for (o = 0; o < 3; o++) {
+ dh = table[bx];
+ ah = table[di];
+ al = table[si];
+ si--;
+ XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
+ }
+
+ dl++;
+ }
+
+ si += 5;
+ }
+}
+
+static void XGI_GetLVDSResInfo(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short resindex, xres, yres, modeflag;
+
+ /* si+Ext_ResInfo */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+
+ /* si+Ext_ResInfo */
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+
+ xres = XGI330_ModeResInfo[resindex].HTotal;
+ yres = XGI330_ModeResInfo[resindex].VTotal;
+
+ if (modeflag & HalfDCLK)
+ xres = xres << 1;
+
+ if (modeflag & DoubleScanMode)
+ yres = yres << 1;
+
+ if (xres == 720)
+ xres = 640;
+
+ pVBInfo->VGAHDE = xres;
+ pVBInfo->HDE = xres;
+ pVBInfo->VGAVDE = yres;
+ pVBInfo->VDE = yres;
+}
+
+static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table,
+ unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i, tempdx, tempbx, modeflag;
+
+ tempbx = 0;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ i = 0;
+
+ while (table[i].PANELID != 0xff) {
+ tempdx = pVBInfo->LCDResInfo;
+ if (tempbx & 0x0080) { /* OEMUtil */
+ tempbx &= (~0x0080);
+ tempdx = pVBInfo->LCDTypeInfo;
+ }
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempdx &= (~PanelResInfo);
+
+ if (table[i].PANELID == tempdx) {
+ tempbx = table[i].MASK;
+ tempdx = pVBInfo->LCDInfo;
+
+ if (modeflag & HalfDCLK)
+ tempdx |= SetLCDLowResolution;
+
+ tempbx &= tempdx;
+ if (tempbx == table[i].CAP)
+ break;
+ }
+ i++;
+ }
+
+ return table[i].DATAPTR;
+}
+
+static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i, tempdx, tempal, modeflag;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ tempal = tempal & 0x3f;
+ tempdx = pVBInfo->TVInfo;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempdx = tempdx | SetTVLockMode;
+
+ if (modeflag & HalfDCLK)
+ tempdx = tempdx | SetTVLowResolution;
+
+ i = 0;
+
+ while (XGI_TVDataTable[i].MASK != 0xffff) {
+ if ((tempdx & XGI_TVDataTable[i].MASK) ==
+ XGI_TVDataTable[i].CAP)
+ break;
+ i++;
+ }
+
+ return &XGI_TVDataTable[i].DATAPTR[tempal];
+}
+
+static void XGI_GetLVDSData(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ struct SiS_LVDSData const *LCDPtr;
+
+ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
+ return;
+
+ LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeIdIndex, pVBInfo);
+ pVBInfo->VGAHT = LCDPtr->VGAHT;
+ pVBInfo->VGAVT = LCDPtr->VGAVT;
+ pVBInfo->HT = LCDPtr->LCDHT;
+ pVBInfo->VT = LCDPtr->LCDVT;
+
+ if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))
+ return;
+
+ if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
+ (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
+ pVBInfo->HDE = 1024;
+ pVBInfo->VDE = 768;
+ } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
+ (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
+ pVBInfo->HDE = 1280;
+ pVBInfo->VDE = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
+ pVBInfo->HDE = 1400;
+ pVBInfo->VDE = 1050;
+ } else {
+ pVBInfo->HDE = 1600;
+ pVBInfo->VDE = 1200;
+ }
+}
+
+static void XGI_ModCRT1Regs(unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i;
+ struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL;
+ struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+ LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeIdIndex,
+ pVBInfo);
+
+ for (i = 0; i < 8; i++)
+ pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
+ }
+
+ XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+ LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeIdIndex,
+ pVBInfo);
+ for (i = 0; i < 7; i++)
+ pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
+ }
+
+ XGI_SetCRT1Timing_V(ModeIdIndex, pVBInfo);
+}
+
+static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
+{
+ unsigned char tempal, tempah, tempbl, i;
+
+ tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36);
+ tempal = tempah & 0x0F;
+ tempah = tempah & 0xF0;
+ i = 0;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+
+ while (tempbl != 0xFF) {
+ if (tempbl & 0x80) { /* OEMUtil */
+ tempal = tempah;
+ tempbl = tempbl & ~(0x80);
+ }
+
+ if (tempal == tempbl)
+ break;
+
+ i++;
+
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+ }
+
+ return i;
+}
+
+static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempah, tempal, tempbl, i;
+
+ tempal = pVBInfo->LCDResInfo;
+ tempah = pVBInfo->LCDTypeInfo;
+
+ i = 0;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+
+ while (tempbl != 0xFF) {
+ if ((tempbl & 0x80) && (tempbl != 0x80)) {
+ tempal = tempah;
+ tempbl &= ~0x80;
+ }
+
+ if (tempal == tempbl)
+ break;
+
+ i++;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+ }
+
+ if (tempbl == 0xFF) {
+ pVBInfo->LCDResInfo = Panel_1024x768;
+ pVBInfo->LCDTypeInfo = 0;
+ i = 0;
+ }
+
+ return i;
+}
+
+static void XGI_GetLCDSync(unsigned short *HSyncWidth,
+ unsigned short *VSyncWidth,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short Index;
+
+ Index = XGI_GetLCDCapPtr(pVBInfo);
+ *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
+ *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
+}
+
+static void XGI_SetLVDSRegs(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
+ unsigned long temp, temp1, temp2, temp3, push3;
+ struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeIdIndex, pVBInfo);
+
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ push1 = tempbx;
+ push2 = tempax;
+
+ /* GetLCDResInfo */
+ if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
+ (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
+ tempax = 1024;
+ tempbx = 768;
+ } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
+ (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
+ tempax = 1280;
+ tempbx = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
+ tempax = 1400;
+ tempbx = 1050;
+ } else {
+ tempax = 1600;
+ tempbx = 1200;
+ }
+
+ if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
+ pVBInfo->HDE = tempax;
+ pVBInfo->VDE = tempbx;
+ pVBInfo->VGAHDE = tempax;
+ pVBInfo->VGAVDE = tempbx;
+ }
+
+ tempax = pVBInfo->HT;
+
+ tempbx = LCDPtr1->LCDHDES;
+
+ tempcx = pVBInfo->HDE;
+ tempbx = tempbx & 0x0fff;
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
+
+ tempcx = tempcx >> 3;
+ tempbx = tempbx >> 3;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x16,
+ (unsigned short) (tempbx & 0xff));
+ xgifb_reg_set(pVBInfo->Part1Port, 0x17,
+ (unsigned short) (tempcx & 0xff));
+
+ tempax = pVBInfo->HT;
+
+ tempbx = LCDPtr1->LCDHRS;
+
+ tempcx = push2;
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempcx = LCDPtr1->LCDHSync;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ tempax = tempbx & 0x07;
+ tempax = tempax >> 5;
+ tempcx = tempcx >> 3;
+ tempbx = tempbx >> 3;
+
+ tempcx &= 0x1f;
+ tempax |= tempcx;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x14,
+ (unsigned short) (tempbx & 0xff));
+
+ tempax = pVBInfo->VT;
+ tempbx = LCDPtr1->LCDVDES;
+ tempcx = pVBInfo->VDE;
+
+ tempbx = tempbx & 0x0fff;
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x1b,
+ (unsigned short) (tempbx & 0xff));
+ xgifb_reg_set(pVBInfo->Part1Port, 0x1c,
+ (unsigned short) (tempcx & 0xff));
+
+ tempbx = (tempbx >> 8) & 0x07;
+ tempcx = (tempcx >> 8) & 0x07;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x1d,
+ (unsigned short) ((tempcx << 3)
+ | tempbx));
+
+ tempax = pVBInfo->VT;
+ tempbx = LCDPtr1->LCDVRS;
+
+ tempcx = push1;
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempcx = LCDPtr1->LCDVSync;
+
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x18,
+ (unsigned short) (tempbx & 0xff));
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f,
+ (unsigned short) (tempcx & 0x0f));
+
+ tempax = ((tempbx >> 8) & 0x07) << 3;
+
+ tempbx = pVBInfo->VGAVDE;
+ if (tempbx != pVBInfo->VDE)
+ tempax |= 0x40;
+
+ if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA)
+ tempax |= 0x40;
+
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07,
+ tempax);
+
+ tempbx = pVBInfo->VDE;
+ tempax = pVBInfo->VGAVDE;
+
+ temp = tempax; /* 0430 ylshieh */
+ temp1 = (temp << 18) / tempbx;
+
+ tempdx = (unsigned short) ((temp << 18) % tempbx);
+
+ if (tempdx != 0)
+ temp1 += 1;
+
+ temp2 = temp1;
+ push3 = temp2;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x37,
+ (unsigned short) (temp2 & 0xff));
+ xgifb_reg_set(pVBInfo->Part1Port, 0x36,
+ (unsigned short) ((temp2 >> 8) & 0xff));
+
+ tempbx = (unsigned short) (temp2 >> 16);
+ tempax = tempbx & 0x03;
+
+ tempbx = pVBInfo->VGAVDE;
+ if (tempbx == pVBInfo->VDE)
+ tempax |= 0x04;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax);
+
+ if (pVBInfo->VBType & VB_XGI301C) {
+ temp2 = push3;
+ xgifb_reg_set(pVBInfo->Part4Port,
+ 0x3c,
+ (unsigned short) (temp2 & 0xff));
+ xgifb_reg_set(pVBInfo->Part4Port,
+ 0x3b,
+ (unsigned short) ((temp2 >> 8) &
+ 0xff));
+ tempbx = (unsigned short) (temp2 >> 16);
+ xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a,
+ ~0xc0,
+ (unsigned short) ((tempbx &
+ 0xff) << 6));
+
+ tempcx = pVBInfo->VGAVDE;
+ if (tempcx == pVBInfo->VDE)
+ xgifb_reg_and_or(pVBInfo->Part4Port,
+ 0x30, ~0x0c, 0x00);
+ else
+ xgifb_reg_and_or(pVBInfo->Part4Port,
+ 0x30, ~0x0c, 0x08);
+ }
+
+ tempcx = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->HDE;
+
+ temp1 = tempcx << 16;
+
+ tempax = (unsigned short) (temp1 / tempbx);
+
+ if ((tempbx & 0xffff) == (tempcx & 0xffff))
+ tempax = 65535;
+
+ temp3 = tempax;
+ temp1 = pVBInfo->VGAHDE << 16;
+
+ temp1 /= temp3;
+ temp3 = temp3 << 16;
+ temp1 -= 1;
+
+ temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
+
+ tempax = (unsigned short) (temp3 & 0xff);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax);
+
+ temp1 = pVBInfo->VGAVDE << 18;
+ temp1 = temp1 / push3;
+ tempbx = (unsigned short) (temp1 & 0xffff);
+
+ if (pVBInfo->LCDResInfo == Panel_1024x768)
+ tempbx -= 1;
+
+ tempax = ((tempbx >> 8) & 0xff) << 3;
+ tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x20,
+ (unsigned short) (tempax & 0xff));
+ xgifb_reg_set(pVBInfo->Part1Port, 0x21,
+ (unsigned short) (tempbx & 0xff));
+
+ temp3 = temp3 >> 16;
+
+ if (modeflag & HalfDCLK)
+ temp3 = temp3 >> 1;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x22,
+ (unsigned short) ((temp3 >> 8) & 0xff));
+ xgifb_reg_set(pVBInfo->Part1Port, 0x23,
+ (unsigned short) (temp3 & 0xff));
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GETLCDVCLKPtr */
+/* Input : */
+/* Output : al -> VCLK Index */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short index;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+ index = XGI_GetLCDCapPtr1(pVBInfo);
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
+ *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
+ *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
+ } else { /* LCDA */
+ *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
+ *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
+ }
+ }
+}
+
+static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
+ unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+
+ unsigned short index, modeflag;
+ unsigned char tempal;
+
+ /* si+Ext_ResInfo */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
+ (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
+ index = XGI_GetLCDCapPtr(pVBInfo);
+ tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
+ return tempal;
+
+ /* {TV} */
+ if (pVBInfo->VBType &
+ (VB_SIS301B |
+ VB_SIS302B |
+ VB_SIS301LV |
+ VB_SIS302LV |
+ VB_XGI301C)) {
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ tempal = TVCLKBASE_315 + HiTVVCLKDIV2;
+ if (!(pVBInfo->TVInfo & RPLLDIV2XO))
+ tempal = TVCLKBASE_315 + HiTVVCLK;
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ tempal = TVCLKBASE_315 + HiTVSimuVCLK;
+ if (!(modeflag & Charx8Dot))
+ tempal = TVCLKBASE_315 +
+ HiTVTextVCLK;
+
+ }
+ return tempal;
+ }
+
+ if (pVBInfo->TVInfo & TVSetYPbPr750p) {
+ tempal = XGI_YPbPr750pVCLK;
+ return tempal;
+ }
+
+ if (pVBInfo->TVInfo & TVSetYPbPr525p) {
+ tempal = YPbPr525pVCLK;
+ return tempal;
+ }
+
+ tempal = NTSC1024VCLK;
+
+ if (!(pVBInfo->TVInfo & NTSC1024x768)) {
+ tempal = TVCLKBASE_315 + TVVCLKDIV2;
+ if (!(pVBInfo->TVInfo & RPLLDIV2XO))
+ tempal = TVCLKBASE_315 + TVVCLK;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ return tempal;
+ }
+ } /* {End of VB} */
+
+ inb((pVBInfo->P3ca + 0x02));
+ tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ return tempal;
+}
+
+static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
+ unsigned char *di_1, struct vb_device_info *pVBInfo)
+{
+ if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B
+ | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
+ if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
+ (pVBInfo->SetFlag & ProgrammingCRT2)) {
+ *di_0 = XGI_VBVCLKData[tempal].Part4_A;
+ *di_1 = XGI_VBVCLKData[tempal].Part4_B;
+ }
+ } else {
+ *di_0 = XGI_VCLKData[tempal].SR2B;
+ *di_1 = XGI_VCLKData[tempal].SR2C;
+ }
+}
+
+static void XGI_SetCRT2ECLK(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char di_0, di_1, tempal;
+ int i;
+
+ tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo);
+ XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
+ XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
+
+ for (i = 0; i < 4; i++) {
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30,
+ (unsigned short) (0x10 * i));
+ if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
+ && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
+ xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1);
+ } else {
+ xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1);
+ }
+ }
+}
+
+static void XGI_UpdateModeInfo(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempcl, tempch, temp, tempbl, tempax;
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ tempcl = 0;
+ tempch = 0;
+ temp = xgifb_reg_get(pVBInfo->P3c4, 0x01);
+
+ if (!(temp & 0x20)) {
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x17);
+ if (temp & 0x80) {
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x53);
+ if (!(temp & 0x40))
+ tempcl |= ActiveCRT1;
+ }
+ }
+
+ temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e);
+ temp &= 0x0f;
+
+ if (!(temp == 0x08)) {
+ /* Check ChannelA */
+ tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13);
+ if (tempax & 0x04)
+ tempcl = tempcl | ActiveLCD;
+
+ temp &= 0x05;
+
+ if (!(tempcl & ActiveLCD))
+ if (temp == 0x01)
+ tempcl |= ActiveCRT2;
+
+ if (temp == 0x04)
+ tempcl |= ActiveLCD;
+
+ if (temp == 0x05) {
+ temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00);
+
+ if (!(temp & 0x08))
+ tempch |= ActiveAVideo;
+
+ if (!(temp & 0x04))
+ tempch |= ActiveSVideo;
+
+ if (temp & 0x02)
+ tempch |= ActiveSCART;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ if (temp & 0x01)
+ tempch |= ActiveHiTV;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+ temp = xgifb_reg_get(
+ pVBInfo->Part2Port,
+ 0x4d);
+
+ if (temp & 0x10)
+ tempch |= ActiveYPbPr;
+ }
+
+ if (tempch != 0)
+ tempcl |= ActiveTV;
+ }
+ }
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
+ if (tempcl & ActiveLCD) {
+ if ((pVBInfo->SetFlag & ReserveTVOption)) {
+ if (temp & ActiveTV)
+ tempcl |= ActiveTV;
+ }
+ }
+ temp = tempcl;
+ tempbl = ~XGI_ModeSwitchStatus;
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp);
+
+ if (!(pVBInfo->SetFlag & ReserveTVOption))
+ xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch);
+ }
+}
+
+void XGI_GetVBType(struct vb_device_info *pVBInfo)
+{
+ unsigned short flag, tempbx, tempah;
+
+ tempbx = VB_SIS302B;
+ flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
+ if (flag == 0x02)
+ goto finish;
+
+ tempbx = VB_SIS301;
+ flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
+ if (flag < 0xB0)
+ goto finish;
+
+ tempbx = VB_SIS301B;
+ if (flag < 0xC0)
+ goto bigger_than_0xB0;
+
+ tempbx = VB_XGI301C;
+ if (flag < 0xD0)
+ goto bigger_than_0xB0;
+
+ tempbx = VB_SIS301LV;
+ if (flag < 0xE0)
+ goto bigger_than_0xB0;
+
+ tempbx = VB_SIS302LV;
+ tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39);
+ if (tempah != 0xFF)
+ tempbx = VB_XGI301C;
+
+bigger_than_0xB0:
+ if (tempbx & (VB_SIS301B | VB_SIS302B)) {
+ flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23);
+ if (!(flag & 0x02))
+ tempbx = tempbx | VB_NoLCD;
+ }
+
+finish:
+ pVBInfo->VBType = tempbx;
+}
+
+static void XGI_GetVBInfo(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, push, tempbx, temp, modeflag;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ pVBInfo->SetFlag = 0;
+ pVBInfo->ModeType = modeflag & ModeTypeMask;
+ tempbx = 0;
+
+ if (!(pVBInfo->VBType & 0xFFFF))
+ return;
+
+ /* Check Display Device */
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x30);
+ tempbx = tempbx | temp;
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x31);
+ push = temp;
+ push = push << 8;
+ tempax = temp << 8;
+ tempbx = tempbx | tempax;
+ temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA
+ | SetInSlaveMode | DisableCRT2Display);
+ temp = 0xFFFF ^ temp;
+ tempbx &= temp;
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
+
+ if (pVBInfo->VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV |
+ VB_XGI301C)) {
+ if (temp & EnableDualEdge) {
+ tempbx |= SetCRT2ToDualEdge;
+ if (temp & SetToLCDA)
+ tempbx |= XGI_SetCRT2ToLCDA;
+ }
+ }
+
+ if (pVBInfo->VBType & (VB_SIS301LV|VB_SIS302LV|VB_XGI301C)) {
+ if (temp & SetYPbPr) {
+ /* shampoo add for new scratch */
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x35);
+ temp &= YPbPrMode;
+ tempbx |= SetCRT2ToHiVision;
+
+ if (temp != YPbPrMode1080i) {
+ tempbx &= (~SetCRT2ToHiVision);
+ tempbx |= SetCRT2ToYPbPr525750;
+ }
+ }
+ }
+
+ tempax = push; /* restore CR31 */
+
+ temp = 0x09FC;
+
+ if (!(tempbx & temp)) {
+ tempax |= DisableCRT2Display;
+ tempbx = 0;
+ }
+
+ if (!(pVBInfo->VBType & VB_NoLCD)) {
+ if (tempbx & XGI_SetCRT2ToLCDA) {
+ if (tempbx & SetSimuScanMode)
+ tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC |
+ SwitchCRT2));
+ else
+ tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC |
+ SetCRT2ToTV | SwitchCRT2));
+ }
+ }
+
+ /* shampoo add */
+ /* for driver abnormal */
+ if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
+ if (tempbx & SetCRT2ToRAMDAC) {
+ tempbx &= (0xFF00 | SetCRT2ToRAMDAC |
+ SwitchCRT2 | SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
+ }
+ }
+
+ if (!(pVBInfo->VBType & VB_NoLCD)) {
+ if (tempbx & SetCRT2ToLCD) {
+ tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchCRT2 |
+ SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
+ }
+ }
+
+ if (tempbx & SetCRT2ToSCART) {
+ tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchCRT2 |
+ SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
+ }
+
+ if (tempbx & SetCRT2ToYPbPr525750)
+ tempbx &= (0xFF00 | SwitchCRT2 | SetSimuScanMode);
+
+ if (tempbx & SetCRT2ToHiVision)
+ tempbx &= (0xFF00 | SetCRT2ToHiVision | SwitchCRT2 |
+ SetSimuScanMode);
+
+ if (tempax & DisableCRT2Display) { /* Set Display Device Info */
+ if (!(tempbx & (SwitchCRT2 | SetSimuScanMode)))
+ tempbx = DisableCRT2Display;
+ }
+
+ if (!(tempbx & DisableCRT2Display)) {
+ if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) {
+ if (!(tempbx & XGI_SetCRT2ToLCDA))
+ tempbx |= (SetInSlaveMode | SetSimuScanMode);
+ }
+
+ /* LCD+TV can't support in slave mode
+ * (Force LCDA+TV->LCDB) */
+ if ((tempbx & SetInSlaveMode) && (tempbx & XGI_SetCRT2ToLCDA)) {
+ tempbx ^= (SetCRT2ToLCD | XGI_SetCRT2ToLCDA |
+ SetCRT2ToDualEdge);
+ pVBInfo->SetFlag |= ReserveTVOption;
+ }
+ }
+
+ pVBInfo->VBInfo = tempbx;
+}
+
+static void XGI_GetTVInfo(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx = 0, resinfo = 0, modeflag, index1;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+
+ tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35);
+ if (tempbx & TVSetPAL) {
+ tempbx &= (SetCHTVOverScan |
+ TVSetPALM |
+ TVSetPALN |
+ TVSetPAL);
+ if (tempbx & TVSetPALM)
+ /* set to NTSC if PAL-M */
+ tempbx &= ~TVSetPAL;
+ } else
+ tempbx &= (SetCHTVOverScan |
+ TVSetNTSCJ |
+ TVSetPAL);
+
+ if (pVBInfo->VBInfo & SetCRT2ToSCART)
+ tempbx |= TVSetPAL;
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+ index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35);
+ index1 &= YPbPrMode;
+
+ if (index1 == YPbPrMode525i)
+ tempbx |= TVSetYPbPr525i;
+
+ if (index1 == YPbPrMode525p)
+ tempbx = tempbx | TVSetYPbPr525p;
+ if (index1 == YPbPrMode750p)
+ tempbx = tempbx | TVSetYPbPr750p;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision)
+ tempbx = tempbx | TVSetHiVision | TVSetPAL;
+
+ if ((pVBInfo->VBInfo & SetInSlaveMode) &&
+ (!(pVBInfo->VBInfo & SetNotSimuMode)))
+ tempbx |= TVSimuMode;
+
+ if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8))
+ /* NTSC 1024x768, */
+ tempbx |= NTSC1024x768;
+
+ tempbx |= RPLLDIV2XO;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempbx &= (~RPLLDIV2XO);
+ } else if (tempbx & (TVSetYPbPr525p | TVSetYPbPr750p)) {
+ tempbx &= (~RPLLDIV2XO);
+ } else if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B |
+ VB_SIS301LV | VB_SIS302LV |
+ VB_XGI301C))) {
+ if (tempbx & TVSimuMode)
+ tempbx &= (~RPLLDIV2XO);
+ }
+ }
+ pVBInfo->TVInfo = tempbx;
+}
+
+static unsigned char XGI_GetLCDInfo(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp, tempax, tempbx, resinfo = 0, LCDIdIndex;
+
+ pVBInfo->LCDResInfo = 0;
+ pVBInfo->LCDTypeInfo = 0;
+ pVBInfo->LCDInfo = 0;
+
+ /* si+Ext_ResInfo // */
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
+ tempbx = temp & 0x0F;
+
+ if (tempbx == 0)
+ tempbx = Panel_1024x768; /* default */
+
+ /* LCD75 */
+ if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) {
+ if (pVBInfo->VBInfo & DriverMode) {
+ tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33);
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
+ tempax &= 0x0F;
+ else
+ tempax = tempax >> 4;
+
+ if ((resinfo == 6) || (resinfo == 9)) {
+ if (tempax >= 3)
+ tempbx |= PanelRef75Hz;
+ } else if ((resinfo == 7) || (resinfo == 8)) {
+ if (tempax >= 4)
+ tempbx |= PanelRef75Hz;
+ }
+ }
+ }
+
+ pVBInfo->LCDResInfo = tempbx;
+
+ /* End of LCD75 */
+
+ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
+ return 0;
+
+ tempbx = 0;
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
+
+ temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
+
+ tempbx |= temp;
+
+ LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
+
+ tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
+
+ if (((pVBInfo->VBType & VB_SIS302LV) ||
+ (pVBInfo->VBType & VB_XGI301C)) && (tempax & XGI_LCDDualLink))
+ tempbx |= SetLCDDualLink;
+
+ if ((pVBInfo->LCDResInfo == Panel_1400x1050) &&
+ (pVBInfo->VBInfo & SetCRT2ToLCD) && (resinfo == 9) &&
+ (!(tempbx & EnableScalingLCD)))
+ /*
+ * set to center in 1280x1024 LCDB
+ * for Panel_1400x1050
+ */
+ tempbx |= SetLCDtoNonExpanding;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (pVBInfo->VBInfo & SetNotSimuMode)
+ tempbx |= XGI_LCDVESATiming;
+ } else {
+ tempbx |= XGI_LCDVESATiming;
+ }
+
+ pVBInfo->LCDInfo = tempbx;
+
+ return 1;
+}
+
+unsigned char XGI_SearchModeID(unsigned short ModeNo,
+ unsigned short *ModeIdIndex)
+{
+ for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
+ if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
+ break;
+ if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
+ return 0;
+ }
+
+ return 1;
+}
+
+static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
+{
+ unsigned char ujRet = 0;
+ unsigned char i = 0;
+
+ for (i = 0; i < 8; i++) {
+ ujRet = ujRet << 1;
+ ujRet |= (ujDate >> i) & 1;
+ }
+
+ return ujRet;
+}
+
+/*----------------------------------------------------------------------------*/
+/* output */
+/* bl[5] : LVDS signal */
+/* bl[1] : LVDS backlight */
+/* bl[0] : LVDS VDD */
+/*----------------------------------------------------------------------------*/
+static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
+{
+ unsigned char CR4A, temp;
+
+ CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+ xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
+
+ temp = XG21GPIODataTransfer(temp);
+ temp &= 0x23;
+ xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
+ return temp;
+}
+
+/*----------------------------------------------------------------------------*/
+/* output */
+/* bl[5] : LVDS signal */
+/* bl[1] : LVDS backlight */
+/* bl[0] : LVDS VDD */
+/*----------------------------------------------------------------------------*/
+static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
+{
+ unsigned char CR4A, CRB4, temp;
+
+ CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+ xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
+
+ temp &= 0x0C;
+ temp >>= 2;
+ xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
+ CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4);
+ temp |= ((CRB4 & 0x04) << 3);
+ return temp;
+}
+
+/*----------------------------------------------------------------------------*/
+/* input */
+/* bl[5] : 1;LVDS signal on */
+/* bl[1] : 1;LVDS backlight on */
+/* bl[0] : 1:LVDS VDD on */
+/* bh: 100000b : clear bit 5, to set bit5 */
+/* 000010b : clear bit 1, to set bit1 */
+/* 000001b : clear bit 0, to set bit0 */
+/*----------------------------------------------------------------------------*/
+static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char CR4A, temp;
+
+ CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+ tempbh &= 0x23;
+ tempbl &= 0x23;
+ xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
+
+ if (tempbh & 0x20) {
+ temp = (tempbl >> 4) & 0x02;
+
+ /* CR B4[1] */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
+
+ }
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
+
+ temp = XG21GPIODataTransfer(temp);
+ temp &= ~tempbh;
+ temp |= tempbl;
+ xgifb_reg_set(pVBInfo->P3d4, 0x48, temp);
+}
+
+static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char CR4A, temp;
+ unsigned short tempbh0, tempbl0;
+
+ tempbh0 = tempbh;
+ tempbl0 = tempbl;
+ tempbh0 &= 0x20;
+ tempbl0 &= 0x20;
+ tempbh0 >>= 3;
+ tempbl0 >>= 3;
+
+ if (tempbh & 0x20) {
+ temp = (tempbl >> 4) & 0x02;
+
+ /* CR B4[1] */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
+
+ }
+ xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
+
+ CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+ tempbh &= 0x03;
+ tempbl &= 0x03;
+ tempbh <<= 2;
+ tempbl <<= 2; /* GPIOC,GPIOD */
+ xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
+}
+
+static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
+ struct xgi_hw_device_info *pXGIHWDE,
+ struct vb_device_info *pVBInfo)
+{
+
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
+ if (pXGIHWDE->jChipType == XG21) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
+ /* LVDS VDD on */
+ XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo);
+ mdelay(xgifb_info->lvds_data.PSC_S2);
+ }
+ if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
+ /* LVDS signal on */
+ XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
+ mdelay(xgifb_info->lvds_data.PSC_S3);
+ /* LVDS backlight on */
+ XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo);
+ } else {
+ /* DVO/DVI signal on */
+ XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
+ }
+
+ }
+
+ if (pXGIHWDE->jChipType == XG27) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
+ /* LVDS VDD on */
+ XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo);
+ mdelay(xgifb_info->lvds_data.PSC_S2);
+ }
+ if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
+ /* LVDS signal on */
+ XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
+ mdelay(xgifb_info->lvds_data.PSC_S3);
+ /* LVDS backlight on */
+ XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo);
+ } else {
+ /* DVO/DVI signal on */
+ XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
+ }
+
+ }
+}
+
+void XGI_DisplayOff(struct xgifb_video_info *xgifb_info,
+ struct xgi_hw_device_info *pXGIHWDE,
+ struct vb_device_info *pVBInfo)
+{
+
+ if (pXGIHWDE->jChipType == XG21) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ /* LVDS backlight off */
+ XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo);
+ mdelay(xgifb_info->lvds_data.PSC_S3);
+ } else {
+ /* DVO/DVI signal off */
+ XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo);
+ }
+ }
+
+ if (pXGIHWDE->jChipType == XG27) {
+ if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
+ /* LVDS backlight off */
+ XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo);
+ mdelay(xgifb_info->lvds_data.PSC_S3);
+ }
+
+ if (pVBInfo->IF_DEF_LVDS == 0)
+ /* DVO/DVI signal off */
+ XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo);
+ }
+
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
+}
+
+static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
+{
+ while ((inb(pVBInfo->P3da) & 0x01))
+ break;
+
+ while (!(inb(pVBInfo->P3da) & 0x01))
+ break;
+}
+
+static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
+{
+ xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40);
+}
+
+static void XGI_SaveCRT2Info(unsigned short ModeNo,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp1, temp2;
+
+ /* reserve CR34 for CRT1 Mode No */
+ xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo);
+ temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
+ temp2 = ~(SetInSlaveMode >> 8);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1);
+}
+
+static void XGI_GetCRT2ResInfo(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short xres, yres, modeflag, resindex;
+
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
+ /* si+St_ModeFlag */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ if (modeflag & HalfDCLK)
+ xres *= 2;
+
+ if (modeflag & DoubleScanMode)
+ yres *= 2;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+ goto exit;
+
+ if (pVBInfo->LCDResInfo == Panel_1600x1200) {
+ if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
+ if (yres == 1024)
+ yres = 1056;
+ }
+ }
+
+ if (pVBInfo->LCDResInfo == Panel_1280x1024) {
+ if (yres == 400)
+ yres = 405;
+ else if (yres == 350)
+ yres = 360;
+
+ if (pVBInfo->LCDInfo & XGI_LCDVESATiming) {
+ if (yres == 360)
+ yres = 375;
+ }
+ }
+
+ if (pVBInfo->LCDResInfo == Panel_1024x768) {
+ if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
+ if (!(pVBInfo->LCDInfo & LCDNonExpanding)) {
+ if (yres == 350)
+ yres = 357;
+ else if (yres == 400)
+ yres = 420;
+ else if (yres == 480)
+ yres = 525;
+ }
+ }
+ }
+
+ if (xres == 720)
+ xres = 640;
+
+exit:
+ pVBInfo->VGAHDE = xres;
+ pVBInfo->HDE = xres;
+ pVBInfo->VGAVDE = yres;
+ pVBInfo->VDE = yres;
+}
+
+static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
+{
+
+ if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) &&
+ (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
+ return 1;
+
+ return 0;
+}
+
+static void XGI_GetRAMDAC2DATA(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
+ CRT1Index;
+
+ pVBInfo->RVBHCMAX = 1;
+ pVBInfo->RVBHCFACT = 1;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[0];
+ temp2 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[5];
+ tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
+ tempbx = (unsigned short) XGI_CRT1Table[CRT1Index].CR[8];
+ tempcx = (unsigned short)
+ XGI_CRT1Table[CRT1Index].CR[14] << 8;
+ tempcx &= 0x0100;
+ tempcx = tempcx << 2;
+ tempbx |= tempcx;
+ temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[9];
+
+ if (temp1 & 0x01)
+ tempbx |= 0x0100;
+
+ if (temp1 & 0x20)
+ tempbx |= 0x0200;
+ tempax += 5;
+
+ if (modeflag & Charx8Dot)
+ tempax *= 8;
+ else
+ tempax *= 9;
+
+ pVBInfo->VGAHT = tempax;
+ pVBInfo->HT = tempax;
+ tempbx++;
+ pVBInfo->VGAVT = tempbx;
+ pVBInfo->VT = tempbx;
+}
+
+static void XGI_GetCRT2Data(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax = 0, tempbx = 0, modeflag, resinfo;
+
+ struct SiS_LCDData const *LCDPtr = NULL;
+
+ /* si+Ext_ResInfo */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ pVBInfo->NewFlickerMode = 0;
+ pVBInfo->RVBHRS = 50;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ XGI_GetRAMDAC2DATA(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ return;
+ }
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+ LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeIdIndex,
+ pVBInfo);
+
+ pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
+ pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
+ pVBInfo->VGAHT = LCDPtr->VGAHT;
+ pVBInfo->VGAVT = LCDPtr->VGAVT;
+ pVBInfo->HT = LCDPtr->LCDHT;
+ pVBInfo->VT = LCDPtr->LCDVT;
+
+ if (pVBInfo->LCDResInfo == Panel_1024x768) {
+ tempax = 1024;
+ tempbx = 768;
+
+ if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 357)
+ tempbx = 527;
+ else if (pVBInfo->VGAVDE == 420)
+ tempbx = 620;
+ else if (pVBInfo->VGAVDE == 525)
+ tempbx = 775;
+ else if (pVBInfo->VGAVDE == 600)
+ tempbx = 775;
+ }
+ } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) {
+ tempax = 1024;
+ tempbx = 768;
+ } else if (pVBInfo->LCDResInfo == Panel_1280x1024) {
+ tempax = 1280;
+ if (pVBInfo->VGAVDE == 360)
+ tempbx = 768;
+ else if (pVBInfo->VGAVDE == 375)
+ tempbx = 800;
+ else if (pVBInfo->VGAVDE == 405)
+ tempbx = 864;
+ else
+ tempbx = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) {
+ tempax = 1280;
+ tempbx = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel_1280x960) {
+ tempax = 1280;
+ if (pVBInfo->VGAVDE == 350)
+ tempbx = 700;
+ else if (pVBInfo->VGAVDE == 400)
+ tempbx = 800;
+ else if (pVBInfo->VGAVDE == 1024)
+ tempbx = 960;
+ else
+ tempbx = 960;
+ } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
+ tempax = 1400;
+ tempbx = 1050;
+
+ if (pVBInfo->VGAVDE == 1024) {
+ tempax = 1280;
+ tempbx = 1024;
+ }
+ } else if (pVBInfo->LCDResInfo == Panel_1600x1200) {
+ tempax = 1600;
+ tempbx = 1200; /* alan 10/14/2003 */
+ if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 350)
+ tempbx = 875;
+ else if (pVBInfo->VGAVDE == 400)
+ tempbx = 1000;
+ }
+ }
+
+ if (pVBInfo->LCDInfo & LCDNonExpanding) {
+ tempax = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->VGAVDE;
+ }
+
+ pVBInfo->HDE = tempax;
+ pVBInfo->VDE = tempbx;
+ return;
+ }
+
+ if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
+ struct SiS_TVData const *TVPtr;
+
+ TVPtr = XGI_GetTVPtr(ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+
+ pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
+ pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
+ pVBInfo->VGAHT = TVPtr->VGAHT;
+ pVBInfo->VGAVT = TVPtr->VGAVT;
+ pVBInfo->HDE = TVPtr->TVHDE;
+ pVBInfo->VDE = TVPtr->TVVDE;
+ pVBInfo->RVBHRS = TVPtr->RVBHRS;
+ pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ if (resinfo == 0x08)
+ pVBInfo->NewFlickerMode = 0x40;
+ else if (resinfo == 0x09)
+ pVBInfo->NewFlickerMode = 0x40;
+ else if (resinfo == 0x12)
+ pVBInfo->NewFlickerMode = 0x40;
+
+ if (pVBInfo->VGAVDE == 350)
+ pVBInfo->TVInfo |= TVSimuMode;
+
+ tempax = ExtHiTVHT;
+ tempbx = ExtHiTVVT;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ tempax = StHiTVHT;
+ tempbx = StHiTVVT;
+
+ if (!(modeflag & Charx8Dot)) {
+ tempax = StHiTextTVHT;
+ tempbx = StHiTextTVVT;
+ }
+ }
+ }
+ } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+ if (pVBInfo->TVInfo & TVSetYPbPr750p) {
+ tempax = YPbPrTV750pHT; /* Ext750pTVHT */
+ tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
+ }
+
+ if (pVBInfo->TVInfo & TVSetYPbPr525p) {
+ tempax = YPbPrTV525pHT; /* Ext525pTVHT */
+ tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
+ } else if (pVBInfo->TVInfo & TVSetYPbPr525i) {
+ tempax = YPbPrTV525iHT; /* Ext525iTVHT */
+ tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
+ if (pVBInfo->TVInfo & NTSC1024x768)
+ tempax = NTSC1024x768HT;
+ }
+ } else {
+ tempax = PALHT;
+ tempbx = PALVT;
+ if (!(pVBInfo->TVInfo & TVSetPAL)) {
+ tempax = NTSCHT;
+ tempbx = NTSCVT;
+ if (pVBInfo->TVInfo & NTSC1024x768)
+ tempax = NTSC1024x768HT;
+ }
+ }
+
+ pVBInfo->HT = tempax;
+ pVBInfo->VT = tempbx;
+ }
+}
+
+static void XGI_SetCRT2VCLK(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char di_0, di_1, tempal;
+
+ tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeIdIndex, pVBInfo);
+ XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
+ XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
+
+ if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */
+ /* 301 */
+ xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
+ } else { /* 301b/302b/301lv/302lv */
+ xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
+ }
+
+ xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12);
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
+ xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28);
+ else
+ xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08);
+}
+
+static unsigned short XGI_GetColorDepth(unsigned short ModeIdIndex)
+{
+ unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
+ short index;
+ unsigned short modeflag;
+
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ index = (modeflag & ModeTypeMask) - ModeEGA;
+
+ if (index < 0)
+ index = 0;
+
+ return ColorDepth[index];
+}
+
+static unsigned short XGI_GetOffset(unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
+{
+ unsigned short temp, colordepth, modeinfo, index, infoflag,
+ ColorDepth[] = { 0x01, 0x02, 0x04 };
+
+ modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+ infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+ index = (modeinfo >> 8) & 0xFF;
+
+ temp = XGI330_ScreenOffset[index];
+
+ if (infoflag & InterlaceMode)
+ temp = temp << 1;
+
+ colordepth = XGI_GetColorDepth(ModeIdIndex);
+
+ if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
+ temp = ModeNo - 0x7C;
+ colordepth = ColorDepth[temp];
+ temp = 0x6B;
+ if (infoflag & InterlaceMode)
+ temp = temp << 1;
+ }
+ return temp * colordepth;
+}
+
+static void XGI_SetCRT2Offset(unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short offset;
+ unsigned char temp;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ return;
+
+ offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ temp = (unsigned char) (offset & 0xFF);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
+ temp = (unsigned char) ((offset & 0xFF00) >> 8);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp);
+ temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
+}
+
+static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
+{
+ /* threshold high ,disable auto threshold */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B);
+ /* threshold low default 04h */
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04);
+}
+
+static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ u8 tempcx;
+
+ XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT2FIFO(pVBInfo);
+
+ for (tempcx = 4; tempcx < 7; tempcx++)
+ xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0);
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
+}
+
+static void XGI_SetGroup1(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
+ pushbx = 0, CRT1Index, modeflag;
+
+ CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ /* bainy change table name */
+ if (modeflag & HalfDCLK) {
+ /* BTVGA2HT 0x08,0x09 */
+ temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
+ temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
+ /* BTVGA2HDEE 0x0A,0x0C */
+ temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
+ tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
+ pushbx = pVBInfo->VGAHDE / 2 + 16;
+ tempcx = tempcx >> 1;
+ tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+ tempcx += tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = XGI_CRT1Table[CRT1Index].CR[4];
+ tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] &
+ 0xC0) << 2);
+ tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+ tempcx = XGI_CRT1Table[CRT1Index].CR[5];
+ tempcx &= 0x1F;
+ temp = XGI_CRT1Table[CRT1Index].CR[15];
+ temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+ }
+
+ tempbx += 4;
+ tempcx += 4;
+
+ if (tempcx > (pVBInfo->VGAHT / 2))
+ tempcx = pVBInfo->VGAHT / 2;
+
+ temp = tempbx & 0x00FF;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
+ } else {
+ temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
+ temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
+ /* BTVGA2HDEE 0x0A,0x0C */
+ temp = (pVBInfo->VGAHDE + 16) & 0x0FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
+ tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
+ pushbx = pVBInfo->VGAHDE + 16;
+ tempcx = tempcx >> 1;
+ tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+ tempcx += tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = XGI_CRT1Table[CRT1Index].CR[3];
+ tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] &
+ 0xC0) << 2);
+ tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+ tempcx = XGI_CRT1Table[CRT1Index].CR[4];
+ tempcx &= 0x1F;
+ temp = XGI_CRT1Table[CRT1Index].CR[6];
+ temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+ tempbx += 16;
+ tempcx += 16;
+ }
+
+ if (tempcx > pVBInfo->VGAHT)
+ tempcx = pVBInfo->VGAHT;
+
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
+ }
+
+ tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
+ tempbx = pushbx;
+ tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+ tempax |= (tempbx & 0xFF00);
+ temp = (tempax & 0xFF00) >> 8;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
+ tempcx = (pVBInfo->VGAVT - 1);
+ temp = tempcx & 0x00FF;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
+ tempbx = pVBInfo->VGAVDE - 1;
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp);
+ temp = ((tempbx & 0xFF00) << 3) >> 8;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp);
+
+ /* BTVGA2VRS 0x10,0x11 */
+ tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1;
+ /* BTVGA2VRE 0x11 */
+ tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = XGI_CRT1Table[CRT1Index].CR[10];
+ temp = XGI_CRT1Table[CRT1Index].CR[9];
+
+ if (temp & 0x04)
+ tempbx |= 0x0100;
+
+ if (temp & 0x080)
+ tempbx |= 0x0200;
+
+ temp = XGI_CRT1Table[CRT1Index].CR[14];
+
+ if (temp & 0x08)
+ tempbx |= 0x0400;
+
+ temp = XGI_CRT1Table[CRT1Index].CR[11];
+ tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
+ }
+
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ temp = ((tempcx & 0x000F) | (temp));
+ xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp);
+ tempax = 0;
+
+ if (modeflag & DoubleScanMode)
+ tempax |= 0x80;
+
+ if (modeflag & HalfDCLK)
+ tempax |= 0x40;
+
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
+}
+
+static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
+{
+ unsigned long tempax, tempbx;
+
+ tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
+ & 0xFFFF;
+ tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
+ tempax = (tempax * pVBInfo->HT) / tempbx;
+
+ return (unsigned short) tempax;
+}
+
+static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
+ modeflag;
+
+ /* si+Ext_ResInfo */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+
+ if (!(pVBInfo->VBInfo & SetInSlaveMode))
+ return;
+
+ temp = 0xFF; /* set MAX HT */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
+ tempcx = 0x08;
+
+ if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
+ modeflag |= Charx8Dot;
+
+ tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
+
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ tempax = (tempax / tempcx) - 1;
+ tempbx |= ((tempax & 0x00FF) << 8);
+ temp = tempax & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp);
+
+ temp = (tempbx & 0xFF00) >> 8;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)))
+ temp += 2;
+
+ if ((pVBInfo->VBInfo & SetCRT2ToHiVision) &&
+ !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7))
+ temp -= 2;
+ }
+
+ /* 0x05 Horizontal Display Start */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp);
+ /* 0x06 Horizontal Blank end */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03);
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ tempax = pVBInfo->VGAHT;
+ else
+ tempax = XGI_GetVGAHT2(pVBInfo);
+ }
+
+ if (tempax >= pVBInfo->VGAHT)
+ tempax = pVBInfo->VGAHT;
+
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ tempax = (tempax / tempcx) - 5;
+ tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ temp = (tempbx & 0x00FF) - 1;
+ if (!(modeflag & HalfDCLK)) {
+ temp -= 6;
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ temp -= 4;
+ temp -= 10;
+ }
+ }
+ } else {
+ tempbx = (tempbx & 0xFF00) >> 8;
+ tempcx = (tempcx + tempbx) >> 1;
+ temp = (tempcx & 0x00FF) + 2;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ temp -= 1;
+ if (!(modeflag & HalfDCLK)) {
+ if ((modeflag & Charx8Dot)) {
+ temp += 4;
+ if (pVBInfo->VGAHDE >= 800)
+ temp -= 6;
+ }
+ }
+ } else if (!(modeflag & HalfDCLK)) {
+ temp -= 4;
+ if (pVBInfo->LCDResInfo != Panel_1280x960 &&
+ pVBInfo->VGAHDE >= 800) {
+ temp -= 7;
+ if (pVBInfo->VGAHDE >= 1280 &&
+ pVBInfo->LCDResInfo != Panel_1280x960 &&
+ (pVBInfo->LCDInfo & LCDNonExpanding))
+ temp += 28;
+ }
+ }
+ }
+
+ /* 0x07 Horizontal Retrace Start */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
+ /* 0x08 Horizontal Retrace End */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0);
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ if (ModeNo == 0x50) {
+ if (pVBInfo->TVInfo == SetNTSCTV) {
+ xgifb_reg_set(pVBInfo->Part1Port,
+ 0x07, 0x30);
+ xgifb_reg_set(pVBInfo->Part1Port,
+ 0x08, 0x03);
+ } else {
+ xgifb_reg_set(pVBInfo->Part1Port,
+ 0x07, 0x2f);
+ xgifb_reg_set(pVBInfo->Part1Port,
+ 0x08, 0x02);
+ }
+ }
+ }
+ }
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
+ xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
+
+ tempbx = pVBInfo->VGAVT;
+ push1 = tempbx;
+ tempcx = 0x121;
+ tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
+
+ if (tempbx == 357)
+ tempbx = 350;
+ if (tempbx == 360)
+ tempbx = 350;
+ if (tempbx == 375)
+ tempbx = 350;
+ if (tempbx == 405)
+ tempbx = 400;
+ if (tempbx == 525)
+ tempbx = 480;
+
+ push2 = tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ if (pVBInfo->LCDResInfo == Panel_1024x768) {
+ if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
+ if (tempbx == 350)
+ tempbx += 5;
+ if (tempbx == 480)
+ tempbx += 5;
+ }
+ }
+ }
+ tempbx--;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ /* 0x10 vertical Blank Start */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
+ tempbx = push2;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
+
+ if (tempbx & 0x0100)
+ tempcx |= 0x0002;
+
+ tempax = 0x000B;
+
+ if (modeflag & DoubleScanMode)
+ tempax |= 0x08000;
+
+ if (tempbx & 0x0200)
+ tempcx |= 0x0040;
+
+ temp = (tempax & 0xFF00) >> 8;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
+
+ if (tempbx & 0x0400)
+ tempcx |= 0x0600;
+
+ /* 0x11 Vertival Blank End */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00);
+
+ tempax = push1;
+ tempax -= tempbx; /* 0x0C Vertical Retrace Start */
+ tempax = tempax >> 2;
+ push1 = tempax; /* push ax */
+
+ if (resinfo != 0x09) {
+ tempax = tempax << 1;
+ tempbx += tempax;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ if ((pVBInfo->VBType & VB_SIS301LV) &&
+ !(pVBInfo->TVInfo & TVSetHiVision)) {
+ if ((pVBInfo->TVInfo & TVSimuMode) &&
+ (pVBInfo->TVInfo & TVSetPAL)) {
+ if (!(pVBInfo->VBType & VB_SIS301LV) ||
+ !(pVBInfo->TVInfo &
+ (TVSetYPbPr525p |
+ TVSetYPbPr750p |
+ TVSetHiVision)))
+ tempbx += 40;
+ }
+ } else {
+ tempbx -= 10;
+ }
+ } else if (pVBInfo->TVInfo & TVSimuMode) {
+ if (pVBInfo->TVInfo & TVSetPAL) {
+ if (pVBInfo->VBType & VB_SIS301LV) {
+ if (!(pVBInfo->TVInfo &
+ (TVSetYPbPr525p |
+ TVSetYPbPr750p |
+ TVSetHiVision)))
+ tempbx += 40;
+ } else {
+ tempbx += 40;
+ }
+ }
+ }
+ tempax = push1;
+ tempax = tempax >> 2;
+ tempax++;
+ tempax += tempbx;
+ push1 = tempax; /* push ax */
+
+ if ((pVBInfo->TVInfo & TVSetPAL)) {
+ if (tempbx <= 513) {
+ if (tempax >= 513)
+ tempbx = 513;
+ }
+ }
+
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
+
+ if (tempbx & 0x0100)
+ tempcx |= 0x0008;
+
+ if (tempbx & 0x0200)
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
+
+ tempbx++;
+
+ if (tempbx & 0x0100)
+ tempcx |= 0x0004;
+
+ if (tempbx & 0x0200)
+ tempcx |= 0x0080;
+
+ if (tempbx & 0x0400)
+ tempcx |= 0x0C00;
+
+ tempbx = push1; /* pop ax */
+ temp = tempbx & 0x00FF;
+ temp &= 0x0F;
+ /* 0x0D vertical Retrace End */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
+
+ if (tempbx & 0x0010)
+ tempcx |= 0x2000;
+
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
+ temp = (tempcx & 0x0FF00) >> 8;
+ xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
+ tempax = modeflag;
+ temp = (tempax & 0xFF00) >> 8;
+
+ temp = (temp >> 1) & 0x09;
+
+ if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
+ temp |= 0x01;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
+
+ if (pVBInfo->LCDInfo & LCDRGB18Bit)
+ temp = 0x80;
+ else
+ temp = 0x00;
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
+}
+
+static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
+ modeflag;
+ unsigned char const *TimingPoint;
+
+ unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
+
+ /* si+Ext_ResInfo */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ tempax = 0;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
+ tempax |= 0x0800;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ tempax |= 0x0400;
+
+ if (pVBInfo->VBInfo & SetCRT2ToSCART)
+ tempax |= 0x0200;
+
+ if (!(pVBInfo->TVInfo & TVSetPAL))
+ tempax |= 0x1000;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision)
+ tempax |= 0x0100;
+
+ if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
+ tempax &= 0xfe00;
+
+ tempax = (tempax & 0xff00) >> 8;
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax);
+ TimingPoint = XGI330_NTSCTiming;
+
+ if (pVBInfo->TVInfo & TVSetPAL)
+ TimingPoint = XGI330_PALTiming;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ TimingPoint = XGI330_HiTVExtTiming;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ TimingPoint = XGI330_HiTVSt2Timing;
+
+ if (pVBInfo->SetFlag & TVSimuMode)
+ TimingPoint = XGI330_HiTVSt1Timing;
+
+ if (!(modeflag & Charx8Dot))
+ TimingPoint = XGI330_HiTVTextTiming;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+ if (pVBInfo->TVInfo & TVSetYPbPr525i)
+ TimingPoint = XGI330_YPbPr525iTiming;
+
+ if (pVBInfo->TVInfo & TVSetYPbPr525p)
+ TimingPoint = XGI330_YPbPr525pTiming;
+
+ if (pVBInfo->TVInfo & TVSetYPbPr750p)
+ TimingPoint = XGI330_YPbPr750pTiming;
+ }
+
+ for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
+ xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
+
+ for (i = 0x39; i <= 0x45; i++, j++)
+ /* di->temp2[j] */
+ xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
+
+ temp = pVBInfo->NewFlickerMode;
+ temp &= 0x80;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
+
+ if (pVBInfo->TVInfo & TVSetPAL)
+ tempax = 520;
+ else
+ tempax = 440;
+
+ if (pVBInfo->VDE <= tempax) {
+ tempax -= pVBInfo->VDE;
+ tempax = tempax >> 2;
+ tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+ push1 = tempax;
+ temp = (tempax & 0xFF00) >> 8;
+ temp += (unsigned short) TimingPoint[0];
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
+ | SetCRT2ToSVIDEO | SetCRT2ToSCART
+ | SetCRT2ToYPbPr525750)) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= 1024) {
+ temp = 0x17; /* NTSC */
+ if (pVBInfo->TVInfo & TVSetPAL)
+ temp = 0x19; /* PAL */
+ }
+ }
+ }
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
+ tempax = push1;
+ temp = (tempax & 0xFF00) >> 8;
+ temp += TimingPoint[1];
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
+ | SetCRT2ToSVIDEO | SetCRT2ToSCART
+ | SetCRT2ToYPbPr525750))) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= 1024) {
+ temp = 0x1D; /* NTSC */
+ if (pVBInfo->TVInfo & TVSetPAL)
+ temp = 0x52; /* PAL */
+ }
+ }
+ }
+ xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp);
+ }
+
+ /* 301b */
+ tempcx = pVBInfo->HT;
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempcx = tempcx >> 1;
+
+ tempcx -= 2;
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp);
+
+ temp = (tempcx & 0xFF00) >> 8;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
+
+ tempcx = pVBInfo->HT >> 1;
+ push1 = tempcx; /* push cx */
+ tempcx += 7;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision)
+ tempcx -= 4;
+
+ temp = tempcx & 0x00FF;
+ temp = temp << 4;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp);
+
+ tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+ tempbx += tempcx;
+ push2 = tempbx;
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp);
+
+ tempbx = push2;
+ tempbx = tempbx + 8;
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ tempbx = tempbx - 4;
+ tempcx = tempbx;
+ }
+
+ temp = (tempbx & 0x00FF) << 4;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp);
+
+ j += 2;
+ tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp);
+ temp = ((tempcx & 0xFF00) >> 8) << 4;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp);
+
+ tempcx += 8;
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision)
+ tempcx -= 4;
+
+ temp = tempcx & 0xFF;
+ temp = temp << 4;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
+
+ tempcx = push1; /* pop cx */
+ j += 2;
+ temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+ tempcx -= temp;
+ temp = tempcx & 0x00FF;
+ temp = temp << 4;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
+
+ tempcx -= 11;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+ tempax = XGI_GetVGAHT2(pVBInfo);
+ tempcx = tempax - 1;
+ }
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp);
+
+ tempbx = pVBInfo->VDE;
+
+ if (pVBInfo->VGAVDE == 360)
+ tempbx = 746;
+ if (pVBInfo->VGAVDE == 375)
+ tempbx = 746;
+ if (pVBInfo->VGAVDE == 405)
+ tempbx = 853;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->VBType &
+ (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
+ if (!(pVBInfo->TVInfo &
+ (TVSetYPbPr525p | TVSetYPbPr750p)))
+ tempbx = tempbx >> 1;
+ } else
+ tempbx = tempbx >> 1;
+ }
+
+ tempbx -= 2;
+ temp = tempbx & 0x00FF;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ if (pVBInfo->VBType & VB_SIS301LV) {
+ if (pVBInfo->TVInfo & TVSetHiVision) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (ModeNo == 0x2f)
+ temp += 1;
+ }
+ }
+ } else if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (ModeNo == 0x2f)
+ temp += 1;
+ }
+ }
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp);
+
+ temp = (tempcx & 0xFF00) >> 8;
+ temp |= ((tempbx & 0xFF00) >> 8) << 6;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
+ if (pVBInfo->VBType & VB_SIS301LV) {
+ if (pVBInfo->TVInfo & TVSetHiVision) {
+ temp |= 0x10;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ temp |= 0x20;
+ }
+ } else {
+ temp |= 0x10;
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ temp |= 0x20;
+ }
+ }
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp);
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */
+ tempbx = pVBInfo->VDE;
+ tempcx = tempbx - 2;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!(pVBInfo->TVInfo & (TVSetYPbPr525p
+ | TVSetYPbPr750p)))
+ tempbx = tempbx >> 1;
+ }
+
+ if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
+ temp = 0;
+ if (tempcx & 0x0400)
+ temp |= 0x20;
+
+ if (tempbx & 0x0400)
+ temp |= 0x40;
+
+ xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp);
+ }
+
+ temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp);
+ temp = (tempbx - 3) & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp);
+ }
+
+ tempbx = tempbx & 0x00FF;
+
+ if (!(modeflag & HalfDCLK)) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= pVBInfo->HDE) {
+ tempbx |= 0x2000;
+ tempax &= 0x00FF;
+ }
+ }
+
+ tempcx = 0x0101;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
+ if (pVBInfo->VGAHDE >= 1024) {
+ tempcx = 0x1920;
+ if (pVBInfo->VGAHDE >= 1280) {
+ tempcx = 0x1420;
+ tempbx = tempbx & 0xDFFF;
+ }
+ }
+ }
+
+ if (!(tempbx & 0x2000)) {
+ if (modeflag & HalfDCLK)
+ tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
+
+ push1 = tempbx;
+ tempeax = pVBInfo->VGAHDE;
+ tempebx = (tempcx & 0xFF00) >> 8;
+ longtemp = tempeax * tempebx;
+ tempecx = tempcx & 0x00FF;
+ longtemp = longtemp / tempecx;
+
+ /* 301b */
+ tempecx = 8 * 1024;
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ tempecx = tempecx * 8;
+ }
+
+ longtemp = longtemp * tempecx;
+ tempecx = pVBInfo->HDE;
+ temp2 = longtemp % tempecx;
+ tempeax = longtemp / tempecx;
+ if (temp2 != 0)
+ tempeax += 1;
+
+ tempax = (unsigned short) tempeax;
+
+ /* 301b */
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ tempcx = ((tempax & 0xFF00) >> 5) >> 8;
+ }
+ /* end 301b */
+
+ tempbx = push1;
+ tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
+ | (tempbx & 0x00FF));
+ tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
+ | (tempax & 0x00FF));
+ temp = (tempax & 0xFF00) >> 8;
+ } else {
+ temp = (tempax & 0x00FF) >> 8;
+ }
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
+ temp = tempcx & 0x00FF;
+
+ if (tempbx & 0x2000)
+ temp = 0;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+ temp |= 0x18;
+
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
+ if (pVBInfo->TVInfo & TVSetPAL) {
+ tempbx = 0x0382;
+ tempcx = 0x007e;
+ } else {
+ tempbx = 0x0369;
+ tempcx = 0x0061;
+ }
+
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp);
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp);
+
+ temp = ((tempcx & 0xFF00) >> 8) & 0x03;
+ temp = temp << 2;
+ temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+ temp |= 0x10;
+
+ if (pVBInfo->TVInfo & TVSetYPbPr525p)
+ temp |= 0x20;
+
+ if (pVBInfo->TVInfo & TVSetYPbPr750p)
+ temp |= 0x60;
+ }
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp);
+ temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */
+ xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
+
+ if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) {
+ if (pVBInfo->TVInfo & NTSC1024x768) {
+ TimingPoint = XGI_NTSC1024AdjTime;
+ for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
+ xgifb_reg_set(pVBInfo->Part2Port, i,
+ TimingPoint[j]);
+ }
+ xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72);
+ }
+ }
+
+ /* Modify for 301C PALM Support */
+ if (pVBInfo->VBType & VB_XGI301C) {
+ if (pVBInfo->TVInfo & TVSetPALM)
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08,
+ 0x08); /* PALM Mode */
+ }
+
+ if (pVBInfo->TVInfo & TVSetPALM) {
+ tempax = xgifb_reg_get(pVBInfo->Part2Port, 0x01);
+ tempax--;
+ xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax);
+
+ xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF);
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+ if (!(pVBInfo->VBInfo & SetInSlaveMode))
+ xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00);
+ }
+}
+
+static void XGI_SetLCDRegs(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short pushbx, tempax, tempbx, tempcx, temp, tempah,
+ tempbh, tempch;
+
+ struct XGI_LCDDesStruct const *LCDBDesPtr = NULL;
+
+ /* si+Ext_ResInfo */
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+ return;
+
+ tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+
+ tempbx -= 1;
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
+ temp = 0x01;
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp);
+ tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp);
+ temp = ((tempbx & 0xFF00) >> 8) & 0x07;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
+
+ tempcx = pVBInfo->VT - 1;
+ temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
+ xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp);
+ temp = (tempcx & 0xFF00) >> 8;
+ temp = temp << 5;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp);
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
+
+ /* Customized LCDB Does not add */
+ if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
+ LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeIdIndex,
+ pVBInfo);
+ else
+ LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeIdIndex,
+ pVBInfo);
+
+ tempah = pVBInfo->LCDResInfo;
+ tempah &= PanelResInfo;
+
+ if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) {
+ tempbx = 1024;
+ tempcx = 768;
+ } else if ((tempah == Panel_1280x1024) ||
+ (tempah == Panel_1280x1024x75)) {
+ tempbx = 1280;
+ tempcx = 1024;
+ } else if (tempah == Panel_1400x1050) {
+ tempbx = 1400;
+ tempcx = 1050;
+ } else {
+ tempbx = 1600;
+ tempcx = 1200;
+ }
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD) {
+ tempbx = pVBInfo->HDE;
+ tempcx = pVBInfo->VDE;
+ }
+
+ pushbx = tempbx;
+ tempax = pVBInfo->VT;
+ pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
+ pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
+ pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
+ pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
+ tempbx = pVBInfo->LCDVDES;
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax; /* lcdvdes */
+
+ temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
+ xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp);
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp);
+ tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
+ tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
+ tempah = tempch;
+ tempah = tempah << 3;
+ tempah |= tempbh;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah);
+
+ /* getlcdsync() */
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ tempcx = tempbx;
+ tempax = pVBInfo->VT;
+ tempbx = pVBInfo->LCDVRS;
+
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
+ xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ temp |= (tempcx & 0x000F);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
+ tempcx = pushbx;
+ tempax = pVBInfo->HT;
+ tempbx = pVBInfo->LCDHDES;
+ tempbx &= 0x0FFF;
+
+ if (XGI_IsLCDDualLink(pVBInfo)) {
+ tempax = tempax >> 1;
+ tempbx = tempbx >> 1;
+ tempcx = tempcx >> 1;
+ }
+
+ if (pVBInfo->VBType & VB_SIS302LV)
+ tempbx += 1;
+
+ if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
+ tempbx += 1;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp);
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
+ temp = (tempcx & 0xFF00) >> 8;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp);
+
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ tempcx = tempax;
+ tempax = pVBInfo->HT;
+ tempbx = pVBInfo->LCDHRS;
+ if (XGI_IsLCDDualLink(pVBInfo)) {
+ tempax = tempax >> 1;
+ tempbx = tempbx >> 1;
+ tempcx = tempcx >> 1;
+ }
+
+ if (pVBInfo->VBType & VB_SIS302LV)
+ tempbx += 1;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
+ xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp);
+
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
+ temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
+ xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp);
+
+ if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 525) {
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
+ | VB_SIS301LV | VB_SIS302LV
+ | VB_XGI301C)) {
+ temp = 0xC6;
+ } else
+ temp = 0xC4;
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3);
+ }
+
+ if (pVBInfo->VGAVDE == 420) {
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
+ | VB_SIS301LV | VB_SIS302LV
+ | VB_XGI301C)) {
+ temp = 0x4F;
+ } else
+ temp = 0x4E;
+ xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
+ }
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTap4Ptr */
+/* Input : */
+/* Output : di -> Tap4 Reg. Setting Pointer */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static struct XGI301C_Tap4TimingStruct const
+*XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, tempbx, i;
+ struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
+
+ if (tempcx == 0) {
+ tempax = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->HDE;
+ } else {
+ tempax = pVBInfo->VGAVDE;
+ tempbx = pVBInfo->VDE;
+ }
+
+ if (tempax <= tempbx)
+ return &xgifb_tap4_timing[0];
+ Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */
+
+ if (pVBInfo->TVInfo & TVSetPAL)
+ Tap4TimingPtr = PALTap4Timing;
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+ if ((pVBInfo->TVInfo & TVSetYPbPr525i) ||
+ (pVBInfo->TVInfo & TVSetYPbPr525p))
+ Tap4TimingPtr = xgifb_ntsc_525_tap4_timing;
+ if (pVBInfo->TVInfo & TVSetYPbPr750p)
+ Tap4TimingPtr = YPbPr750pTap4Timing;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVision)
+ Tap4TimingPtr = xgifb_tap4_timing;
+
+ i = 0;
+ while (Tap4TimingPtr[i].DE != 0xFFFF) {
+ if (Tap4TimingPtr[i].DE == tempax)
+ break;
+ i++;
+ }
+ return &Tap4TimingPtr[i];
+}
+
+static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
+{
+ unsigned short i, j;
+ struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
+
+ if (!(pVBInfo->VBType & VB_XGI301C))
+ return;
+
+ Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
+ for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
+ xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
+
+ if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
+ (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) {
+ /* Set Vertical Scaling */
+ Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
+ for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
+ xgifb_reg_set(pVBInfo->Part2Port,
+ i,
+ Tap4TimingPtr->Reg[j]);
+ }
+
+ if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
+ (!(pVBInfo->VBInfo & SetCRT2ToHiVision)))
+ /* Enable V.Scaling */
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
+ else
+ /* Enable H.Scaling */
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10);
+}
+
+static void XGI_SetGroup3(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i;
+ unsigned char const *tempdi;
+ unsigned short modeflag;
+
+ /* si+Ext_ResInfo */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
+ if (pVBInfo->TVInfo & TVSetPAL) {
+ xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
+ xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
+ } else {
+ xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5);
+ xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7);
+ }
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV))
+ return;
+
+ if (pVBInfo->TVInfo & TVSetPALM) {
+ xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
+ xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
+ xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8);
+ }
+
+ if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo
+ & SetCRT2ToYPbPr525750)) {
+ if (pVBInfo->TVInfo & TVSetYPbPr525i)
+ return;
+
+ tempdi = XGI330_HiTVGroup3Data;
+ if (pVBInfo->SetFlag & TVSimuMode) {
+ tempdi = XGI330_HiTVGroup3Simu;
+ if (!(modeflag & Charx8Dot))
+ tempdi = XGI330_HiTVGroup3Text;
+ }
+
+ if (pVBInfo->TVInfo & TVSetYPbPr525p)
+ tempdi = XGI330_Ren525pGroup3;
+
+ if (pVBInfo->TVInfo & TVSetYPbPr750p)
+ tempdi = XGI330_Ren750pGroup3;
+
+ for (i = 0; i <= 0x3E; i++)
+ xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]);
+
+ if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
+ if (pVBInfo->TVInfo & TVSetYPbPr525p)
+ xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f);
+ }
+ }
+}
+
+static void XGI_SetGroup4(unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
+
+ unsigned long tempebx, tempeax, templong;
+
+ /* si+Ext_ResInfo */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ temp = pVBInfo->RVBHCFACT;
+ xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp);
+
+ tempbx = pVBInfo->RVBHCMAX;
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp);
+ temp2 = ((tempbx & 0xFF00) >> 8) << 7;
+ tempcx = pVBInfo->VGAHT - 1;
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp);
+
+ temp = ((tempcx & 0xFF00) >> 8) << 3;
+ temp2 |= temp;
+
+ tempcx = pVBInfo->VGAVT - 1;
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV))
+ tempcx -= 5;
+
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp);
+ temp = temp2 | ((tempcx & 0xFF00) >> 8);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp);
+ xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08);
+ tempcx = pVBInfo->VBInfo;
+ tempbx = pVBInfo->VGAHDE;
+
+ if (modeflag & HalfDCLK)
+ tempbx = tempbx >> 1;
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+
+ if (tempcx & SetCRT2ToHiVision) {
+ temp = 0;
+ if (tempbx <= 1024)
+ temp = 0xA0;
+ if (tempbx == 1280)
+ temp = 0xC0;
+ } else if (tempcx & SetCRT2ToTV) {
+ temp = 0xA0;
+ if (tempbx <= 800)
+ temp = 0x80;
+ } else {
+ temp = 0x80;
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ temp = 0;
+ if (tempbx > 800)
+ temp = 0x60;
+ }
+ }
+
+ if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) {
+ temp = 0x00;
+ if (pVBInfo->VGAHDE == 1280)
+ temp = 0x40;
+ if (pVBInfo->VGAHDE == 1024)
+ temp = 0x20;
+ }
+ xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
+
+ tempebx = pVBInfo->VDE;
+
+ tempcx = pVBInfo->RVBHRS;
+ temp = tempcx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp);
+
+ tempeax = pVBInfo->VGAVDE;
+ tempcx |= 0x04000;
+
+ if (tempeax <= tempebx) {
+ tempcx = (tempcx & (~0x4000));
+ tempeax = pVBInfo->VGAVDE;
+ } else {
+ tempeax -= tempebx;
+ }
+
+ templong = (tempeax * 256 * 1024) % tempebx;
+ tempeax = (tempeax * 256 * 1024) / tempebx;
+ tempebx = tempeax;
+
+ if (templong != 0)
+ tempebx++;
+
+ temp = (unsigned short) (tempebx & 0x000000FF);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp);
+
+ temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp);
+ tempbx = (unsigned short) (tempebx >> 16);
+ temp = tempbx & 0x00FF;
+ temp = temp << 4;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp);
+
+ /* 301b */
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ temp = 0x0028;
+ xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp);
+ tempax = pVBInfo->VGAHDE;
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempax = tempax >> 1;
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ if (tempax > 800)
+ tempax -= 800;
+ } else if (pVBInfo->VGAHDE > 800) {
+ if (pVBInfo->VGAHDE == 1024)
+ tempax = (tempax * 25 / 32) - 1;
+ else
+ tempax = (tempax * 20 / 32) - 1;
+ }
+ tempax -= 1;
+
+ temp = (tempax & 0xFF00) >> 8;
+ temp = ((temp & 0x0003) << 4);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp);
+ temp = (tempax & 0x00FF);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) {
+ if (pVBInfo->VGAHDE > 800)
+ xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08);
+
+ }
+ temp = 0x0036;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!(pVBInfo->TVInfo & (NTSC1024x768
+ | TVSetYPbPr525p | TVSetYPbPr750p
+ | TVSetHiVision))) {
+ temp |= 0x0001;
+ if ((pVBInfo->VBInfo & SetInSlaveMode)
+ && (!(pVBInfo->TVInfo
+ & TVSimuMode)))
+ temp &= (~0x0001);
+ }
+ }
+
+ xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
+ tempbx = pVBInfo->HT;
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+ tempbx = (tempbx >> 1) - 2;
+ temp = ((tempbx & 0x0700) >> 8) << 3;
+ xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
+ temp = tempbx & 0x00FF;
+ xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp);
+ }
+ /* end 301b */
+
+ XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+}
+
+static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
+{
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
+}
+
+static void XGI_SetGroup5(struct vb_device_info *pVBInfo)
+{
+ if (pVBInfo->ModeType == ModeVGA) {
+ if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
+ | DisableCRT2Display))) {
+ XGINew_EnableCRT2(pVBInfo);
+ }
+ }
+}
+
+static void XGI_DisableGatingCRT(struct vb_device_info *pVBInfo)
+{
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
+}
+
+static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info,
+ unsigned short ModeNo, unsigned short ModeIdIndex)
+{
+ unsigned short xres, yres, colordepth, modeflag, resindex;
+
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
+ /* si+St_ModeFlag */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ if (!(modeflag & Charx8Dot)) {
+ xres /= 9;
+ xres *= 8;
+ }
+
+ if ((ModeNo > 0x13) && (modeflag & HalfDCLK))
+ xres *= 2;
+
+ if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
+ yres *= 2;
+
+ if (xres > xgifb_info->lvds_data.LVDSHDE)
+ return 0;
+
+ if (yres > xgifb_info->lvds_data.LVDSVDE)
+ return 0;
+
+ if (xres != xgifb_info->lvds_data.LVDSHDE ||
+ yres != xgifb_info->lvds_data.LVDSVDE) {
+ colordepth = XGI_GetColorDepth(ModeIdIndex);
+ if (colordepth > 2)
+ return 0;
+ }
+ return 1;
+}
+
+static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
+ int chip_id,
+ unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char temp, Miscdata;
+ unsigned short xres, yres, modeflag, resindex;
+ unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
+ unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
+ unsigned short value;
+
+ temp = (unsigned char) ((xgifb_info->lvds_data.LVDS_Capability &
+ (LCDPolarity << 8)) >> 8);
+ temp &= LCDPolarity;
+ Miscdata = inb(pVBInfo->P3cc);
+
+ outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
+
+ temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity;
+ /* SR35[7] FP VSync polarity */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
+ /* SR30[5] FP HSync polarity */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1);
+
+ if (chip_id == XG27)
+ XGI_SetXG27FPBits(pVBInfo);
+ else
+ XGI_SetXG21FPBits(pVBInfo);
+
+ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
+ /* si+St_ModeFlag */
+ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ if (!(modeflag & Charx8Dot))
+ xres = xres * 8 / 9;
+
+ LVDSHT = xgifb_info->lvds_data.LVDSHT;
+
+ LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2;
+
+ if (LVDSHBS > LVDSHT)
+ LVDSHBS -= LVDSHT;
+
+ LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP;
+ if (LVDSHRS > LVDSHT)
+ LVDSHRS -= LVDSHT;
+
+ LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC;
+ if (LVDSHRE > LVDSHT)
+ LVDSHRE -= LVDSHT;
+
+ LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE;
+
+ LVDSVT = xgifb_info->lvds_data.LVDSVT;
+
+ LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2;
+ if (modeflag & DoubleScanMode)
+ LVDSVBS += yres / 2;
+
+ if (LVDSVBS > LVDSVT)
+ LVDSVBS -= LVDSVT;
+
+ LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP;
+ if (LVDSVRS > LVDSVT)
+ LVDSVRS -= LVDSVT;
+
+ LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC;
+ if (LVDSVRE > LVDSVT)
+ LVDSVRE -= LVDSVT;
+
+ LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE;
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x11);
+ xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
+
+ if (!(modeflag & Charx8Dot))
+ xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1);
+
+ /* HT SR0B[1:0] CR00 */
+ value = (LVDSHT >> 3) - 5;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
+ xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF));
+
+ /* HBS SR0B[5:4] CR02 */
+ value = (LVDSHBS >> 3) - 1;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
+ xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF));
+
+ /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
+ value = (LVDSHBE >> 3) - 1;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
+
+ /* HRS SR0B[7:6] CR04 */
+ value = (LVDSHRS >> 3) + 2;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
+ xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF));
+
+ /* Panel HRS SR2F[1:0] SR2E[7:0] */
+ value--;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF));
+
+ /* HRE SR0C[2] CR05[4:0] */
+ value = (LVDSHRE >> 3) + 2;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
+
+ /* Panel HRE SR2F[7:2] */
+ value--;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
+
+ /* VT SR0A[0] CR07[5][0] CR06 */
+ value = LVDSVT - 2;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
+ xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF));
+
+ /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
+ value = LVDSVBS - 1;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
+ xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF));
+
+ /* VBE SR0A[4] CR16 */
+ value = LVDSVBE - 1;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
+ xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF));
+
+ /* VRS SR0A[3] CR7[7][2] CR10 */
+ value = LVDSVRS - 1;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
+ xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF));
+
+ if (chip_id == XG27) {
+ /* Panel VRS SR35[2:0] SR34[7:0] */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07,
+ (value & 0x700) >> 8);
+ xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF);
+ } else {
+ /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03,
+ (value & 0x600) >> 9);
+ xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01);
+ }
+
+ /* VRE SR0A[5] CR11[3:0] */
+ value = LVDSVRE - 1;
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
+
+ /* Panel VRE SR3F[7:2] */
+ if (chip_id == XG27)
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
+ (value << 2) & 0xFC);
+ else
+ /* SR3F[7] has to be 0, h/w bug */
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
+ (value << 2) & 0x7C);
+
+ for (temp = 0, value = 0; temp < 3; temp++) {
+
+ xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x2B, xgifb_info->lvds_data.VCLKData1);
+ xgifb_reg_set(pVBInfo->P3c4,
+ 0x2C, xgifb_info->lvds_data.VCLKData2);
+ value += 0x10;
+ }
+
+ if (!(modeflag & Charx8Dot)) {
+ inb(pVBInfo->P3da); /* reset 3da */
+ outb(0x13, pVBInfo->P3c0); /* set index */
+ /* set data, panning = 0, shift left 1 dot*/
+ outb(0x00, pVBInfo->P3c0);
+
+ inb(pVBInfo->P3da); /* Enable Attribute */
+ outb(0x20, pVBInfo->P3c0);
+
+ inb(pVBInfo->P3da); /* reset 3da */
+ }
+
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_IsLCDON */
+/* Input : */
+/* Output : 0 : Skip PSC Control */
+/* 1: Disable PSC */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax;
+
+ tempax = pVBInfo->VBInfo;
+ if (tempax & SetCRT2ToDualEdge)
+ return 0;
+ else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode))
+ return 1;
+
+ return 0;
+}
+
+static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempah = 0;
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ tempah = 0x3F;
+ if (!(pVBInfo->VBInfo &
+ (DisableCRT2Display | SetSimuScanMode))) {
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempah = 0x7F; /* Disable Channel A */
+ }
+ }
+
+ /* disable part4_1f */
+ xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah);
+
+ if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
+ if (((pVBInfo->VBInfo &
+ (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) ||
+ (XGI_IsLCDON(pVBInfo)))
+ /* LVDS Driver power down */
+ xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80);
+ }
+
+ if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA |
+ SetSimuScanMode))
+ XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
+
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
+ /* Power down */
+ xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf);
+
+ /* disable TV as primary VGA swap */
+ xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf);
+
+ if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
+ xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf);
+
+ if ((pVBInfo->VBInfo &
+ (DisableCRT2Display | SetSimuScanMode)) ||
+ ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
+ (pVBInfo->VBInfo &
+ (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
+ xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
+
+ if ((pVBInfo->VBInfo &
+ (DisableCRT2Display | SetSimuScanMode)) ||
+ (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) ||
+ (pVBInfo->VBInfo &
+ (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
+ /* save Part1 index 0 */
+ tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
+ /* BTDAC = 1, avoid VB reset */
+ xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10);
+ /* disable CRT2 */
+ xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
+ /* restore Part1 index 0 */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
+ }
+ } else { /* {301} */
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+ xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
+ /* Disable CRT2 */
+ xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
+ /* Disable TV asPrimary VGA swap */
+ xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF);
+ }
+
+ if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA
+ | SetSimuScanMode))
+ XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTVPtrIndex */
+/* Input : */
+/* Output : */
+/* Description : bx 0 : ExtNTSC */
+/* 1 : StNTSC */
+/* 2 : ExtPAL */
+/* 3 : StPAL */
+/* 4 : ExtHiTV */
+/* 5 : StHiTV */
+/* 6 : Ext525i */
+/* 7 : St525i */
+/* 8 : Ext525p */
+/* 9 : St525p */
+/* A : Ext750p */
+/* B : St750p */
+/* --------------------------------------------------------------------- */
+static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx = 0;
+
+ if (pVBInfo->TVInfo & TVSetPAL)
+ tempbx = 2;
+ if (pVBInfo->TVInfo & TVSetHiVision)
+ tempbx = 4;
+ if (pVBInfo->TVInfo & TVSetYPbPr525i)
+ tempbx = 6;
+ if (pVBInfo->TVInfo & TVSetYPbPr525p)
+ tempbx = 8;
+ if (pVBInfo->TVInfo & TVSetYPbPr750p)
+ tempbx = 10;
+ if (pVBInfo->TVInfo & TVSimuMode)
+ tempbx++;
+
+ return tempbx;
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTVPtrIndex2 */
+/* Input : */
+/* Output : bx 0 : NTSC */
+/* 1 : PAL */
+/* 2 : PALM */
+/* 3 : PALN */
+/* 4 : NTSC1024x768 */
+/* 5 : PAL-M 1024x768 */
+/* 6-7: reserved */
+/* cl 0 : YFilter1 */
+/* 1 : YFilter2 */
+/* ch 0 : 301A */
+/* 1 : 301B/302B/301LV/302LV */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
+ unsigned char *tempch, struct vb_device_info *pVBInfo)
+{
+ *tempbx = 0;
+ *tempcl = 0;
+ *tempch = 0;
+
+ if (pVBInfo->TVInfo & TVSetPAL)
+ *tempbx = 1;
+
+ if (pVBInfo->TVInfo & TVSetPALM)
+ *tempbx = 2;
+
+ if (pVBInfo->TVInfo & TVSetPALN)
+ *tempbx = 3;
+
+ if (pVBInfo->TVInfo & NTSC1024x768) {
+ *tempbx = 4;
+ if (pVBInfo->TVInfo & TVSetPALM)
+ *tempbx = 5;
+ }
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
+ & TVSimuMode)) {
+ *tempbx += 8;
+ *tempcl += 1;
+ }
+ }
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C))
+ (*tempch)++;
+}
+
+static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
+{
+ unsigned char tempah, tempbl, tempbh;
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA
+ | SetCRT2ToTV | SetCRT2ToRAMDAC)) {
+ tempbh = 0;
+ tempbl = XGI301TVDelay;
+
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempbl = tempbl >> 4;
+ if (pVBInfo->VBInfo &
+ (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+ tempbh = XGI301LCDDelay;
+
+ if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
+ tempbl = tempbh;
+ }
+
+ tempbl &= 0x0F;
+ tempbh &= 0xF0;
+ tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
+ | SetCRT2ToTV)) { /* Channel B */
+ tempah &= 0xF0;
+ tempah |= tempbl;
+ }
+
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
+ /* Channel A */
+ tempah &= 0x0F;
+ tempah |= tempbh;
+ }
+ xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah);
+ }
+ }
+}
+
+static void XGI_SetLCDCap_A(unsigned short tempcx,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp;
+
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
+
+ if (temp & LCDRGB18Bit) {
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
+ /* Enable Dither */
+ (unsigned short) (0x20 | (tempcx & 0x00C0)));
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
+ } else {
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
+ (unsigned short) (0x30 | (tempcx & 0x00C0)));
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLCDCap_B */
+/* Input : cx -> LCD Capability */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+static void XGI_SetLCDCap_B(unsigned short tempcx,
+ struct vb_device_info *pVBInfo)
+{
+ if (tempcx & EnableLCD24bpp) /* 24bits */
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
+ (unsigned short) (((tempcx & 0x00ff) >> 6)
+ | 0x0c));
+ else
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
+ (unsigned short) (((tempcx & 0x00ff) >> 6)
+ | 0x18)); /* Enable Dither */
+}
+
+static void XGI_LongWait(struct vb_device_info *pVBInfo)
+{
+ unsigned short i;
+
+ i = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
+
+ if (!(i & 0xC0)) {
+ for (i = 0; i < 0xFFFF; i++) {
+ if (!(inb(pVBInfo->P3da) & 0x08))
+ break;
+ }
+
+ for (i = 0; i < 0xFFFF; i++) {
+ if ((inb(pVBInfo->P3da) & 0x08))
+ break;
+ }
+ }
+}
+
+static void SetSpectrum(struct vb_device_info *pVBInfo)
+{
+ unsigned short index;
+
+ index = XGI_GetLCDCapPtr(pVBInfo);
+
+ /* disable down spectrum D[4] */
+ xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F);
+ XGI_LongWait(pVBInfo);
+ xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
+ XGI_LongWait(pVBInfo);
+
+ xgifb_reg_set(pVBInfo->Part4Port, 0x31,
+ pVBInfo->LCDCapList[index].Spectrum_31);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x32,
+ pVBInfo->LCDCapList[index].Spectrum_32);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x33,
+ pVBInfo->LCDCapList[index].Spectrum_33);
+ xgifb_reg_set(pVBInfo->Part4Port, 0x34,
+ pVBInfo->LCDCapList[index].Spectrum_34);
+ XGI_LongWait(pVBInfo);
+ xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
+}
+
+static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempcx;
+
+ tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV |
+ VB_SIS302LV | VB_XGI301C)) {
+ if (pVBInfo->VBType &
+ (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
+ /* Set 301LV Capability */
+ xgifb_reg_set(pVBInfo->Part4Port, 0x24,
+ (unsigned char) (tempcx & 0x1F));
+ }
+ /* VB Driving */
+ xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D,
+ ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
+ (unsigned short) ((tempcx & (EnableVBCLKDRVLOW
+ | EnablePLLSPLOW)) >> 8));
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD)
+ XGI_SetLCDCap_B(tempcx, pVBInfo);
+ else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
+ XGI_SetLCDCap_A(tempcx, pVBInfo);
+
+ if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
+ if (tempcx & EnableSpectrum)
+ SetSpectrum(pVBInfo);
+ }
+ } else {
+ /* LVDS,CH7017 */
+ XGI_SetLCDCap_A(tempcx, pVBInfo);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetAntiFlicker */
+/* Input : */
+/* Output : */
+/* Description : Set TV Customized Param. */
+/* --------------------------------------------------------------------- */
+static void XGI_SetAntiFlicker(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx;
+
+ unsigned char tempah;
+
+ if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
+ return;
+
+ tempbx = XGI_GetTVPtrIndex(pVBInfo);
+ tempbx &= 0xFE;
+ tempah = TVAntiFlickList[tempbx];
+ tempah = tempah << 4;
+
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
+}
+
+static void XGI_SetEdgeEnhance(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx;
+
+ unsigned char tempah;
+
+ tempbx = XGI_GetTVPtrIndex(pVBInfo);
+ tempbx &= 0xFE;
+ tempah = TVEdgeList[tempbx];
+ tempah = tempah << 5;
+
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
+}
+
+static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx;
+
+ unsigned char tempcl, tempch;
+
+ unsigned long tempData;
+
+ XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+ tempData = TVPhaseList[tempbx];
+
+ xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
+ & 0x000000FF));
+ xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
+ & 0x0000FF00) >> 8));
+ xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
+ & 0x00FF0000) >> 16));
+ xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
+ & 0xFF000000) >> 24));
+}
+
+static void XGI_SetYFilter(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx, index;
+ unsigned char const *filterPtr;
+ unsigned char tempcl, tempch, tempal;
+
+ XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+
+ switch (tempbx) {
+ case 0x00:
+ case 0x04:
+ filterPtr = NTSCYFilter1;
+ break;
+
+ case 0x01:
+ filterPtr = PALYFilter1;
+ break;
+
+ case 0x02:
+ case 0x05:
+ case 0x0D:
+ case 0x03:
+ filterPtr = xgifb_palmn_yfilter1;
+ break;
+
+ case 0x08:
+ case 0x0C:
+ case 0x0A:
+ case 0x0B:
+ case 0x09:
+ filterPtr = xgifb_yfilter2;
+ break;
+
+ default:
+ return;
+ }
+
+ tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+ if (tempcl == 0)
+ index = tempal * 4;
+ else
+ index = tempal * 7;
+
+ if ((tempcl == 0) && (tempch == 1)) {
+ xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
+ } else {
+ xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
+ }
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
+ xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_OEM310Setting */
+/* Input : */
+/* Output : */
+/* Description : Customized Param. for 301 */
+/* --------------------------------------------------------------------- */
+static void XGI_OEM310Setting(unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ XGI_SetDelayComp(pVBInfo);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
+ XGI_SetLCDCap(pVBInfo);
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ XGI_SetPhaseIncr(pVBInfo);
+ XGI_SetYFilter(ModeIdIndex, pVBInfo);
+ XGI_SetAntiFlicker(pVBInfo);
+
+ if (pVBInfo->VBType & VB_SIS301)
+ XGI_SetEdgeEnhance(pVBInfo);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT2ModeRegs */
+/* Input : */
+/* Output : */
+/* Description : Origin code for crt2group */
+/* --------------------------------------------------------------------- */
+static void XGI_SetCRT2ModeRegs(struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbl;
+ short tempcl;
+
+ unsigned char tempah;
+
+ tempah = 0;
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
+ tempah &= ~0x10; /* BTRAMDAC */
+ tempah |= 0x40; /* BTRAM */
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
+ | SetCRT2ToLCD)) {
+ tempah = 0x40; /* BTDRAM */
+ tempcl = pVBInfo->ModeType;
+ tempcl -= ModeVGA;
+ if (tempcl >= 0) {
+ /* BT Color */
+ tempah = (0x008 >> tempcl);
+ if (tempah == 0)
+ tempah = 1;
+ tempah |= 0x040;
+ }
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempah ^= 0x50; /* BTDAC */
+ }
+ }
+
+ xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
+ tempah = 0x08;
+ tempbl = 0xf0;
+
+ if (pVBInfo->VBInfo & DisableCRT2Display)
+ goto reg_and_or;
+
+ tempah = 0x00;
+ tempbl = 0xff;
+
+ if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV |
+ SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
+ goto reg_and_or;
+
+ if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
+ (!(pVBInfo->VBInfo & SetSimuScanMode))) {
+ tempbl &= 0xf7;
+ tempah |= 0x01;
+ goto reg_and_or;
+ }
+
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
+ tempbl &= 0xf7;
+ tempah |= 0x01;
+ }
+
+ if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)))
+ goto reg_and_or;
+
+ tempbl &= 0xf8;
+ tempah = 0x01;
+
+ if (!(pVBInfo->VBInfo & SetInSlaveMode))
+ tempah |= 0x02;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+ tempah = tempah ^ 0x05;
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+ tempah = tempah ^ 0x01;
+ }
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
+ tempah |= 0x08;
+
+reg_and_or:
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
+ | XGI_SetCRT2ToLCDA)) {
+ tempah &= (~0x08);
+ if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
+ & SetInSlaveMode))) {
+ tempah |= 0x010;
+ }
+ tempah |= 0x080;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ tempah |= 0x020;
+ if (pVBInfo->VBInfo & DriverMode)
+ tempah = tempah ^ 0x20;
+ }
+
+ xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
+ tempah = 0;
+
+ if (pVBInfo->LCDInfo & SetLCDDualLink)
+ tempah |= 0x40;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->TVInfo & RPLLDIV2XO)
+ tempah |= 0x40;
+ }
+
+ if ((pVBInfo->LCDResInfo == Panel_1280x1024)
+ || (pVBInfo->LCDResInfo == Panel_1280x1024x75))
+ tempah |= 0x80;
+
+ if (pVBInfo->LCDResInfo == Panel_1280x960)
+ tempah |= 0x80;
+
+ xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah);
+ }
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ tempah = 0;
+ tempbl = 0xfb;
+
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+ tempbl = 0xff;
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
+ tempah |= 0x04; /* shampoo 0129 */
+ }
+
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah);
+ tempah = 0x00;
+ tempbl = 0xcf;
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempah |= 0x30;
+ }
+
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
+ tempah = 0;
+ tempbl = 0x3f;
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempah |= 0xc0;
+ }
+ xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah);
+ }
+
+ tempah = 0;
+ tempbl = 0x7f;
+ if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) {
+ tempbl = 0xff;
+ if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
+ tempah |= 0x80;
+ }
+
+ xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah);
+
+ if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
+ if (pVBInfo->LCDInfo & SetLCDDualLink) {
+ xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20);
+ xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10);
+ }
+ }
+}
+
+
+void XGI_UnLockCRT2(struct vb_device_info *pVBInfo)
+{
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
+}
+
+void XGI_LockCRT2(struct vb_device_info *pVBInfo)
+{
+ xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
+}
+
+unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
+ unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ const u8 LCDARefreshIndex[] = {
+ 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00 };
+
+ unsigned short RefreshRateTableIndex, i, index, temp;
+
+ index = xgifb_reg_get(pVBInfo->P3d4, 0x33);
+ index = index >> pVBInfo->SelectCRT2Rate;
+ index &= 0x0F;
+
+ if (pVBInfo->LCDInfo & LCDNonExpanding)
+ index = 0;
+
+ if (index > 0)
+ index--;
+
+ if (pVBInfo->SetFlag & ProgrammingCRT2) {
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+ temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x07];
+
+ if (index > temp)
+ index = temp;
+ }
+ }
+
+ RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID;
+ if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
+ if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) &&
+ (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) {
+ index++;
+ }
+ /* do the similar adjustment like XGISearchCRT1Rate() */
+ if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) &&
+ (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) {
+ index++;
+ }
+ if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+ (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) {
+ index++;
+ }
+ }
+
+ i = 0;
+ do {
+ if (XGI330_RefIndex[RefreshRateTableIndex + i].
+ ModeID != ModeNo)
+ break;
+ temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
+ temp &= ModeTypeMask;
+ if (temp < pVBInfo->ModeType)
+ break;
+ i++;
+ index--;
+
+ } while (index != 0xFFFF);
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1].
+ Ext_InfoFlag;
+ if (temp & InterlaceMode)
+ i++;
+ }
+ }
+ i--;
+ if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
+ temp = XGI_AjustCRT2Rate(ModeIdIndex, RefreshRateTableIndex,
+ &i, pVBInfo);
+ }
+ return RefreshRateTableIndex + i;
+}
+
+static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short RefreshRateTableIndex;
+
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+ XGI_GetLVDSResInfo(ModeIdIndex, pVBInfo);
+ XGI_GetLVDSData(ModeIdIndex, pVBInfo);
+ XGI_ModCRT1Regs(ModeIdIndex, HwDeviceExtension, pVBInfo);
+ XGI_SetLVDSRegs(ModeIdIndex, pVBInfo);
+ XGI_SetCRT2ECLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+}
+
+static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short ModeIdIndex, RefreshRateTableIndex;
+
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+ XGI_SearchModeID(ModeNo, &ModeIdIndex);
+ pVBInfo->SelectCRT2Rate = 4;
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+ XGI_SaveCRT2Info(ModeNo, pVBInfo);
+ XGI_GetCRT2ResInfo(ModeIdIndex, pVBInfo);
+ XGI_GetCRT2Data(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_PreSetGroup1(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetGroup1(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetLockRegs(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_SetGroup2(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_SetLCDRegs(ModeIdIndex, pVBInfo);
+ XGI_SetTap4Regs(pVBInfo);
+ XGI_SetGroup3(ModeIdIndex, pVBInfo);
+ XGI_SetGroup4(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT2VCLK(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetGroup5(pVBInfo);
+ XGI_AutoThreshold(pVBInfo);
+ return 1;
+}
+
+void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
+{
+ unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
+ 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
+ 0x05, 0x00 };
+
+ unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
+
+ unsigned char CR17, CR63, SR31;
+ unsigned short temp;
+
+ int i;
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
+
+ /* to fix XG42 single LCD sense to CRT+LCD */
+ xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A);
+ xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get(
+ pVBInfo->P3d4, 0x53) | 0x02));
+
+ SR31 = xgifb_reg_get(pVBInfo->P3c4, 0x31);
+ CR63 = xgifb_reg_get(pVBInfo->P3d4, 0x63);
+ SR01 = xgifb_reg_get(pVBInfo->P3c4, 0x01);
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
+ xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
+
+ CR17 = xgifb_reg_get(pVBInfo->P3d4, 0x17);
+ xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
+
+ SR1F = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
+ xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
+
+ SR07 = xgifb_reg_get(pVBInfo->P3c4, 0x07);
+ xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
+ SR06 = xgifb_reg_get(pVBInfo->P3c4, 0x06);
+ xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
+
+ xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00);
+
+ for (i = 0; i < 8; i++)
+ xgifb_reg_set(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
+
+ for (i = 8; i < 11; i++)
+ xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 8),
+ CRTCData[i]);
+
+ for (i = 11; i < 13; i++)
+ xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 4),
+ CRTCData[i]);
+
+ for (i = 13; i < 16; i++)
+ xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i - 3),
+ CRTCData[i]);
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
+ & 0xE0));
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B);
+ xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1);
+
+ outb(0x00, pVBInfo->P3c8);
+
+ for (i = 0; i < 256 * 3; i++)
+ outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */
+
+ mdelay(1);
+
+ XGI_WaitDisply(pVBInfo);
+ temp = inb(pVBInfo->P3c2);
+
+ if (temp & 0x10)
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
+ else
+ xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
+
+ /* avoid display something, set BLACK DAC if not restore DAC */
+ outb(0x00, pVBInfo->P3c8);
+
+ for (i = 0; i < 256 * 3; i++)
+ outb(0, (pVBInfo->P3c8 + 1));
+
+ xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01);
+ xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63);
+ xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31);
+
+ xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get(
+ pVBInfo->P3d4, 0x53) & 0xFD));
+ xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
+}
+
+static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempah;
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ /* Power on */
+ xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV |
+ SetCRT2ToRAMDAC)) {
+ tempah = xgifb_reg_get(pVBInfo->P3c4, 0x32);
+ tempah &= 0xDF;
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
+ tempah |= 0x20;
+ }
+ xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah);
+ xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20);
+
+ tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E);
+
+ if (!(tempah & 0x80))
+ xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
+ xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
+ }
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0,
+ 0x20); /* shampoo 0129 */
+ if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo &
+ (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
+ /* LVDS PLL power on */
+ xgifb_reg_and(pVBInfo->Part4Port, 0x2A,
+ 0x7F);
+ /* LVDS Driver power on */
+ xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F);
+ }
+ }
+
+ tempah = 0x00;
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ tempah = 0xc0;
+
+ if (!(pVBInfo->VBInfo & SetSimuScanMode) &&
+ (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
+ (pVBInfo->VBInfo & SetCRT2ToDualEdge)) {
+ tempah = tempah & 0x40;
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
+ tempah = tempah ^ 0xC0;
+ }
+ }
+
+ /* EnablePart4_1F */
+ xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah);
+
+ XGI_DisableGatingCRT(pVBInfo);
+ XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
+ } /* 301 */
+ else { /* LVDS */
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
+ | XGI_SetCRT2ToLCDA))
+ /* enable CRT2 */
+ xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20);
+
+ tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E);
+ if (!(tempah & 0x80))
+ xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
+
+ xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
+ XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
+ } /* End of VB */
+}
+
+static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short RefreshRateTableIndex, temp;
+
+ XGI_SetSeqRegs(pVBInfo);
+ outb(XGI330_StandTable.MISC, pVBInfo->P3c2);
+ XGI_SetCRTCRegs(pVBInfo);
+ XGI_SetATTRegs(ModeIdIndex, pVBInfo);
+ XGI_SetGRCRegs(pVBInfo);
+ XGI_ClearExt1Regs(pVBInfo);
+
+ if (HwDeviceExtension->jChipType == XG27) {
+ if (pVBInfo->IF_DEF_LVDS == 0)
+ XGI_SetDefaultVCLK(pVBInfo);
+ }
+
+ temp = ~ProgrammingCRT2;
+ pVBInfo->SetFlag &= temp;
+ pVBInfo->SelectCRT2Rate = 0;
+
+ if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+ | VB_SIS302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA
+ | SetInSlaveMode)) {
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+ }
+ }
+
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+ if (RefreshRateTableIndex != 0xFFFF) {
+ XGI_SetSync(RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT1CRTC(ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo, HwDeviceExtension);
+ XGI_SetCRT1DE(ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetCRT1VCLK(ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ }
+
+ if (HwDeviceExtension->jChipType >= XG21) {
+ temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
+ if (temp & 0xA0) {
+
+ if (HwDeviceExtension->jChipType == XG27)
+ XGI_SetXG27CRTC(RefreshRateTableIndex, pVBInfo);
+ else
+ XGI_SetXG21CRTC(RefreshRateTableIndex, pVBInfo);
+
+ XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
+ RefreshRateTableIndex);
+
+ xgifb_set_lcd(HwDeviceExtension->jChipType,
+ pVBInfo, RefreshRateTableIndex);
+
+ if (pVBInfo->IF_DEF_LVDS == 1)
+ xgifb_set_lvds(xgifb_info,
+ HwDeviceExtension->jChipType,
+ ModeIdIndex, pVBInfo);
+ }
+ }
+
+ pVBInfo->SetFlag &= (~ProgrammingCRT2);
+ XGI_SetCRT1FIFO(HwDeviceExtension, pVBInfo);
+ XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_LoadDAC(pVBInfo);
+}
+
+unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short ModeNo)
+{
+ unsigned short ModeIdIndex;
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+
+ pVBInfo->IF_DEF_LVDS = 0;
+
+ if (HwDeviceExtension->jChipType >= XG20)
+ pVBInfo->VBType = 0; /*set VBType default 0*/
+
+ XGIRegInit(pVBInfo, xgifb_info->vga_base);
+
+ /* for x86 Linux, XG21 LVDS */
+ if (HwDeviceExtension->jChipType == XG21) {
+ if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
+ pVBInfo->IF_DEF_LVDS = 1;
+ }
+ if (HwDeviceExtension->jChipType == XG27) {
+ if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
+ if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20)
+ pVBInfo->IF_DEF_LVDS = 1;
+ }
+ }
+
+ InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+ if (ModeNo & 0x80)
+ ModeNo = ModeNo & 0x7F;
+ xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
+
+ if (HwDeviceExtension->jChipType < XG20)
+ XGI_UnLockCRT2(pVBInfo);
+
+ XGI_SearchModeID(ModeNo, &ModeIdIndex);
+
+ if (HwDeviceExtension->jChipType < XG20) {
+ XGI_GetVBInfo(ModeIdIndex, pVBInfo);
+ XGI_GetTVInfo(ModeIdIndex, pVBInfo);
+ XGI_GetLCDInfo(ModeIdIndex, pVBInfo);
+ XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
+
+ if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA) ||
+ (!(pVBInfo->VBInfo & SwitchCRT2))) {
+ XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+
+ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
+ XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
+ HwDeviceExtension, pVBInfo);
+ }
+ }
+
+ if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) {
+ switch (HwDeviceExtension->ujVBChipID) {
+ case VB_CHIP_301: /* fall through */
+ case VB_CHIP_302:
+ XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
+ pVBInfo); /*add for CRT2 */
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ XGI_SetCRT2ModeRegs(pVBInfo);
+ XGI_OEM310Setting(ModeIdIndex, pVBInfo); /*0212*/
+ XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
+ } /* !XG20 */
+ else {
+ if (pVBInfo->IF_DEF_LVDS == 1)
+ if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo,
+ ModeIdIndex))
+ return 0;
+
+ pVBInfo->ModeType = XGI330_EModeIDTable[ModeIdIndex].
+ Ext_ModeFlag & ModeTypeMask;
+
+ pVBInfo->SetFlag = 0;
+ pVBInfo->VBInfo = DisableCRT2Display;
+
+ XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
+
+ XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+
+ XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
+ }
+
+ XGI_UpdateModeInfo(pVBInfo);
+
+ if (HwDeviceExtension->jChipType < XG20)
+ XGI_LockCRT2(pVBInfo);
+
+ return 1;
+}
diff --git a/src/drivers/xgi/common/vb_setmode.h b/src/drivers/xgi/common/vb_setmode.h
new file mode 100644
index 0000000000..6703fbce13
--- /dev/null
+++ b/src/drivers/xgi/common/vb_setmode.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken verbatim from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VBSETMODE_
+#define _VBSETMODE_
+
+extern void InitTo330Pointer(unsigned char, struct vb_device_info *);
+extern void XGI_UnLockCRT2(struct vb_device_info *);
+extern void XGI_LockCRT2(struct vb_device_info *);
+extern void XGI_DisplayOff(struct xgifb_video_info *,
+ struct xgi_hw_device_info *,
+ struct vb_device_info *);
+extern void XGI_GetVBType(struct vb_device_info *);
+extern void XGI_SenseCRT1(struct vb_device_info *);
+extern unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short ModeNo);
+
+extern unsigned char XGI_SearchModeID(unsigned short ModeNo,
+ unsigned short *ModeIdIndex);
+extern unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
+ unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ struct vb_device_info *);
+
+#endif
diff --git a/src/drivers/xgi/common/vb_struct.h b/src/drivers/xgi/common/vb_struct.h
new file mode 100644
index 0000000000..dc6d311103
--- /dev/null
+++ b/src/drivers/xgi/common/vb_struct.h
@@ -0,0 +1,184 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken verbatim from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VB_STRUCT_
+#define _VB_STRUCT_
+
+struct XGI_LVDSCRT1HDataStruct {
+ unsigned char Reg[8];
+};
+
+struct XGI_LVDSCRT1VDataStruct {
+ unsigned char Reg[7];
+};
+
+struct XGI_ExtStruct {
+ unsigned char Ext_ModeID;
+ unsigned short Ext_ModeFlag;
+ unsigned short Ext_ModeInfo;
+ unsigned char Ext_RESINFO;
+ unsigned char VB_ExtTVYFilterIndex;
+ unsigned char REFindex;
+};
+
+struct XGI_Ext2Struct {
+ unsigned short Ext_InfoFlag;
+ unsigned char Ext_CRT1CRTC;
+ unsigned char Ext_CRTVCLK;
+ unsigned char Ext_CRT2CRTC;
+ unsigned char Ext_CRT2CRTC2;
+ unsigned char ModeID;
+ unsigned short XRes;
+ unsigned short YRes;
+};
+
+struct XGI_ECLKDataStruct {
+ unsigned char SR2E, SR2F, SR30;
+ unsigned short CLOCK;
+};
+
+/*add for new UNIVGABIOS*/
+struct XGI_LCDDesStruct {
+ unsigned short LCDHDES;
+ unsigned short LCDHRS;
+ unsigned short LCDVDES;
+ unsigned short LCDVRS;
+};
+
+struct XGI330_LCDDataDesStruct2 {
+ unsigned short LCDHDES;
+ unsigned short LCDHRS;
+ unsigned short LCDVDES;
+ unsigned short LCDVRS;
+ unsigned short LCDHSync;
+ unsigned short LCDVSync;
+};
+
+struct XGI330_LCDDataTablStruct {
+ unsigned char PANELID;
+ unsigned short MASK;
+ unsigned short CAP;
+ void const *DATAPTR;
+};
+
+struct XGI330_TVDataTablStruct {
+ unsigned short MASK;
+ unsigned short CAP;
+ struct SiS_TVData const *DATAPTR;
+};
+
+
+struct XGI_TimingHStruct {
+ unsigned char data[8];
+};
+
+struct XGI_TimingVStruct {
+ unsigned char data[7];
+};
+
+struct XGI_XG21CRT1Struct {
+ unsigned char ModeID, CR02, CR03, CR15, CR16;
+};
+
+struct XGI330_LCDCapStruct {
+ unsigned char LCD_ID;
+ unsigned short LCD_Capability;
+ unsigned char LCD_HSyncWidth;
+ unsigned char LCD_VSyncWidth;
+ unsigned char LCD_VCLK;
+ unsigned char LCDA_VCLKData1;
+ unsigned char LCDA_VCLKData2;
+ unsigned char LCUCHAR_VCLKData1;
+ unsigned char LCUCHAR_VCLKData2;
+ unsigned char Spectrum_31;
+ unsigned char Spectrum_32;
+ unsigned char Spectrum_33;
+ unsigned char Spectrum_34;
+};
+
+struct XGI21_LVDSCapStruct {
+ unsigned short LVDS_Capability;
+ unsigned short LVDSHT;
+ unsigned short LVDSVT;
+ unsigned short LVDSHDE;
+ unsigned short LVDSVDE;
+ unsigned short LVDSHFP;
+ unsigned short LVDSVFP;
+ unsigned short LVDSHSYNC;
+ unsigned short LVDSVSYNC;
+ unsigned char VCLKData1;
+ unsigned char VCLKData2;
+ unsigned char PSC_S1; /* Duration between CPL on and signal on */
+ unsigned char PSC_S2; /* Duration signal on and Vdd on */
+ unsigned char PSC_S3; /* Duration between CPL off and signal off */
+ unsigned char PSC_S4; /* Duration signal off and Vdd off */
+ unsigned char PSC_S5;
+};
+
+struct XGI_CRT1TableStruct {
+ unsigned char CR[16];
+};
+
+
+struct XGI301C_Tap4TimingStruct {
+ unsigned short DE;
+ unsigned char Reg[64]; /* C0-FF */
+};
+
+struct vb_device_info {
+ unsigned long P3c4, P3d4, P3c0, P3ce, P3c2, P3cc;
+ unsigned long P3ca, P3c6, P3c7, P3c8, P3c9, P3da;
+ unsigned long Part0Port, Part1Port, Part2Port;
+ unsigned long Part3Port, Part4Port, Part5Port;
+ unsigned short RVBHCFACT, RVBHCMAX, RVBHRS;
+ unsigned short VGAVT, VGAHT, VGAVDE, VGAHDE;
+ unsigned short VT, HT, VDE, HDE;
+ unsigned short LCDHRS, LCDVRS, LCDHDES, LCDVDES;
+
+ unsigned short ModeType;
+ unsigned short IF_DEF_LVDS;
+ unsigned short IF_DEF_CRT2Monitor;
+ unsigned short IF_DEF_YPbPr;
+ unsigned short IF_DEF_HiVision;
+ unsigned short LCDResInfo, LCDTypeInfo, VBType;/*301b*/
+ unsigned short VBInfo, TVInfo, LCDInfo;
+ unsigned short SetFlag;
+ unsigned short NewFlickerMode;
+ unsigned short SelectCRT2Rate;
+
+ void __iomem *FBAddr;
+
+ unsigned char const *SR18;
+ unsigned char const (*CR40)[3];
+
+ struct SiS_MCLKData const *MCLKData;
+
+ unsigned char XGINew_CR97;
+
+ struct XGI330_LCDCapStruct const *LCDCapList;
+
+ struct XGI_TimingHStruct TimingH;
+ struct XGI_TimingVStruct TimingV;
+
+ int ram_type;
+ int ram_channel;
+ int ram_bus;
+}; /* _struct vb_device_info */
+
+#endif /* _VB_STRUCT_ */
diff --git a/src/drivers/xgi/common/vb_table.h b/src/drivers/xgi/common/vb_table.h
new file mode 100644
index 0000000000..923f2d8592
--- /dev/null
+++ b/src/drivers/xgi/common/vb_table.h
@@ -0,0 +1,2510 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken verbatim from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VB_TABLE_
+#define _VB_TABLE_
+static const struct SiS_MCLKData XGI340New_MCLKData[] = {
+ {0x16, 0x01, 0x01, 166},
+ {0x19, 0x02, 0x01, 124},
+ {0x7C, 0x08, 0x01, 200},
+};
+
+static const struct SiS_MCLKData XGI27New_MCLKData[] = {
+ {0x5c, 0x23, 0x01, 166},
+ {0x19, 0x02, 0x01, 124},
+ {0x7C, 0x08, 0x80, 200},
+};
+
+const struct XGI_ECLKDataStruct XGI340_ECLKData[] = {
+ {0x5c, 0x23, 0x01, 166},
+ {0x55, 0x84, 0x01, 123},
+ {0x7C, 0x08, 0x01, 200},
+};
+
+static const unsigned char XG27_SR18[3] = {
+ 0x32, 0x32, 0x42 /* SR18 */
+};
+
+static const unsigned char XGI340_SR18[3] = {
+ 0x31, 0x42, 0x42 /* SR18 */
+};
+
+static const unsigned char XGI340_cr41[24][3] = {
+ {0x20, 0x50, 0x60}, /* 0 CR41 */
+ {0xc4, 0x40, 0x84}, /* 1 CR8A */
+ {0xc4, 0x40, 0x84}, /* 2 CR8B */
+ {0xb5, 0xa4, 0xa4},
+ {0xf0, 0xf0, 0xf0},
+ {0x90, 0x90, 0x24}, /* 5 CR68 */
+ {0x77, 0x77, 0x44}, /* 6 CR69 */
+ {0x77, 0x77, 0x44}, /* 7 CR6A */
+ {0xff, 0xff, 0xff}, /* 8 CR6D */
+ {0x55, 0x55, 0x55}, /* 9 CR80 */
+ {0x00, 0x00, 0x00}, /* 10 CR81 */
+ {0x88, 0xa8, 0x48}, /* 11 CR82 */
+ {0x44, 0x44, 0x77}, /* 12 CR85 */
+ {0x48, 0x48, 0x88}, /* 13 CR86 */
+ {0x54, 0x54, 0x44}, /* 14 CR90 */
+ {0x54, 0x54, 0x44}, /* 15 CR91 */
+ {0x0a, 0x0a, 0x07}, /* 16 CR92 */
+ {0x44, 0x44, 0x44}, /* 17 CR93 */
+ {0x10, 0x10, 0x0A}, /* 18 CR94 */
+ {0x11, 0x11, 0x0a}, /* 19 CR95 */
+ {0x05, 0x05, 0x05}, /* 20 CR96 */
+ {0xf0, 0xf0, 0xf0}, /* 21 CRC3 */
+ {0x05, 0x00, 0x02}, /* 22 CRC4 */
+ {0x00, 0x00, 0x00} /* 23 CRC5 */
+};
+
+static const unsigned char XGI27_cr41[24][3] = {
+ {0x20, 0x40, 0x60}, /* 0 CR41 */
+ {0xC4, 0x40, 0x84}, /* 1 CR8A */
+ {0xC4, 0x40, 0x84}, /* 2 CR8B */
+ {0xB3, 0x13, 0xa4}, /* 3 CR40[7],
+ CR99[2:0],
+ CR45[3:0]*/
+ {0xf0, 0xf5, 0xf0}, /* 4 CR59 */
+ {0x90, 0x90, 0x24}, /* 5 CR68 */
+ {0x77, 0x67, 0x44}, /* 6 CR69 */
+ {0x77, 0x77, 0x44}, /* 7 CR6A */
+ {0xff, 0xff, 0xff}, /* 8 CR6D */
+ {0x55, 0x55, 0x55}, /* 9 CR80 */
+ {0x00, 0x00, 0x00}, /* 10 CR81 */
+ {0x88, 0xcc, 0x48}, /* 11 CR82 */
+ {0x44, 0x88, 0x77}, /* 12 CR85 */
+ {0x48, 0x88, 0x88}, /* 13 CR86 */
+ {0x54, 0x32, 0x44}, /* 14 CR90 */
+ {0x54, 0x33, 0x44}, /* 15 CR91 */
+ {0x0a, 0x07, 0x07}, /* 16 CR92 */
+ {0x44, 0x63, 0x44}, /* 17 CR93 */
+ {0x10, 0x14, 0x0A}, /* 18 CR94 */
+ {0x11, 0x0B, 0x0C}, /* 19 CR95 */
+ {0x05, 0x22, 0x05}, /* 20 CR96 */
+ {0xf0, 0xf0, 0x00}, /* 21 CRC3 */
+ {0x05, 0x00, 0x02}, /* 22 CRC4 */
+ {0x00, 0x00, 0x00} /* 23 CRC5 */
+};
+
+/* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */
+const unsigned char XGI340_AGPReg[12] = {
+ 0x28, 0x23, 0x00, 0x20, 0x00, 0x20,
+ 0x00, 0x05, 0xd0, 0x10, 0x10, 0x00
+};
+
+const struct XGI_ExtStruct XGI330_EModeIDTable[] = {
+ {0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06},
+ {0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05},
+ {0x30, 0x2a1b, 0x0407, 0x07, 0x07, 0x0e},
+ {0x31, 0x0a1b, 0x030d, 0x0d, 0x06, 0x3d},
+ {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x06, 0x3e},
+ {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x06, 0x3d},
+ {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x06, 0x3e},
+ {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x06, 0x3d},
+ {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x06, 0x3e},
+ {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x16},
+ {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x1e},
+ {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200
+ add CRT2MODE [2003/10/07] */
+ {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200
+ add CRT2MODE */
+ {0x40, 0x9a1c, 0x0000, 0x00, 0x04, 0x00},
+ {0x41, 0x9a1d, 0x0000, 0x00, 0x04, 0x00},
+ {0x43, 0x0a1c, 0x0306, 0x06, 0x05, 0x06},
+ {0x44, 0x0a1d, 0x0306, 0x06, 0x05, 0x06},
+ {0x46, 0x2a1c, 0x0407, 0x07, 0x07, 0x0e},
+ {0x47, 0x2a1d, 0x0407, 0x07, 0x07, 0x0e},
+ {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x16},
+ {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x16},
+ {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x1e},
+ {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x1e},
+ {0x50, 0x9a1b, 0x0001, 0x01, 0x04, 0x02},
+ {0x51, 0xba1b, 0x0103, 0x03, 0x07, 0x03},
+ {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x04},
+ {0x56, 0x9a1d, 0x0001, 0x01, 0x04, 0x02},
+ {0x57, 0xba1d, 0x0103, 0x03, 0x07, 0x03},
+ {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x04},
+ {0x59, 0x9a1b, 0x0000, 0x00, 0x04, 0x00},
+ {0x5A, 0x021b, 0x0014, 0x01, 0x04, 0x3f},
+ {0x5B, 0x0a1d, 0x0014, 0x01, 0x04, 0x3f},
+ {0x5d, 0x0a1d, 0x0305, 0x05, 0x07, 0x05},
+ {0x62, 0x0a3f, 0x0306, 0x06, 0x05, 0x06},
+ {0x63, 0x2a3f, 0x0407, 0x07, 0x07, 0x0e},
+ {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x16},
+ {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x1e},
+ {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200
+ add CRT2MODE */
+ {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x29},
+ {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x29},
+ {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x29},
+ {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x2f},
+ {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x2f},
+ {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x2f},
+ {0x70, 0x2a1b, 0x0410, 0x10, 0x07, 0x34},
+ {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x37},
+ {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x37},
+ {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x3a},
+ {0x76, 0x2a1f, 0x0410, 0x10, 0x07, 0x34},
+ {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x37},
+ {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x3a},
+ {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x3a},
+ {0x7a, 0x2a1d, 0x0410, 0x10, 0x07, 0x34},
+ {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x1d},
+ {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x1d},
+ {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x1d},
+ {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x43},
+ {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x43},
+ {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x43},
+ {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x41},
+ {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x41},
+ {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x41},
+ {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x42},
+ {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x42},
+ {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x42},
+ {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00}
+};
+
+static const struct SiS_StandTable_S XGI330_StandTable = {
+/* ExtVGATable */
+ 0x00, 0x00, 0x00, 0x0000,
+ {0x21, 0x0f, 0x00, 0x0e}, /* 0x21 = 0x01 | (0x20 = screen off) */
+ 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}
+};
+
+static const struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = {
+ {0x01, 0x27, 0x91, 0x8f, 0xc0}, /* 00 */
+ {0x03, 0x4f, 0x83, 0x8f, 0xc0}, /* 01 */
+ {0x05, 0x27, 0x91, 0x8f, 0xc0}, /* 02 */
+ {0x06, 0x4f, 0x83, 0x8f, 0xc0}, /* 03 */
+ {0x07, 0x4f, 0x83, 0x8f, 0xc0}, /* 04 */
+ {0x0d, 0x27, 0x91, 0x8f, 0xc0}, /* 05 */
+ {0x0e, 0x4f, 0x83, 0x8f, 0xc0}, /* 06 */
+ {0x0f, 0x4f, 0x83, 0x5d, 0xc0}, /* 07 */
+ {0x10, 0x4f, 0x83, 0x5d, 0xc0}, /* 08 */
+ {0x11, 0x4f, 0x83, 0xdf, 0x0c}, /* 09 */
+ {0x12, 0x4f, 0x83, 0xdf, 0x0c}, /* 10 */
+ {0x13, 0x4f, 0x83, 0x8f, 0xc0}, /* 11 */
+ {0x2e, 0x4f, 0x83, 0xdf, 0x0c}, /* 12 */
+ {0x2e, 0x4f, 0x87, 0xdf, 0xc0}, /* 13 */
+ {0x2f, 0x4f, 0x83, 0x8f, 0xc0}, /* 14 */
+ {0x50, 0x27, 0x91, 0xdf, 0x0c}, /* 15 */
+ {0x59, 0x27, 0x91, 0x8f, 0xc0} /* 16 */
+};
+
+const struct XGI_CRT1TableStruct XGI_CRT1Table[] = {
+ { {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00,
+ 0xbf, 0x1f, 0x9c, 0x8e, 0x96, 0xb9, 0x30} }, /* 0x0 */
+ { {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00,
+ 0x0b, 0x3e, 0xe9, 0x8b, 0xe7, 0x04, 0x00} }, /* 0x1 */
+ { {0x3D, 0x31, 0x81, 0x37, 0x1F, 0x00, 0x05, 0x00,
+ 0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, /* 0x2 */
+ { {0x4F, 0x3F, 0x93, 0x45, 0x0D, 0x00, 0x01, 0x00,
+ 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x3 */
+ { {0x5F, 0x50, 0x82, 0x55, 0x81, 0x00, 0x05, 0x00,
+ 0xBF, 0x1F, 0x9C, 0x8E, 0x96, 0xB9, 0x30} }, /* 0x4 */
+ { {0x5F, 0x50, 0x82, 0x55, 0x81, 0x00, 0x05, 0x00,
+ 0x0B, 0x3E, 0xE9, 0x8B, 0xE7, 0x04, 0x00} }, /* 0x5 */
+ { {0x63, 0x50, 0x86, 0x56, 0x9B, 0x00, 0x01, 0x00,
+ 0x06, 0x3E, 0xE8, 0x8B, 0xE7, 0xFF, 0x10} }, /* 0x6 */
+ { {0x64, 0x4F, 0x88, 0x55, 0x9D, 0x00, 0x01, 0x00,
+ 0xF2, 0x1F, 0xE0, 0x83, 0xDF, 0xF3, 0x10} }, /* 0x7 */
+ { {0x63, 0x4F, 0x87, 0x5A, 0x81, 0x00, 0x05, 0x00,
+ 0xFB, 0x1F, 0xE0, 0x83, 0xDF, 0xFC, 0x10} }, /* 0x8 */
+ { {0x65, 0x4F, 0x89, 0x58, 0x80, 0x00, 0x05, 0x60,
+ 0xFB, 0x1F, 0xE0, 0x83, 0xDF, 0xFC, 0x80} }, /* 0x9 */
+ { {0x65, 0x4F, 0x89, 0x58, 0x80, 0x00, 0x05, 0x60,
+ 0x01, 0x3E, 0xE0, 0x83, 0xDF, 0x02, 0x80} }, /* 0xa */
+ { {0x67, 0x4F, 0x8B, 0x58, 0x81, 0x00, 0x05, 0x60,
+ 0x0D, 0x3E, 0xE0, 0x83, 0xDF, 0x0E, 0x90} }, /* 0xb */
+ { {0x65, 0x4F, 0x89, 0x57, 0x9F, 0x00, 0x01, 0x00,
+ 0xFB, 0x1F, 0xE6, 0x8A, 0xDF, 0xFC, 0x10} }, /* 0xc */
+ { {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00, /* ;
+ 0D (800x600,56Hz) */
+ 0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, /* ;
+ (VCLK 36.0MHz) */
+ { {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00, /* ;
+ 0E (800x600,60Hz) */
+ 0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, /* ;
+ (VCLK 40.0MHz) */
+ { {0x7D, 0x63, 0x81, 0x6E, 0x1D, 0x00, 0x06, 0x00, /* ;
+ 0F (800x600,72Hz) */
+ 0x98, 0xF0, 0x7C, 0x82, 0x57, 0x99, 0x80} }, /* ;
+ (VCLK 50.0MHz) */
+ { {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00, /* ;
+ 10 (800x600,75Hz) */
+ 0x6F, 0xF0, 0x58, 0x8B, 0x57, 0x70, 0xA0} }, /* ;
+ (VCLK 49.5MHz) */
+ { {0x7E, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00, /* ;
+ 11 (800x600,85Hz) */
+ 0x75, 0xF0, 0x58, 0x8B, 0x57, 0x76, 0xA0} }, /* ;
+ (VCLK 56.25MHz) */
+ { {0x81, 0x63, 0x85, 0x6D, 0x18, 0x00, 0x06, 0x60, /* ;
+ 12 (800x600,100Hz) */
+ 0x7A, 0xF0, 0x58, 0x8B, 0x57, 0x7B, 0xA0} }, /* ;
+ (VCLK 75.8MHz) */
+ { {0x83, 0x63, 0x87, 0x6E, 0x19, 0x00, 0x06, 0x60, /* ;
+ 13 (800x600,120Hz) */
+ 0x81, 0xF0, 0x58, 0x8B, 0x57, 0x82, 0xA0} }, /* ;
+ (VCLK 79.411MHz) */
+ { {0x85, 0x63, 0x89, 0x6F, 0x1A, 0x00, 0x06, 0x60, /* ;
+ 14 (800x600,160Hz) */
+ 0x91, 0xF0, 0x58, 0x8B, 0x57, 0x92, 0xA0} }, /* ;
+ (VCLK 105.822MHz) */
+ { {0x99, 0x7F, 0x9D, 0x84, 0x1A, 0x00, 0x02, 0x00,
+ 0x96, 0x1F, 0x7F, 0x83, 0x7F, 0x97, 0x10} }, /* 0x15 */
+ { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00,
+ 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x16 */
+ { {0xA1, 0x7F, 0x85, 0x86, 0x97, 0x00, 0x02, 0x00,
+ 0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x17 */
+ { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00,
+ 0x1E, 0xF5, 0x00, 0x83, 0xFF, 0x1F, 0x90} }, /* 0x18 */
+ { {0xA7, 0x7F, 0x8B, 0x89, 0x95, 0x00, 0x02, 0x00,
+ 0x26, 0xF5, 0x00, 0x83, 0xFF, 0x27, 0x90} }, /* 0x19 */
+ { {0xA9, 0x7F, 0x8D, 0x8C, 0x9A, 0x00, 0x02, 0x62,
+ 0x2C, 0xF5, 0x00, 0x83, 0xFF, 0x2D, 0x14} }, /* 0x1a */
+ { {0xAB, 0x7F, 0x8F, 0x8D, 0x9B, 0x00, 0x02, 0x62,
+ 0x35, 0xF5, 0x00, 0x83, 0xFF, 0x36, 0x14} }, /* 0x1b */
+ { {0xCF, 0x9F, 0x93, 0xB2, 0x01, 0x00, 0x03, 0x00,
+ 0x14, 0xBA, 0x00, 0x83, 0xFF, 0x15, 0x00} }, /* 0x1c */
+ { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00,
+ 0x28, 0x5A, 0x00, 0x83, 0xFF, 0x29, 0x89} }, /* 0x1d */
+ { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00,
+ 0x28, 0x5A, 0x00, 0x83, 0xFF, 0x29, 0x89} }, /* 0x1e */
+ { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x00,
+ 0x2E, 0x5A, 0x00, 0x83, 0xFF, 0x2F, 0x89} }, /* 0x1f */
+ { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+ 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x20 */
+ { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+ 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x21 */
+ { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+ 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x22 */
+ { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+ 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x23 */
+ { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+ 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x24 */
+ { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+ 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x25 */
+ { {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+ 0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x26 */
+ { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00,
+ 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x27 */
+ { {0x43, 0xEF, 0x87, 0x06, 0x00, 0x41, 0x05, 0x62,
+ 0xD4, 0x1F, 0xA0, 0x83, 0x9F, 0xD5, 0x9F} }, /* 0x28 */
+ { {0x45, 0xEF, 0x89, 0x07, 0x01, 0x41, 0x05, 0x62,
+ 0xD9, 0x1F, 0xA0, 0x83, 0x9F, 0xDA, 0x9F} }, /* 0x29 */
+ { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00,
+ 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2a */
+ { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00,
+ 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2b */
+ { {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00,
+ 0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2c */
+ { {0x59, 0xFF, 0x9D, 0x17, 0x13, 0x41, 0x05, 0x44,
+ 0x33, 0xBA, 0x00, 0x83, 0xFF, 0x34, 0x0F} }, /* 0x2d */
+ { {0x5B, 0xFF, 0x9F, 0x18, 0x14, 0x41, 0x05, 0x44,
+ 0x38, 0xBA, 0x00, 0x83, 0xFF, 0x39, 0x0F} }, /* 0x2e */
+ { {0x5B, 0xFF, 0x9F, 0x18, 0x14, 0x41, 0x05, 0x44,
+ 0x3D, 0xBA, 0x00, 0x83, 0xFF, 0x3E, 0x0F} }, /* 0x2f */
+ { {0x5D, 0xFF, 0x81, 0x19, 0x95, 0x41, 0x05, 0x44,
+ 0x41, 0xBA, 0x00, 0x84, 0xFF, 0x42, 0x0F} }, /* 0x30 */
+ { {0x55, 0xFF, 0x99, 0x0D, 0x0C, 0x41, 0x05, 0x00,
+ 0x3E, 0xBA, 0x00, 0x84, 0xFF, 0x3F, 0x0F} }, /* 0x31 */
+ { {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00,
+ 0x72, 0xBA, 0x27, 0x8B, 0xDF, 0x73, 0x80} }, /* 0x32 */
+ { {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00,
+ 0x6F, 0xBA, 0x26, 0x89, 0xDF, 0x6F, 0x80} }, /* 0x33 */
+ { {0x7F, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00,
+ 0x75, 0xBA, 0x29, 0x8C, 0xDF, 0x75, 0x80} }, /* 0x34 */
+ { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00,
+ 0x24, 0xF1, 0xAF, 0x85, 0x3F, 0x25, 0xB0} }, /* 0x35 */
+ { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00,
+ 0x1E, 0xF1, 0xAD, 0x81, 0x3F, 0x1F, 0xB0} }, /* 0x36 */
+ { {0xA7, 0x7F, 0x88, 0x89, 0x15, 0x00, 0x02, 0x00,
+ 0x26, 0xF1, 0xB1, 0x85, 0x3F, 0x27, 0xB0} }, /* 0x37 */
+ { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00,
+ 0x28, 0xC4, 0x7A, 0x8E, 0xCF, 0x29, 0xA1} }, /* 0x38 */
+ { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00,
+ 0x28, 0xD4, 0x7A, 0x8E, 0xCF, 0x29, 0xA1} }, /* 0x39 */
+ { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x00,
+ 0x2E, 0xD4, 0x7D, 0x81, 0xCF, 0x2F, 0xA1} }, /* 0x3a */
+ { {0xDC, 0x9F, 0x00, 0xAB, 0x19, 0x00, 0x07, 0x00,
+ 0xE6, 0xEF, 0xC0, 0xC3, 0xBF, 0xE7, 0x90} }, /* 0x3b */
+ { {0x6B, 0x59, 0x8F, 0x5E, 0x8C, 0x00, 0x05, 0x00,
+ 0x0B, 0x3E, 0xE9, 0x8B, 0xE7, 0x04, 0x00} }, /* 0x3c */
+ { {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00,
+ 0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, /* 0x3d */
+ { {0x86, 0x6A, 0x8a, 0x74, 0x06, 0x00, 0x02, 0x00,
+ 0x8c, 0x15, 0x4f, 0x83, 0xef, 0x8d, 0x30} }, /* 0x3e */
+ { {0x81, 0x6A, 0x85, 0x70, 0x00, 0x00, 0x02, 0x00,
+ 0x0f, 0x3e, 0xeb, 0x8e, 0xdf, 0x10, 0x00} }, /* 0x3f */
+ { {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00,
+ 0x20, 0xF5, 0x03, 0x88, 0xFF, 0x21, 0x90} }, /* 0x40 */
+ { {0xE6, 0xAE, 0x8A, 0xBD, 0x90, 0x00, 0x03, 0x00,
+ 0x3D, 0x10, 0x1A, 0x8D, 0x19, 0x3E, 0x2F} }, /* 0x41 */
+ { {0xB9, 0x8F, 0x9D, 0x9B, 0x8A, 0x00, 0x06, 0x00,
+ 0x7D, 0xFF, 0x60, 0x83, 0x5F, 0x7E, 0x90} }, /* 0x42 */
+ { {0xC3, 0x8F, 0x87, 0x9B, 0x0B, 0x00, 0x07, 0x00,
+ 0x82, 0xFF, 0x60, 0x83, 0x5F, 0x83, 0x90} }, /* 0x43 */
+ { {0xAD, 0x7F, 0x91, 0x8E, 0x9C, 0x00, 0x02, 0x82,
+ 0x49, 0xF5, 0x00, 0x83, 0xFF, 0x4A, 0x90} }, /* 0x44 */
+ { {0xCD, 0x9F, 0x91, 0xA7, 0x19, 0x00, 0x07, 0x60,
+ 0xE6, 0xFF, 0xC0, 0x83, 0xBF, 0xE7, 0x90} }, /* 0x45 */
+ { {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x60,
+ 0xF1, 0xFF, 0xC0, 0x83, 0xBF, 0xF2, 0x90} }, /* 0x46 */
+ { {0xD7, 0x9F, 0x9B, 0xAC, 0x1E, 0x00, 0x07, 0x00,
+ 0x03, 0xDE, 0xC0, 0x84, 0xBF, 0x04, 0x90} } /* 0x47 */
+};
+
+/*add for new UNIVGABIOS*/
+static const struct SiS_LCDData XGI_StLCD1024x768Data[] = {
+ {62, 25, 800, 546, 1344, 806},
+ {32, 15, 930, 546, 1344, 806},
+ {62, 25, 800, 546, 1344, 806}, /*chiawenfordot9->dot8*/
+ {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 struct SiS_LCDData XGI_ExtLCD1024x768Data[] = {
+ {42, 25, 1536, 419, 1344, 806},
+ {48, 25, 1536, 369, 1344, 806},
+ {42, 25, 1536, 419, 1344, 806},
+ {48, 25, 1536, 369, 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 struct SiS_LCDData XGI_CetLCD1024x768Data[] = {
+ {1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400,
+ 640x200,640x400) */
+ {1, 1, 1344, 806, 1344, 806}, /* 01 (320x350,640x350) */
+ {1, 1, 1344, 806, 1344, 806}, /* 02 (360x400,720x400) */
+ {1, 1, 1344, 806, 1344, 806}, /* 03 (720x350) */
+ {1, 1, 1344, 806, 1344, 806}, /* 04 (640x480x60Hz) */
+ {1, 1, 1344, 806, 1344, 806}, /* 05 (800x600x60Hz) */
+ {1, 1, 1344, 806, 1344, 806} /* 06 (1024x768x60Hz) */
+};
+
+static const struct SiS_LCDData XGI_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 struct SiS_LCDData XGI_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 struct SiS_LCDData XGI_CetLCD1280x1024Data[] = {
+ {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* 02 (360x400,720x400) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* 03 (720x350) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* 04 (640x480x60Hz) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* 05 (800x600x60Hz) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* 06 (1024x768x60Hz) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */
+ {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */
+};
+
+static const struct SiS_LCDData xgifb_lcd_1400x1050[] = {
+ {211, 100, 2100, 408, 1688, 1066}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {211, 64, 1536, 358, 1688, 1066}, /* 01 (320x350,640x350) */
+ {211, 100, 2100, 408, 1688, 1066}, /* 02 (360x400,720x400) */
+ {211, 64, 1536, 358, 1688, 1066}, /* 03 (720x350) */
+ {211, 48, 840, 488, 1688, 1066}, /* 04 (640x480x60Hz) */
+ {211, 72, 1008, 609, 1688, 1066}, /* 05 (800x600x60Hz) */
+ {211, 128, 1400, 776, 1688, 1066}, /* 06 (1024x768x60Hz) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz
+ w/o Scaling) */
+ {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */
+};
+
+static const struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = {
+ {4, 1, 1620, 420, 2160, 1250}, /* 00 (320x200,320x400,
+ 640x200,640x400)*/
+ {27, 7, 1920, 375, 2160, 1250}, /* 01 (320x350,640x350) */
+ {4, 1, 1620, 420, 2160, 1250}, /* 02 (360x400,720x400)*/
+ {27, 7, 1920, 375, 2160, 1250}, /* 03 (720x350) */
+ {27, 4, 800, 500, 2160, 1250}, /* 04 (640x480x60Hz) */
+ {4, 1, 1080, 625, 2160, 1250}, /* 05 (800x600x60Hz) */
+ {5, 2, 1350, 800, 2160, 1250}, /* 06 (1024x768x60Hz) */
+ {27, 16, 1500, 1064, 2160, 1250}, /* 07 (1280x1024x60Hz) */
+ {9, 7, 1920, 1106, 2160, 1250}, /* 08 (1400x1050x60Hz) */
+ {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200x60Hz) ;302lv */
+};
+
+static const struct SiS_LCDData XGI_StLCD1600x1200Data[] = {
+ {27, 4, 800, 500, 2160, 1250}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {27, 4, 800, 500, 2160, 1250}, /* 01 (320x350,640x350) */
+ {27, 4, 800, 500, 2160, 1250}, /* 02 (360x400,720x400) */
+ {27, 4, 800, 500, 2160, 1250}, /* 03 (720x350) */
+ {27, 4, 800, 500, 2160, 1250}, /* 04 (320x240,640x480) */
+ {4, 1, 1080, 625, 2160, 1250}, /* 05 (400x300,800x600) */
+ {5, 2, 1350, 800, 2160, 1250}, /* 06 (512x384,1024x768) */
+ {135, 88, 1600, 1100, 2160, 1250}, /* 07 (1280x1024) */
+ {1, 1, 1800, 1500, 2160, 1250}, /* 08 (1400x1050) */
+ {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200) */
+};
+
+#define XGI_CetLCD1400x1050Data XGI_CetLCD1280x1024Data
+
+static const struct SiS_LCDData XGI_NoScalingData[] = {
+ {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 struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = {
+ {42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400,
+ 640x200,640x400) */
+ {48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */
+ {42, 25, 1536, 419, 1344, 806}, /* ; 02 (360x400,720x400) */
+ {48, 25, 1536, 369, 1344, 806}, /* ; 03 (720x350) */
+ {8, 5, 1312, 500, 1312, 800}, /* ; 04 (640x480x75Hz) */
+ {41, 25, 1024, 625, 1312, 800}, /* ; 05 (800x600x75Hz) */
+ {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */
+};
+
+static const struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = {
+ {1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,
+ 640x200,640x400) */
+ {1, 1, 1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */
+ {1, 1, 1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */
+ {1, 1, 1312, 800, 1312, 800}, /* ; 03 (720x350) */
+ {1, 1, 1312, 800, 1312, 800}, /* ; 04 (640x480x75Hz) */
+ {1, 1, 1312, 800, 1312, 800}, /* ; 05 (800x600x75Hz) */
+ {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */
+};
+
+static const struct SiS_LCDData xgifb_lcd_1280x1024x75[] = {
+ {211, 60, 1024, 501, 1688, 1066}, /* ; 00 (320x200,320x400,
+ 640x200,640x400) */
+ {211, 60, 1024, 508, 1688, 1066}, /* ; 01 (320x350,640x350) */
+ {211, 60, 1024, 501, 1688, 1066}, /* ; 02 (360x400,720x400) */
+ {211, 60, 1024, 508, 1688, 1066}, /* ; 03 (720x350) */
+ {211, 45, 768, 498, 1688, 1066}, /* ; 04 (640x480x75Hz) */
+ {211, 75, 1024, 625, 1688, 1066}, /* ; 05 (800x600x75Hz) */
+ {211, 120, 1280, 798, 1688, 1066}, /* ; 06 (1024x768x75Hz) */
+ {1, 1, 1688, 1066, 1688, 1066} /* ; 07 (1280x1024x75Hz) */
+};
+
+#define XGI_CetLCD1280x1024x75Data XGI_CetLCD1280x1024Data
+
+static const struct SiS_LCDData XGI_NoScalingDatax75[] = {
+ {1, 1, 800, 449, 800, 449}, /* ; 00 (320x200, 320x400,
+ 640x200, 640x400) */
+ {1, 1, 800, 449, 800, 449}, /* ; 01 (320x350, 640x350) */
+ {1, 1, 900, 449, 900, 449}, /* ; 02 (360x400, 720x400) */
+ {1, 1, 900, 449, 900, 449}, /* ; 03 (720x350) */
+ {1, 1, 840, 500, 840, 500}, /* ; 04 (640x480x75Hz) */
+ {1, 1, 1056, 625, 1056, 625}, /* ; 05 (800x600x75Hz) */
+ {1, 1, 1312, 800, 1312, 800}, /* ; 06 (1024x768x75Hz) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */
+ {1, 1, 1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz)*/
+ {1, 1, 2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */
+ {1, 1, 1688, 806, 1688, 806} /* ; 0A (1280x768x75Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = {
+ {9, 1057, 0, 771}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {9, 1057, 0, 771}, /* ; 01 (320x350,640x350) */
+ {9, 1057, 0, 771}, /* ; 02 (360x400,720x400) */
+ {9, 1057, 0, 771}, /* ; 03 (720x350) */
+ {9, 1057, 0, 771}, /* ; 04 (640x480x60Hz) */
+ {9, 1057, 0, 771}, /* ; 05 (800x600x60Hz) */
+ {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = {
+ {9, 1057, 737, 703}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {9, 1057, 686, 651}, /* ; 01 (320x350,640x350) */
+ {9, 1057, 737, 703}, /* ; 02 (360x400,720x400) */
+ {9, 1057, 686, 651}, /* ; 03 (720x350) */
+ {9, 1057, 776, 741}, /* ; 04 (640x480x60Hz) */
+ {9, 1057, 0, 771}, /* ; 05 (800x600x60Hz) */
+ {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = {
+ {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */
+ {1152, 856, 622, 587}, /* ; 02 (360x400,720x400) */
+ {1152, 856, 597, 562}, /* ; 03 (720x350) */
+ {1152, 856, 662, 627}, /* ; 04 (640x480x60Hz) */
+ {1232, 936, 722, 687}, /* ; 05 (800x600x60Hz) */
+ {0, 1048, 805, 770} /* ; 06 (1024x768x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = {
+ {18, 1346, 981, 940}, /* 00 (320x200,320x400,640x200,640x400) */
+ {18, 1346, 926, 865}, /* 01 (320x350,640x350) */
+ {18, 1346, 981, 940}, /* 02 (360x400,720x400) */
+ {18, 1346, 926, 865}, /* 03 (720x350) */
+ {18, 1346, 0, 1025}, /* 04 (640x480x60Hz) */
+ {18, 1346, 0, 1025}, /* 05 (800x600x60Hz) */
+ {18, 1346, 1065, 1024}, /* 06 (1024x768x60Hz) */
+ {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = {
+ {18, 1346, 970, 907}, /* 00 (320x200,320x400,640x200,640x400) */
+ {18, 1346, 917, 854}, /* 01 (320x350,640x350) */
+ {18, 1346, 970, 907}, /* 02 (360x400,720x400) */
+ {18, 1346, 917, 854}, /* 03 (720x350) */
+ {18, 1346, 0, 1025}, /* 04 (640x480x60Hz) */
+ {18, 1346, 0, 1025}, /* 05 (800x600x60Hz) */
+ {18, 1346, 1065, 1024}, /* 06 (1024x768x60Hz) */
+ {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = {
+ {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */
+ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */
+ {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */
+ {1368, 1008, 729, 688}, /* 03 (720x350) */
+ {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */
+ {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */
+ {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */
+ {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = {
+ {9, 1337, 981, 940}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {9, 1337, 926, 884}, /* ; 01 (320x350,640x350) alan, 2003/09/30 */
+ {9, 1337, 981, 940}, /* ; 02 (360x400,720x400) */
+ {9, 1337, 926, 884}, /* ; 03 (720x350) alan, 2003/09/30 */
+ {9, 1337, 0, 1025}, /* ; 04 (640x480x60Hz) */
+ {9, 1337, 0, 1025}, /* ; 05 (800x600x60Hz) */
+ {9, 1337, 1065, 1024}, /* ; 06 (1024x768x60Hz) */
+ {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = {
+ {9, 1337, 970, 907}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {9, 1337, 917, 854}, /* ; 01 (320x350,640x350) */
+ {9, 1337, 970, 907}, /* ; 02 (360x400,720x400) */
+ {9, 1337, 917, 854}, /* ; 03 (720x350) */
+ {9, 1337, 0, 1025}, /* ; 04 (640x480x60Hz) */
+ {9, 1337, 0, 1025}, /* ; 05 (800x600x60Hz) */
+ {9, 1337, 1065, 1024}, /* ; 06 (1024x768x60Hz) */
+ {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = {
+ {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */
+ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */
+ {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */
+ {1368, 1008, 729, 688}, /* 03 (720x350) */
+ {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */
+ {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */
+ {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */
+ {9, 1337, 1065, 1024} /* 07 (1280x1024x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = {
+ {18, 1464, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
+ {18, 1464, 0, 1051}, /* 01 (320x350,640x350) */
+ {18, 1464, 0, 1051}, /* 02 (360x400,720x400) */
+ {18, 1464, 0, 1051}, /* 03 (720x350) */
+ {18, 1464, 0, 1051}, /* 04 (640x480x60Hz) */
+ {18, 1464, 0, 1051}, /* 05 (800x600x60Hz) */
+ {18, 1464, 0, 1051}, /* 06 (1024x768x60Hz) */
+ {1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+ {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = {
+ {9, 1455, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
+ {9, 1455, 0, 1051}, /* 01 (320x350,640x350) */
+ {9, 1455, 0, 1051}, /* 02 (360x400,720x400) */
+ {9, 1455, 0, 1051}, /* 03 (720x350) */
+ {9, 1455, 0, 1051}, /* 04 (640x480x60Hz) */
+ {9, 1455, 0, 1051}, /* 05 (800x600x60Hz) */
+ {9, 1455, 0, 1051}, /* 06 (1024x768x60Hz) */
+ {1637, 1397, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+ {9, 1455, 0, 1051} /* 08 (1400x1050x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = {
+ {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */
+ {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */
+ {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */
+ {1308, 1068, 781, 766}, /* 03 (720x350) */
+ {1308, 1068, 781, 766}, /* 04 (640x480x60Hz) */
+ {1388, 1148, 841, 826}, /* 05 (800x600x60Hz) */
+ {1490, 1250, 925, 910}, /* 06 (1024x768x60Hz) */
+ {1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+ {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = {
+ {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
+ {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */
+ {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */
+ {0, 1448, 0, 1051}, /* 03 (720x350) */
+ {0, 1448, 0, 1051} /* 04 (640x480x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = {
+ {18, 1682, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
+ {18, 1682, 0, 1201}, /* 01 (320x350,640x350) */
+ {18, 1682, 0, 1201}, /* 02 (360x400,720x400) */
+ {18, 1682, 0, 1201}, /* 03 (720x350) */
+ {18, 1682, 0, 1201}, /* 04 (640x480x60Hz) */
+ {18, 1682, 0, 1201}, /* 05 (800x600x60Hz) */
+ {18, 1682, 0, 1201}, /* 06 (1024x768x60Hz) */
+ {18, 1682, 0, 1201}, /* 07 (1280x1024x60Hz) */
+ {18, 1682, 0, 1201}, /* 08 (1400x1050x60Hz) */
+ {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = {
+ {18, 1682, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */
+ {18, 1682, 1083, 1034}, /* 01 (320x350,640x350) */
+ {18, 1682, 1150, 1101}, /* 02 (360x400,720x400) */
+ {18, 1682, 1083, 1034}, /* 03 (720x350) */
+ {18, 1682, 0, 1201}, /* 04 (640x480x60Hz) */
+ {18, 1682, 0, 1201}, /* 05 (800x600x60Hz) */
+ {18, 1682, 0, 1201}, /* 06 (1024x768x60Hz) */
+ {18, 1682, 1232, 1183}, /* 07 (1280x1024x60Hz) */
+ {18, 1682, 0, 1201}, /* 08 (1400x1050x60Hz) */
+ {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = {
+ {9, 1673, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
+ {9, 1673, 0, 1201}, /* 01 (320x350,640x350) */
+ {9, 1673, 0, 1201}, /* 02 (360x400,720x400) */
+ {9, 1673, 0, 1201}, /* 03 (720x350) */
+ {9, 1673, 0, 1201}, /* 04 (640x480x60Hz) */
+ {9, 1673, 0, 1201}, /* 05 (800x600x60Hz) */
+ {9, 1673, 0, 1201}, /* 06 (1024x768x60Hz) */
+ {9, 1673, 0, 1201}, /* 07 (1280x1024x60Hz) */
+ {9, 1673, 0, 1201}, /* 08 (1400x1050x60Hz) */
+ {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */
+};
+
+static const struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = {
+ {9, 1673, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */
+ {9, 1673, 1083, 1034}, /* 01 (320x350,640x350) */
+ {9, 1673, 1150, 1101}, /* 02 (360x400,720x400) */
+ {9, 1673, 1083, 1034}, /* 03 (720x350) */
+ {9, 1673, 0, 1201}, /* 04 (640x480x60Hz) */
+ {9, 1673, 0, 1201}, /* 05 (800x600x60Hz) */
+ {9, 1673, 0, 1201}, /* 06 (1024x768x60Hz) */
+ {9, 1673, 1232, 1183}, /* 07 (1280x1024x60Hz) */
+ {9, 1673, 0, 1201}, /* 08 (1400x1050x60Hz) */
+ {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */
+};
+
+static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = {
+ {9, 657, 448, 405, 96, 2}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {9, 657, 448, 355, 96, 2}, /* 01 (320x350,640x350) */
+ {9, 657, 448, 405, 96, 2}, /* 02 (360x400,720x400) */
+ {9, 657, 448, 355, 96, 2}, /* 03 (720x350) */
+ {9, 657, 1, 483, 96, 2}, /* 04 (640x480x60Hz) */
+ {9, 849, 627, 600, 128, 4}, /* 05 (800x600x60Hz) */
+ {9, 1057, 805, 770, 0136, 6}, /* 06 (1024x768x60Hz) */
+ {9, 1337, 0, 1025, 112, 3}, /* 07 (1280x1024x60Hz) */
+ {9, 1457, 0, 1051, 112, 3}, /* 08 (1400x1050x60Hz)*/
+ {9, 1673, 0, 1201, 192, 3}, /* 09 (1600x1200x60Hz) */
+ {9, 1337, 0, 771, 112, 6} /* 0A (1280x768x60Hz) */
+};
+
+/* ;;1024x768x75Hz */
+static const struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = {
+ {9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */
+ {9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */
+ {9, 1049, 0, 769}, /* ; 03 (720x350) */
+ {9, 1049, 0, 769}, /* ; 04 (640x480x75Hz) */
+ {9, 1049, 0, 769}, /* ; 05 (800x600x75Hz) */
+ {9, 1049, 0, 769} /* ; 06 (1024x768x75Hz) */
+};
+
+/* ;;1024x768x75Hz */
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = {
+ {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */
+ {1192, 896, 622, 587}, /* ; 02 (360x400,720x400) */
+ {1192, 896, 597, 562}, /* ; 03 (720x350) */
+ {1129, 857, 656, 625}, /* ; 04 (640x480x75Hz) */
+ {1209, 937, 716, 685}, /* ; 05 (800x600x75Hz) */
+ {9, 1049, 0, 769} /* ; 06 (1024x768x75Hz) */
+};
+
+/* ;;1280x1024x75Hz */
+static const struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = {
+ {18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */
+ {18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */
+ {18, 1314, 0, 1025}, /* ; 03 (720x350) */
+ {18, 1314, 0, 1025}, /* ; 04 (640x480x60Hz) */
+ {18, 1314, 0, 1025}, /* ; 05 (800x600x60Hz) */
+ {18, 1314, 0, 1025}, /* ; 06 (1024x768x60Hz) */
+ {18, 1314, 0, 1025} /* ; 07 (1280x1024x60Hz) */
+};
+
+/* 1280x1024x75Hz */
+static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = {
+ {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */
+ {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */
+ {1408, 1048, 729, 688}, /* ; 03 (720x350) */
+ {1377, 985, 794, 753}, /* ; 04 (640x480x75Hz) */
+ {1457, 1065, 854, 813}, /* ; 05 (800x600x75Hz) */
+ {1569, 1177, 938, 897}, /* ; 06 (1024x768x75Hz) */
+ {18, 1314, 0, 1025} /* ; 07 (1280x1024x75Hz) */
+};
+
+/* ;;1280x1024x75Hz */
+static const struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = {
+ {9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */
+ {9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */
+ {9, 1305, 0, 1025}, /* ; 03 (720x350) */
+ {9, 1305, 0, 1025}, /* ; 04 (640x480x60Hz) */
+ {9, 1305, 0, 1025}, /* ; 05 (800x600x60Hz) */
+ {9, 1305, 0, 1025}, /* ; 06 (1024x768x60Hz) */
+ {9, 1305, 0, 1025} /* ; 07 (1280x1024x60Hz) */
+};
+
+/* 1280x1024x75Hz */
+static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = {
+ {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */
+ {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */
+ {1408, 1048, 729, 688}, /* ; 03 (720x350) */
+ {1377, 985, 794, 753}, /* ; 04 (640x480x75Hz) */
+ {1457, 1065, 854, 813}, /* ; 05 (800x600x75Hz) */
+ {1569, 1177, 938, 897}, /* ; 06 (1024x768x75Hz) */
+ {9, 1305, 0, 1025} /* ; 07 (1280x1024x75Hz) */
+};
+
+/* Scaling LCD 75Hz */
+static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = {
+ {9, 657, 448, 405, 96, 2}, /* ; 00 (320x200,320x400,
+ 640x200,640x400) */
+ {9, 657, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */
+ {9, 738, 448, 405, 108, 2}, /* ; 02 (360x400,720x400) */
+ {9, 738, 448, 355, 108, 2}, /* ; 03 (720x350) */
+ {9, 665, 0, 481, 64, 3}, /* ; 04 (640x480x75Hz) */
+ {9, 825, 0, 601, 80, 3}, /* ; 05 (800x600x75Hz) */
+ {9, 1049, 0, 769, 96, 3}, /* ; 06 (1024x768x75Hz) */
+ {9, 1305, 0, 1025, 144, 3}, /* ; 07 (1280x1024x75Hz) */
+ {9, 1457, 0, 1051, 112, 3}, /* ; 08 (1400x1050x60Hz)*/
+ {9, 1673, 0, 1201, 192, 3}, /* ; 09 (1600x1200x75Hz) */
+ {9, 1337, 0, 771, 112, 6} /* ; 0A (1280x768x60Hz) */
+};
+
+static const struct SiS_TVData XGI_StPALData[] = {
+ {1, 1, 864, 525, 1270, 400, 100, 0, 760},
+ {1, 1, 864, 525, 1270, 350, 100, 0, 760},
+ {1, 1, 864, 525, 1270, 400, 0, 0, 720},
+ {1, 1, 864, 525, 1270, 350, 0, 0, 720},
+ {1, 1, 864, 525, 1270, 480, 50, 0, 760},
+ {1, 1, 864, 525, 1270, 600, 50, 0, 0}
+};
+
+static const struct SiS_TVData XGI_ExtPALData[] = {
+ {2, 1, 1080, 463, 1270, 500, 50, 0, 50},
+ {15, 7, 1152, 413, 1270, 500, 50, 0, 50},
+ {2, 1, 1080, 463, 1270, 500, 50, 0, 50},
+ {15, 7, 1152, 413, 1270, 500, 50, 0, 50},
+ {2, 1, 900, 543, 1270, 500, 0, 0, 50},
+ {4, 3, 1080, 663, 1270, 500, 438, 0, 438},
+ {1, 1, 1125, 831, 1270, 500, 686, 0, 686}, /*301b*/
+ {3, 2, 1080, 619, 1270, 540, 438, 0, 438}
+};
+
+static const struct SiS_TVData XGI_StNTSCData[] = {
+ {1, 1, 858, 525, 1270, 400, 50, 0, 760},
+ {1, 1, 858, 525, 1270, 350, 50, 0, 640},
+ {1, 1, 858, 525, 1270, 400, 0, 0, 720},
+ {1, 1, 858, 525, 1270, 350, 0, 0, 720},
+ {1, 1, 858, 525, 1270, 480, 0, 0, 760}
+};
+
+static const struct SiS_TVData XGI_ExtNTSCData[] = {
+ {9, 5, 1001, 453, 1270, 420, 171, 0, 171},
+ {12, 5, 858, 403, 1270, 420, 171, 0, 171},
+ {9, 5, 1001, 453, 1270, 420, 171, 0, 171},
+ {12, 5, 858, 403, 1270, 420, 171, 0, 171},
+ {143, 80, 836, 523, 1270, 420, 224, 0, 0},
+ {143, 120, 1008, 643, 1270, 420, 0, 1, 0},
+ {1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/
+ {2, 1, 858, 503, 1584, 480, 0, 1, 0},
+ {3, 2, 1001, 533, 1270, 420, 0, 0, 0}
+};
+
+static const struct SiS_TVData XGI_St1HiTVData[] = {
+ {1, 1, 892, 563, 690, 800, 0, 0, 0}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */
+ {1, 1, 1000, 563, 785, 800, 0, 0, 0}, /* 02 (360x400,720x400) */
+ {1, 1, 1000, 563, 785, 700, 0, 0, 0}, /* 03 (720x350) */
+ {1, 1, 892, 563, 690, 960, 0, 0, 0}, /* 04 (320x240,640x480) */
+ {8, 5, 1050, 683, 1648, 960, 0x150, 1, 0} /* 05 (400x300,800x600) */
+};
+
+static const struct SiS_TVData XGI_St2HiTVData[] = {
+ {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {1, 1, 892, 563, 690, 700, 0, 0, 0}, /* 01 (320x350,640x350) */
+ {3, 1, 840, 483, 1648, 960, 0x032, 0, 0}, /* 02 (360x400,720x400) */
+ {1, 1, 1000, 563, 785, 700, 0, 0, 0}, /* 03 (720x350) */
+ {5, 2, 840, 563, 1648, 960, 0x08D, 1, 0}, /* 04 (320x240,640x480) */
+ {8, 5, 1050, 683, 1648, 960, 0x17C, 1, 0} /* 05 (400x300,800x600) */
+};
+
+static const struct SiS_TVData XGI_ExtHiTVData[] = {
+ {6, 1, 840, 563, 1632, 960, 0, 0, 0}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 01 (320x350,640x350) */
+ {3, 1, 840, 483, 1632, 960, 0, 0, 0}, /* 02 (360x400,720x400) */
+ {3, 1, 960, 563, 1632, 960, 0, 0, 0}, /* 03 (720x350) */
+ {5, 1, 840, 563, 1648, 960, 0x166, 1, 0}, /* 04 (320x240,640x480) */
+ {16, 5, 1050, 683, 1648, 960, 0x143, 1, 0}, /* 05 (400x300,800x600) */
+ {25, 12, 1260, 851, 1648, 960, 0x032, 0, 0}, /* 06 (512x384,1024x768)*/
+ {5, 4, 1575, 1124, 1648, 960, 0x128, 0, 0}, /* 07 (1280x1024) */
+ {4, 1, 1050, 563, 1548, 960, 0x143, 1, 0}, /* 08 (800x480) */
+ {5, 2, 1400, 659, 1648, 960, 0x032, 0, 0}, /* 09 (1024x576) */
+ {8, 5, 1750, 803, 1648, 960, 0x128, 0, 0} /* 0A (1280x720) */
+};
+
+static const struct SiS_TVData XGI_ExtYPbPr525iData[] = {
+ { 9, 5, 1001, 453, 1270, 420, 171, 0, 171},
+ { 12, 5, 858, 403, 1270, 420, 171, 0, 171},
+ { 9, 5, 1001, 453, 1270, 420, 171, 0, 171},
+ { 12, 5, 858, 403, 1270, 420, 171, 0, 171},
+ {143, 80, 836, 523, 1250, 420, 224, 0, 0},
+ {143, 120, 1008, 643, 1250, 420, 0, 1, 0},
+ { 1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/
+ { 2, 1, 858, 503, 1584, 480, 0, 1, 0},
+ { 3, 2, 1001, 533, 1250, 420, 0, 0, 0}
+};
+
+static const struct SiS_TVData XGI_StYPbPr525iData[] = {
+ {1, 1, 858, 525, 1270, 400, 50, 0, 760},
+ {1, 1, 858, 525, 1270, 350, 50, 0, 640},
+ {1, 1, 858, 525, 1270, 400, 0, 0, 720},
+ {1, 1, 858, 525, 1270, 350, 0, 0, 720},
+ {1, 1, 858, 525, 1270, 480, 0, 0, 760},
+};
+
+static const struct SiS_TVData XGI_ExtYPbPr525pData[] = {
+ { 9, 5, 1001, 453, 1270, 420, 171, 0, 171},
+ { 12, 5, 858, 403, 1270, 420, 171, 0, 171},
+ { 9, 5, 1001, 453, 1270, 420, 171, 0, 171},
+ { 12, 5, 858, 403, 1270, 420, 171, 0, 171},
+ {143, 80, 836, 523, 1270, 420, 224, 0, 0},
+ {143, 120, 1008, 643, 1270, 420, 0, 1, 0},
+ { 1, 1, 1120, 821, 1516, 420, 0, 1, 0}, /*301b*/
+ { 2, 1, 858, 503, 1584, 480, 0, 1, 0},
+ { 3, 2, 1001, 533, 1270, 420, 0, 0, 0}
+};
+
+static const struct SiS_TVData XGI_StYPbPr525pData[] = {
+ {1, 1, 1716, 525, 1270, 400, 50, 0, 760},
+ {1, 1, 1716, 525, 1270, 350, 50, 0, 640},
+ {1, 1, 1716, 525, 1270, 400, 0, 0, 720},
+ {1, 1, 1716, 525, 1270, 350, 0, 0, 720},
+ {1, 1, 1716, 525, 1270, 480, 0, 0, 760},
+};
+
+static const struct SiS_TVData XGI_ExtYPbPr750pData[] = {
+ { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 01 (320x350,640x350) */
+ { 3, 1, 935, 470, 1130, 680, 50, 0, 0}, /* 02 (360x400,720x400) */
+ {24, 7, 935, 420, 1130, 680, 50, 0, 0}, /* 03 (720x350) */
+ { 2, 1, 1100, 590, 1130, 640, 50, 0, 0}, /* 04 (320x240,640x480) */
+ { 3, 2, 1210, 690, 1130, 660, 50, 0, 0}, /* 05 (400x300,800x600) */
+ { 1, 1, 1375, 878, 1130, 640, 638, 0, 0}, /* 06 (1024x768) */
+ { 2, 1, 858, 503, 1130, 480, 0, 1, 0}, /* 07 (720x480) */
+ { 5, 4, 1815, 570, 1130, 660, 50, 0, 0},
+ { 5, 3, 1100, 686, 1130, 640, 50, 1, 0},
+ {10, 9, 1320, 830, 1130, 640, 50, 0, 0}
+};
+
+static const struct SiS_TVData XGI_StYPbPr750pData[] = {
+ {1, 1, 1650, 750, 1280, 400, 50, 0, 760},
+ {1, 1, 1650, 750, 1280, 350, 50, 0, 640},
+ {1, 1, 1650, 750, 1280, 400, 0, 0, 720},
+ {1, 1, 1650, 750, 1280, 350, 0, 0, 720},
+ {1, 1, 1650, 750, 1280, 480, 0, 0, 760},
+};
+
+static const unsigned char XGI330_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,
+ 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 unsigned char XGI330_PALTiming[] = {
+ 0x21, 0x5A, 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
+};
+
+static const unsigned char XGI330_HiTVExtTiming[] = {
+ 0x2D, 0x60, 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 unsigned char XGI330_HiTVSt1Timing[] = {
+ 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 unsigned char XGI330_HiTVSt2Timing[] = {
+ 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 unsigned char XGI330_HiTVTextTiming[] = {
+ 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 unsigned char XGI330_YPbPr750pTiming[] = {
+ 0x30, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c,
+ 0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a,
+ 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+ 0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x60, 0x13,
+ 0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0,
+ 0x4b, 0x4b, 0x6f, 0x2f, 0x63,
+ 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+ 0x60, 0x14, 0x73, 0x00, 0x40,
+ 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
+};
+
+static const unsigned char XGI330_YPbPr525pTiming[] = {
+ 0x3E, 0x11, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
+ 0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
+ 0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+ 0x0c, 0x50, 0xb2, 0x9f, 0x16, 0x59, 0x4f, 0x13,
+ 0xad, 0x11, 0xad, 0x1d, 0x40, 0x8a, 0x3d, 0xb8,
+ 0x51, 0x5e, 0x60, 0x49, 0x7d,
+ 0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+ 0x60, 0x14, 0x4B, 0x43, 0x41,
+ 0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00
+};
+
+static const unsigned char XGI330_YPbPr525iTiming[] = {
+ 0x1B, 0x21, 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, 0x4B, 0x00, 0x40,
+ 0x44, 0x00, 0xDB, 0x02, 0x3B, 0x00
+};
+
+static const unsigned char XGI330_HiTVGroup3Data[] = {
+ 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 unsigned char XGI330_HiTVGroup3Simu[] = {
+ 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 unsigned char XGI330_HiTVGroup3Text[] = {
+ 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
+};
+
+static const unsigned char XGI330_Ren525pGroup3[] = {
+ 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
+ 0xB1, 0x41, 0x62, 0x62, 0xFF, 0xF4, 0x45, 0xa6,
+ 0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20,
+ 0xAC, 0xDA, 0x60, 0xFe, 0x6A, 0x9A, 0x06, 0x10,
+ 0xd1, 0x04, 0x18, 0x0a, 0xFF, 0x80, 0x00, 0x80,
+ 0x3c, 0x77, 0x00, 0xEF, 0xE0, 0x10, 0xB0, 0xE0,
+ 0x10, 0x4F, 0x0F, 0x0F, 0x05, 0x0F, 0x08, 0x6E,
+ 0x1a, 0x1F, 0x25, 0x2a, 0x4C, 0xAA, 0x01
+};
+
+static const unsigned char XGI330_Ren750pGroup3[] = {
+ 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
+ 0x54, 0x41, 0xE7, 0xE7, 0xFF, 0xF4, 0x45, 0xa6,
+ 0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20,
+ 0xAC, 0x6A, 0x60, 0x2b, 0x52, 0xCD, 0x61, 0x10,
+ 0x51, 0x04, 0x18, 0x0a, 0x1F, 0x80, 0x00, 0x80,
+ 0xFF, 0xA4, 0x04, 0x2B, 0x94, 0x21, 0x72, 0x94,
+ 0x26, 0x05, 0x01, 0x0F, 0xed, 0x0F, 0x0A, 0x64,
+ 0x18, 0x1D, 0x23, 0x28, 0x4C, 0xAA, 0x01
+};
+
+static const struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = {
+ { 960, 438, 1344, 806}, /* 00 (320x200,320x400,640x200,640x400) */
+ { 960, 388, 1344, 806}, /* 01 (320x350,640x350) */
+ {1040, 438, 1344, 806}, /* 02 (360x400,720x400) */
+ {1040, 388, 1344, 806}, /* 03 (720x350) */
+ { 960, 518, 1344, 806}, /* 04 (320x240,640x480) */
+ {1120, 638, 1344, 806}, /* 05 (400x300,800x600) */
+ {1344, 806, 1344, 806} /* 06 (512x384,1024x768) */
+};
+
+
+static const struct SiS_LVDSData XGI_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 struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = {
+ {1048, 442, 1688, 1066},
+ {1048, 392, 1688, 1066},
+ {1048, 442, 1688, 1066},
+ {1048, 392, 1688, 1066},
+ {1048, 522, 1688, 1066},
+ {1208, 642, 1688, 1066},
+ {1432, 810, 1688, 1066},
+ {1688, 1066, 1688, 1066}
+};
+
+#define XGI_LVDS1280x1024Data_2 XGI_LVDS1024x768Data_2
+
+static const struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = {
+ {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 struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = {
+ {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}
+};
+
+/* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */
+static const struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = {
+ {1088, 520, 2048, 1320}, /* 00 (320x200,320x400,640x200,640x400) */
+ {1088, 470, 2048, 1320}, /* 01 (320x350,640x350) */
+ {1088, 520, 2048, 1320}, /* 02 (360x400,720x400) */
+ {1088, 470, 2048, 1320}, /* 03 (720x350) */
+ {1088, 600, 2048, 1320}, /* 04 (320x240,640x480) */
+ {1248, 720, 2048, 1320}, /* 05 (400x300,800x600) */
+ {1472, 888, 2048, 1320}, /* 06 (512x384,1024x768) */
+ {1728, 1144, 2048, 1320}, /* 07 (640x512,1280x1024) */
+ {1848, 1170, 2048, 1320}, /* 08 (1400x1050) */
+ {2048, 1320, 2048, 1320} /* 09 (1600x1200) */
+};
+
+static const struct SiS_LVDSData XGI_LVDSNoScalingData[] = {
+ { 800, 449, 800, 449}, /* 00 (320x200,320x400,640x200,640x400) */
+ { 800, 449, 800, 449}, /* 01 (320x350,640x350) */
+ { 800, 449, 800, 449}, /* 02 (360x400,720x400) */
+ { 800, 449, 800, 449}, /* 03 (720x350) */
+ { 800, 525, 800, 525}, /* 04 (640x480x60Hz) */
+ {1056, 628, 1056, 628}, /* 05 (800x600x60Hz) */
+ {1344, 806, 1344, 806}, /* 06 (1024x768x60Hz) */
+ {1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */
+ {1688, 1066, 1688, 1066}, /* 08 (1400x1050x60Hz) */
+ {2160, 1250, 2160, 1250}, /* 09 (1600x1200x60Hz) */
+ {1688, 806, 1688, 806} /* 0A (1280x768x60Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = {
+ { 960, 438, 1312, 800}, /* 00 (320x200,320x400,640x200,640x400) */
+ { 960, 388, 1312, 800}, /* 01 (320x350,640x350) */
+ {1040, 438, 1312, 800}, /* 02 (360x400,720x400) */
+ {1040, 388, 1312, 800}, /* 03 (720x350) */
+ { 928, 512, 1312, 800}, /* 04 (320x240,640x480) */
+ {1088, 632, 1312, 800}, /* 05 (400x300,800x600) */
+ {1312, 800, 1312, 800}, /* 06 (512x384,1024x768) */
+};
+
+
+static const struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = {
+ {1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */
+ {1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */
+ {1312, 800, 1312, 800}, /* ; 03 (720x350) */
+ {1312, 800, 1312, 800}, /* ; 04 (320x240,640x480) */
+ {1312, 800, 1312, 800}, /* ; 05 (400x300,800x600) */
+ {1312, 800, 1312, 800}, /* ; 06 (512x384,1024x768) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = {
+ {1048, 442, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {1048, 392, 1688, 1066 }, /* ; 01 (320x350,640x350) */
+ {1128, 442, 1688, 1066 }, /* ; 02 (360x400,720x400) */
+ {1128, 392, 1688, 1066 }, /* ; 03 (720x350) */
+ {1048, 522, 1688, 1066 }, /* ; 04 (320x240,640x480) */
+ {1208, 642, 1688, 1066 }, /* ; 05 (400x300,800x600) */
+ {1432, 810, 1688, 1066 }, /* ; 06 (512x384,1024x768) */
+ {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = {
+ {1688, 1066, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {1688, 1066, 1688, 1066 }, /* ; 01 (320x350,640x350) */
+ {1688, 1066, 1688, 1066 }, /* ; 02 (360x400,720x400) */
+ {1688, 1066, 1688, 1066 }, /* ; 03 (720x350) */
+ {1688, 1066, 1688, 1066 }, /* ; 04 (320x240,640x480) */
+ {1688, 1066, 1688, 1066 }, /* ; 05 (400x300,800x600) */
+ {1688, 1066, 1688, 1066 }, /* ; 06 (512x384,1024x768) */
+ {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */
+};
+
+static const struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = {
+ { 800, 449, 800, 449}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ { 800, 449, 800, 449}, /* ; 01 (320x350,640x350) */
+ { 900, 449, 900, 449}, /* ; 02 (360x400,720x400) */
+ { 900, 449, 900, 449}, /* ; 03 (720x350) */
+ { 800, 500, 800, 500}, /* ; 04 (640x480x75Hz) */
+ {1056, 625, 1056, 625}, /* ; 05 (800x600x75Hz) */
+ {1312, 800, 1312, 800}, /* ; 06 (1024x768x75Hz) */
+ {1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */
+ {1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz)
+ ;;[ycchen] 12/19/02 */
+ {2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */
+ {1688, 806, 1688, 806}, /* ; 0A (1280x768x75Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = {
+ {0, 1048, 0, 771}, /* 00 (320x200,320x400,640x200,640x400) */
+ {0, 1048, 0, 771}, /* 01 (320x350,640x350) */
+ {0, 1048, 0, 771}, /* 02 (360x400,720x400) */
+ {0, 1048, 0, 771}, /* 03 (720x350) */
+ {0, 1048, 0, 771}, /* 04 (640x480x60Hz) */
+ {0, 1048, 0, 771}, /* 05 (800x600x60Hz) */
+ {0, 1048, 805, 770} /* 06 (1024x768x60Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = {
+ {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
+ {1142, 856, 597, 562}, /* 01 (320x350,640x350) */
+ {1142, 856, 622, 587}, /* 02 (360x400,720x400) */
+ {1142, 856, 597, 562}, /* 03 (720x350) */
+ {1142, 1048, 722, 687}, /* 04 (640x480x60Hz) */
+ {1232, 936, 722, 687}, /* 05 (800x600x60Hz) */
+ { 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = {
+ {320, 24, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
+ {320, 24, 597, 562}, /* 01 (320x350,640x350) */
+ {320, 24, 622, 587}, /* 02 (360x400,720x400) */
+ {320, 24, 597, 562}, /* 03 (720x350) */
+ {320, 24, 722, 687} /* 04 (640x480x60Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = {
+ {0, 1328, 0, 1025}, /* 00 (320x200,320x400,640x200,640x400) */
+ {0, 1328, 0, 1025}, /* 01 (320x350,640x350) */
+ {0, 1328, 0, 1025}, /* 02 (360x400,720x400) */
+ {0, 1328, 0, 1025}, /* 03 (720x350) */
+ {0, 1328, 0, 1025}, /* 04 (640x480x60Hz) */
+ {0, 1328, 0, 1025}, /* 05 (800x600x60Hz) */
+ {0, 1328, 0, 1025}, /* 06 (1024x768x60Hz) */
+ {0, 1328, 1065, 1024} /* 07 (1280x1024x60Hz) */
+};
+
+ /* The Display setting for DE Mode Panel */
+static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = {
+ {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */
+ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */
+ {1408, 1048, 752, 711}, /* 02 (360x400,720x400) */
+ {1408, 1048, 729, 688}, /* 03 (720x350) */
+ {1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */
+ {1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */
+ {1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */
+ {0000, 1328, 0, 1025} /* 07 (1280x1024x60Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = {
+ {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
+ {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */
+ {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */
+ {0, 1448, 0, 1051}, /* 03 (720x350) */
+ {0, 1448, 0, 1051}, /* 04 (640x480x60Hz) */
+ {0, 1448, 0, 1051}, /* 05 (800x600x60Hz) */
+ {0, 1448, 0, 1051}, /* 06 (1024x768x60Hz) */
+ {0, 1448, 0, 1051}, /* 07 (1280x1024x60Hz) */
+ {0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = {
+ {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */
+ {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */
+ {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */
+ {1308, 1068, 781, 766}, /* 03 (720x350) */
+ {1308, 1068, 781, 766}, /* 04 (640x480x60Hz) */
+ {1388, 1148, 841, 826}, /* 05 (800x600x60Hz) */
+ {1490, 1250, 925, 910}, /* 06 (1024x768x60Hz) */
+ {1608, 1368, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+ { 0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = {
+ {0, 1664, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
+ {0, 1664, 0, 1201}, /* 01 (320x350,640x350) */
+ {0, 1664, 0, 1201}, /* 02 (360x400,720x400) */
+ {0, 1664, 0, 1201}, /* 03 (720x350) */
+ {0, 1664, 0, 1201}, /* 04 (640x480x60Hz) */
+ {0, 1664, 0, 1201}, /* 05 (800x600x60Hz) */
+ {0, 1664, 0, 1201}, /* 06 (1024x768x60Hz) */
+ {0, 1664, 0, 1201}, /* 07 (1280x1024x60Hz) */
+ {0, 1664, 0, 1201}, /* 08 (1400x1050x60Hz) */
+ {0, 1664, 0, 1201} /* 09 (1600x1200x60Hz) */
+};
+
+static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = {
+ {0, 648, 448, 405, 96, 2}, /* 00 (320x200,320x400,
+ 640x200,640x400) */
+ {0, 648, 448, 355, 96, 2}, /* 01 (320x350,640x350) */
+ {0, 648, 448, 405, 96, 2}, /* 02 (360x400,720x400) */
+ {0, 648, 448, 355, 96, 2}, /* 03 (720x350) */
+ {0, 648, 1, 483, 96, 2}, /* 04 (640x480x60Hz) */
+ {0, 840, 627, 600, 128, 4}, /* 05 (800x600x60Hz) */
+ {0, 1048, 805, 770, 136, 6}, /* 06 (1024x768x60Hz) */
+ {0, 1328, 0, 1025, 112, 3}, /* 07 (1280x1024x60Hz) */
+ {0, 1438, 0, 1051, 112, 3}, /* 08 (1400x1050x60Hz)*/
+ {0, 1664, 0, 1201, 192, 3}, /* 09 (1600x1200x60Hz) */
+ {0, 1328, 0, 0771, 112, 6} /* 0A (1280x768x60Hz) */
+};
+
+/* ; 1024x768 Full-screen */
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = {
+ {0, 1040, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {0, 1040, 0, 769}, /* ; 01 (320x350,640x350) */
+ {0, 1040, 0, 769}, /* ; 02 (360x400,720x400) */
+ {0, 1040, 0, 769}, /* ; 03 (720x350) */
+ {0, 1040, 0, 769}, /* ; 04 (640x480x75Hz) */
+ {0, 1040, 0, 769}, /* ; 05 (800x600x75Hz) */
+ {0, 1040, 0, 769} /* ; 06 (1024x768x75Hz) */
+};
+
+/* ; 1024x768 center-screen (Enh. Mode) */
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = {
+ {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
+ {1142, 856, 597, 562}, /* 01 (320x350,640x350) */
+ {1142, 856, 622, 587}, /* 02 (360x400,720x400) */
+ {1142, 856, 597, 562}, /* 03 (720x350) */
+ {1142, 1048, 722, 687}, /* 04 (640x480x60Hz) */
+ {1232, 936, 722, 687}, /* 05 (800x600x60Hz) */
+ { 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */
+};
+
+/* ; 1024x768 center-screen (St.Mode) */
+static const struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = {
+ {320, 24, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {320, 24, 597, 562}, /* ; 01 (320x350,640x350) */
+ {320, 24, 622, 587}, /* ; 02 (360x400,720x400) */
+ {320, 24, 597, 562}, /* ; 03 (720x350) */
+ {320, 24, 722, 687} /* ; 04 (640x480x60Hz) */
+};
+
+static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = {
+ {0, 1296, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {0, 1296, 0, 1025}, /* ; 01 (320x350,640x350) */
+ {0, 1296, 0, 1025}, /* ; 02 (360x400,720x400) */
+ {0, 1296, 0, 1025}, /* ; 03 (720x350) */
+ {0, 1296, 0, 1025}, /* ; 04 (640x480x75Hz) */
+ {0, 1296, 0, 1025}, /* ; 05 (800x600x75Hz) */
+ {0, 1296, 0, 1025}, /* ; 06 (1024x768x75Hz) */
+ {0, 1296, 0, 1025} /* ; 07 (1280x1024x75Hz) */
+};
+
+/* The Display setting for DE Mode Panel */
+/* Set DE as default */
+static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = {
+ {1368, 976, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */
+ {1368, 976, 729, 688}, /* ; 01 (320x350,640x350) */
+ {1408, 976, 752, 711}, /* ; 02 (360x400,720x400) */
+ {1408, 976, 729, 688}, /* ; 03 (720x350) */
+ {1368, 976, 794, 753}, /* ; 04 (640x480x75Hz) */
+ {1448, 1036, 854, 813}, /* ; 05 (800x600x75Hz) */
+ {1560, 1168, 938, 897}, /* ; 06 (1024x768x75Hz) */
+ { 0, 1296, 0, 1025} /* ; 07 (1280x1024x75Hz) */
+};
+
+/* Scaling LCD 75Hz */
+static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = {
+ {0, 648, 448, 405, 96, 2}, /* ; 00 (320x200,320x400,
+ 640x200,640x400) */
+ {0, 648, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */
+ {0, 729, 448, 405, 108, 2}, /* ; 02 (360x400,720x400) */
+ {0, 729, 448, 355, 108, 2}, /* ; 03 (720x350) */
+ {0, 656, 0, 481, 64, 3}, /* ; 04 (640x480x75Hz) */
+ {0, 816, 0, 601, 80, 3}, /* ; 05 (800x600x75Hz) */
+ {0, 1040, 0, 769, 96, 3}, /* ; 06 (1024x768x75Hz) */
+ {0, 1296, 0, 1025, 144, 3}, /* ; 07 (1280x1024x75Hz) */
+ {0, 1448, 0, 1051, 112, 3}, /* ; 08 (1400x1050x75Hz) */
+ {0, 1664, 0, 1201, 192, 3}, /* ; 09 (1600x1200x75Hz) */
+ {0, 1328, 0, 771, 112, 6} /* ; 0A (1280x768x75Hz) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = {
+ { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} }, /* 00 (320x) */
+ { {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} }, /* 01 (360x) */
+ { {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} }, /* 02 (400x) */
+ { {0x63, 0x3F, 0x87, 0x4A, 0x93, 0x00, 0x01, 0x00} }, /* 03 (512x) */
+ { {0x73, 0x4F, 0x97, 0x55, 0x86, 0x00, 0x05, 0x00} }, /* 04 (640x) */
+ { {0x73, 0x4F, 0x97, 0x55, 0x86, 0x00, 0x05, 0x00} }, /* 05 (720x) */
+ { {0x87, 0x63, 0x8B, 0x69, 0x1A, 0x00, 0x26, 0x00} }, /* 06 (800x) */
+ { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* 07 (1024x) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = {
+ { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 00 (320x) */
+ { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 01 (360x) */
+ { {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00 } }, /* 02 (400x) */
+ { {0x6E, 0x3F, 0x92, 0x48, 0x96, 0x00, 0x01, 0x00 } }, /* 03 (512x) */
+ { {0x7E, 0x4F, 0x82, 0x58, 0x06, 0x00, 0x06, 0x00 } }, /* 04 (640x) */
+ { {0x7E, 0x4F, 0x82, 0x58, 0x06, 0x00, 0x06, 0x00 } }, /* 05 (720x) */
+ { {0x92, 0x63, 0x96, 0x6C, 0x1A, 0x00, 0x06, 0x00 } }, /* 06 (800x) */
+ { {0xAE, 0x7F, 0x92, 0x88, 0x96, 0x00, 0x02, 0x00 } }, /* 07 (1024x) */
+ { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00 } } /* 08 (1280x) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = {
+ { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 00 (320x) */
+ { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 01 (360x) */
+ { {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} }, /* 02 (400x) */
+ { {0x63, 0x3F, 0x87, 0x45, 0x96, 0x00, 0x01, 0x00} }, /* 03 (512x) */
+ { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} }, /* 04 (640x) */
+ { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} }, /* 05 (720x) */
+ { {0xA3, 0x63, 0x87, 0x78, 0x89, 0x00, 0x02, 0x00} }, /* 06 (800x) */
+ { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* 07 (1024x) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = {
+ { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 00 (320x) */
+ { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 01 (360x) */
+ { {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} }, /* 02 (400x) */
+ { {0x7E, 0x47, 0x93, 0x50, 0x9E, 0x00, 0x01, 0x00} }, /* 03 (512x) */
+ { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} }, /* 04 (640x) */
+ { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} }, /* 05 (720x) */
+ { {0xCE, 0x81, 0x94, 0x8A, 0x98, 0x00, 0x02, 0x00} }, /* 06 (800x) */
+ { {0xCE, 0x8F, 0x82, 0x98, 0x06, 0x00, 0x07, 0x00} }, /* 07 (1024x) */
+ { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00} } /* 08 (1280x) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = {
+ { {0x47, 0x27, 0x8B, 0x2C, 0x1A, 0x00, 0x05, 0x00} }, /* 00 (320x) */
+ { {0x47, 0x27, 0x8B, 0x30, 0x1E, 0x00, 0x05, 0x00} }, /* 01 (360x) */
+ { {0x51, 0x31, 0x95, 0x36, 0x04, 0x00, 0x01, 0x00} }, /* 02 (400x) */
+ { {0x5F, 0x3F, 0x83, 0x44, 0x92, 0x00, 0x01, 0x00} }, /* 03 (512x) */
+ { {0x6F, 0x4F, 0x93, 0x54, 0x82, 0x00, 0x05, 0x00} }, /* 04 (640x) */
+ { {0x6F, 0x4F, 0x93, 0x54, 0x82, 0x00, 0x05, 0x00} }, /* 05 (720x) */
+ { {0x83, 0x63, 0x87, 0x68, 0x16, 0x00, 0x06, 0x00} }, /* 06 (800x) */
+ { {0x9F, 0x7F, 0x83, 0x84, 0x92, 0x00, 0x02, 0x00} }, /* 07 (1024x) */
+ { {0xBF, 0x9F, 0x83, 0xA4, 0x12, 0x00, 0x07, 0x00} }, /* 08 (1280x) */
+ { {0xCE, 0xAE, 0x92, 0xB3, 0x01, 0x00, 0x03, 0x00} } /* 09 (1400x) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = {
+ { {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 00 (320x) */
+ { {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 01 (360x) */
+ { {0x76, 0x31, 0x9A, 0x48, 0x9F, 0x00, 0x41, 0x00} }, /* 02 (400x) */
+ { {0x76, 0x3F, 0x9A, 0x4F, 0x96, 0x00, 0x41, 0x00} }, /* 03 (512x) */
+ { {0xCE, 0x7E, 0x82, 0x87, 0x9E, 0x00, 0x02, 0x00} }, /* 04 (640x) */
+ { {0xCE, 0x7E, 0x82, 0x87, 0x9E, 0x00, 0x02, 0x00} }, /* 05 (720x) */
+ { {0xCE, 0x63, 0x92, 0x96, 0x04, 0x00, 0x07, 0x00} }, /* 06 (800x) */
+ { {0xCE, 0x7F, 0x92, 0xA4, 0x12, 0x00, 0x07, 0x00} }, /* 07 (1024x) */
+ { {0xCE, 0x9F, 0x92, 0xB4, 0x02, 0x00, 0x03, 0x00} }, /* 08 (1280x) */
+ { {0xCE, 0xAE, 0x92, 0xBC, 0x0A, 0x00, 0x03, 0x00} } /* 09 (1400x) */
+};
+
+/* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */
+/* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = {
+ { {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 00 (320x) */
+ { {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 01 (360x) */
+ { {0x65, 0x31, 0x89, 0x3C, 0x94, 0x00, 0x01, 0x00} }, /* 02 (400x) */
+ { {0x73, 0x3F, 0x97, 0x4A, 0x82, 0x00, 0x05, 0x00} }, /* 03 (512x) */
+ { {0x83, 0x4F, 0x87, 0x51, 0x09, 0x00, 0x06, 0x00} }, /* 04 (640x) */
+ { {0x83, 0x4F, 0x87, 0x51, 0x09, 0x00, 0x06, 0x00} }, /* 05 (720x) */
+ { {0x97, 0x63, 0x9B, 0x65, 0x1D, 0x00, 0x06, 0xF0} }, /* 06 (800x) */
+ { {0xB3, 0x7F, 0x97, 0x81, 0x99, 0x00, 0x02, 0x00} }, /* 07 (1024x) */
+ { {0xD3, 0x9F, 0x97, 0xA1, 0x19, 0x00, 0x07, 0x00} }, /* 08 (1280x) */
+ { {0xE2, 0xAE, 0x86, 0xB9, 0x91, 0x00, 0x03, 0x00} }, /* 09 (1400x) */
+ { {0xFB, 0xC7, 0x9F, 0xC9, 0x81, 0x00, 0x07, 0x00} } /* 0A (1600x) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = {
+ { {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} }, /* 00 (x350) */
+ { {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} }, /* 01 (x400) */
+ { {0x04, 0x3E, 0xE2, 0x89, 0xDF, 0x05, 0x00} }, /* 02 (x480) */
+ { {0x7C, 0xF0, 0x5A, 0x8F, 0x57, 0x7D, 0xA0} }, /* 03 (x600) */
+ { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* 04 (x768) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = {
+ { {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} }, /* 00 (x350) */
+ { {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} }, /* 01 (x400) */
+ { {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} }, /* 02 (x480) */
+ { {0x24, 0xF1, 0xAE, 0x84, 0x57, 0x25, 0xB0} }, /* 03 (x600) */
+ { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* 04 (x768) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = {
+ { {0x86, 0x1F, 0x5E, 0x82, 0x5D, 0x87, 0x00} }, /* 00 (x350) */
+ { {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} }, /* 01 (x400) */
+ { {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} }, /* 02 (x480) */
+ { {0x80, 0xF0, 0x58, 0x8C, 0x57, 0x81, 0xA0} }, /* 03 (x600) */
+ { {0x28, 0xF5, 0x00, 0x84, 0xFF, 0x29, 0x90} }, /* 04 (x768) */
+ { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* 05 (x1024) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = {
+ { {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} }, /* 00 (x350) */
+ { {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} }, /* 01 (x400) */
+ { {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} }, /* 02 (x480) */
+ { {0x28, 0xDE, 0x2C, 0x8F, 0x2B, 0x56, 0x91} }, /* 03 (x600) */
+ { {0x28, 0xDE, 0x80, 0x83, 0x7F, 0xAA, 0x91} }, /* 04 (x768) */
+ { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* 05 (x1024) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = {
+ { {0x6C, 0x1F, 0x60, 0x84, 0x5D, 0x6D, 0x10} }, /* 00 (x350) */
+ { {0x9E, 0x1F, 0x93, 0x86, 0x8F, 0x9F, 0x30} }, /* 01 (x400) */
+ { {0xEE, 0x1F, 0xE2, 0x86, 0xDF, 0xEF, 0x10} }, /* 02 (x480) */
+ { {0x66, 0xF0, 0x5A, 0x8e, 0x57, 0x67, 0xA0} }, /* 03 (x600) */
+ { {0x0E, 0xF5, 0x02, 0x86, 0xFF, 0x0F, 0x90} }, /* 04 (x768) */
+ { {0x0E, 0x5A, 0x02, 0x86, 0xFF, 0x0F, 0x89} }, /* 05 (x1024) */
+ { {0x28, 0x10, 0x1A, 0x80, 0x19, 0x29, 0x0F} } /* 06 (x1050) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = {
+ { {0x28, 0x92, 0xB6, 0x83, 0xB5, 0xCF, 0x81} }, /* 00 (x350) */
+ { {0x28, 0x92, 0xD5, 0x82, 0xD4, 0xEE, 0x81} }, /* 01 (x400) */
+ { {0x28, 0x92, 0xFD, 0x8A, 0xFC, 0x16, 0xB1} }, /* 02 (x480) */
+ { {0x28, 0xD4, 0x39, 0x86, 0x57, 0x29, 0x81} }, /* 03 (x600) */
+ { {0x28, 0xD4, 0x8D, 0x9A, 0xFF, 0x29, 0xA1} }, /* 04 (x768) */
+ { {0x28, 0x5A, 0x0D, 0x9A, 0xFF, 0x29, 0xA9} }, /* 05 (x1024) */
+ { {0x28, 0x10, 0x1A, 0x87, 0x19, 0x29, 0x8F} } /* 06 (x1050) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = {
+ { {0xd4, 0x1F, 0x81, 0x84, 0x5D, 0xd5, 0x10} }, /* 00 (x350) */
+ { {0x06, 0x3e, 0xb3, 0x86, 0x8F, 0x07, 0x20} }, /* 01 (x400) */
+ { {0x56, 0xba, 0x03, 0x86, 0xDF, 0x57, 0x00} }, /* 02 (x480) */
+ { {0xce, 0xF0, 0x7b, 0x8e, 0x57, 0xcf, 0xa0} }, /* 03 (x600) */
+ { {0x76, 0xF5, 0x23, 0x86, 0xFF, 0x77, 0x90} }, /* 04 (x768) */
+ { {0x76, 0x5A, 0x23, 0x86, 0xFF, 0x77, 0x89} }, /* 05 (x1024) */
+ { {0x90, 0x10, 0x1A, 0x8E, 0x19, 0x91, 0x2F} }, /* 06 (x1050) */
+ { {0x26, 0x11, 0xd3, 0x86, 0xaF, 0x27, 0x3f} } /* 07 (x1200) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = {
+ { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} },/* ; 00 (320x) */
+ { {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} },/* ; 01 (360x) */
+ { {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} },/* ; 02 (400x) */
+ { {0x63, 0x3F, 0x87, 0x4A, 0x93, 0x00, 0x01, 0x00} },/* ; 03 (512x) */
+ { {0x6F, 0x4F, 0x93, 0x54, 0x80, 0x00, 0x05, 0x00} },/* ; 04 (640x) */
+ { {0x6F, 0x4F, 0x93, 0x54, 0x80, 0x00, 0x05, 0x00} },/* ; 05 (720x) */
+ { {0x83, 0x63, 0x87, 0x68, 0x14, 0x00, 0x26, 0x00} },/* ; 06 (800x) */
+ { {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00} } /* ; 07 (1024x) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = {
+ { {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} },/* ; 00 (x350) */
+ { {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} },/* ; 01 (x400) */
+ { {0xFE, 0x1F, 0xE0, 0x84, 0xDF, 0xFF, 0x10} },/* ; 02 (x480) */
+ { {0x76, 0xF0, 0x58, 0x8C, 0x57, 0x77, 0xA0} },/* ; 03 (x600) */
+ { {0x1E, 0xF5, 0x00, 0x83, 0xFF, 0x1F, 0x90} } /* ; 04 (x768) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = {
+ { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 00 (320x) */
+ { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 01 (360x) */
+ { {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
+ { {0x63, 0x3F, 0x87, 0x45, 0x96, 0x00, 0x01, 0x00} },/* ; 03 (512x) */
+ { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} },/* ; 04 (640x) */
+ { {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} },/* ; 05 (720x) */
+ { {0xA3, 0x63, 0x87, 0x78, 0x89, 0x00, 0x02, 0x00} },/* ; 06 (800x) */
+ { {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* ; 07 (1024x) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = {
+ { {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} },/* ; 00 (x350) */
+ { {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} },/* ; 01 (x400) */
+ { {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} },/* ; 02 (x480) */
+ { {0x24, 0xF1, 0xAE, 0x84, 0x57, 0x25, 0xB0} },/* ; 03 (x600) */
+ { {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* ; 04 (x768) */
+};
+
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = {
+ { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 00 (320x) */
+ { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 01 (360x) */
+ { {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
+ { {0x6E, 0x3F, 0x92, 0x48, 0x96, 0x00, 0x01, 0x00} },/* ; 03 (512x) */
+ { {0x7E, 0x4F, 0x82, 0x54, 0x06, 0x00, 0x06, 0x00} },/* ; 04 (640x) */
+ { {0x7E, 0x4F, 0x82, 0x54, 0x06, 0x00, 0x06, 0x00} },/* ; 05 (720x) */
+ { {0x92, 0x63, 0x96, 0x68, 0x1A, 0x00, 0x06, 0x00} },/* ; 06 (800x) */
+ { {0xAE, 0x7F, 0x92, 0x84, 0x96, 0x00, 0x02, 0x00} },/* ; 07 (1024x) */
+ { {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00} } /* ; 08 (1280x) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = {
+ { {0x86, 0xD1, 0xBC, 0x80, 0xBB, 0xE5, 0x00} },/* ; 00 (x350) */
+ { {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} },/* ; 01 (x400) */
+ { {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} },/* ; 02 (x480) */
+ { {0x80, 0xF0, 0x58, 0x8C, 0x57, 0x81, 0xA0} },/* ; 03 (x600) */
+ { {0x28, 0xF5, 0x00, 0x84, 0xFF, 0x29, 0x90} },/* ; 04 (x768) */
+ { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */
+};
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = {
+ { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 00 (320x) */
+ { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 01 (360x) */
+ { {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
+ { {0x7E, 0x47, 0x93, 0x50, 0x9E, 0x00, 0x01, 0x00} },/* ; 03 (512x) */
+ { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} },/* ; 04 (640x) */
+ { {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} },/* ; 05 (720x) */
+ { {0xCE, 0x81, 0x94, 0x8A, 0x98, 0x00, 0x02, 0x00} },/* ; 06 (800x) */
+ { {0xCE, 0x8F, 0x82, 0x98, 0x06, 0x00, 0x07, 0x00} },/* ; 07 (1024x) */
+ { {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00} } /* ; 08 (1280x) */
+};
+
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = {
+ { {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} },/* ; 00 (x350) */
+ { {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} },/* ; 01 (x400) */
+ { {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} },/* ; 02 (x480) */
+ { {0x28, 0xDE, 0x2C, 0x8F, 0x2B, 0x56, 0x91} },/* ; 03 (x600) */
+ { {0x28, 0xDE, 0x80, 0x83, 0x7F, 0xAA, 0x91} },/* ; 04 (x768) */
+ { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */
+};
+
+/*add for new UNIVGABIOS*/
+static const struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = {
+ {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCD1024x768Data },
+ {Panel_1024x768, 0x0019, 0x0000, XGI_StLCD1024x768Data },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCD1024x768Data },
+ {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCD1280x1024Data },
+ {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCD1280x1024Data },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCD1280x1024Data },
+ {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcd_1400x1050 },
+ {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcd_1400x1050 },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_CetLCD1400x1050Data },
+ {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCD1600x1200Data },
+ {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCD1600x1200Data },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingData },
+ {Panel_1024x768x75, 0x0019, 0x0001, XGI_ExtLCD1024x768x75Data },
+ {Panel_1024x768x75, 0x0019, 0x0000, XGI_ExtLCD1024x768x75Data },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCD1024x768x75Data },
+ {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcd_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcd_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCD1280x1024x75Data },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL } /* End of table */
+};
+
+static const struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = {
+ {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data },
+ {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data },
+ {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDes1280x1024Data },
+ {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDes1280x1024Data },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDes1280x1024Data },
+ {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddes_1400x1050 },
+ {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddes_1400x1050 },
+ {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data },
+ {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 },
+ {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDes1600x1200Data },
+ {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDes1600x1200Data },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData },
+ {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 },
+ {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data },
+ {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddes_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddes_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDes1280x1024x75Data },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = {
+ {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data },
+ {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data },
+ {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDLDes1280x1024Data },
+ {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDLDes1280x1024Data },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024Data },
+ {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddldes_1400x1050 },
+ {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddldes_1400x1050 },
+ {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data },
+ {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 },
+ {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDLDes1600x1200Data },
+ {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDLDes1600x1200Data },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData },
+ {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 },
+ {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data },
+ {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddldes_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddldes_1280x1024x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024x75Data },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = {
+ {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_H },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_H },
+ {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_H },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_H },
+ {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_H },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_H },
+ {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_H },
+ {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Hx75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Hx75 },
+ {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Hx75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Hx75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = {
+ {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_V },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_V },
+ {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_V },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_V },
+ {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_V },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_V },
+ {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_V },
+ {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Vx75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Vx75 },
+ {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Vx75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Vx75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = {
+ {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Data_1 },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Data_2 },
+ {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1 },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2 },
+ {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Data_1 },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Data_2 },
+ {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Data_1 },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingData },
+ {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Data_1x75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Data_2x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2x75 },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = {
+ {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Des_1 },
+ {Panel_1024x768, 0x0618, 0x0410, XGI_LVDS1024x768Des_3 },
+ {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Des_2 },
+ {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1 },
+ {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2 },
+ {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Des_1 },
+ {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Des_2 },
+ {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Des_1 },
+ {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesData },
+ {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Des_1x75 },
+ {Panel_1024x768x75, 0x0618, 0x0410, XGI_LVDS1024x768Des_3x75 },
+ {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Des_2x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1x75 },
+ {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2x75 },
+ {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesDatax75 },
+ {0xFF, 0x0000, 0x0000, NULL }
+};
+
+static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = {
+ {0x09E1, 0x0001, XGI_ExtPALData},
+ {0x09E1, 0x0000, XGI_ExtNTSCData},
+ {0x09E1, 0x0801, XGI_StPALData},
+ {0x09E1, 0x0800, XGI_StNTSCData},
+ {0x49E0, 0x0100, XGI_ExtHiTVData},
+ {0x49E0, 0x4100, XGI_St2HiTVData},
+ {0x49E0, 0x4900, XGI_St1HiTVData},
+ {0x09E0, 0x0020, XGI_ExtYPbPr525iData},
+ {0x09E0, 0x0040, XGI_ExtYPbPr525pData},
+ {0x09E0, 0x0080, XGI_ExtYPbPr750pData},
+ {0x09E0, 0x0820, XGI_StYPbPr525iData},
+ {0x09E0, 0x0840, XGI_StYPbPr525pData},
+ {0x09E0, 0x0880, XGI_StYPbPr750pData},
+ {0xffff, 0x0000, XGI_ExtNTSCData},
+};
+
+/* Dual link only */
+static const struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = {
+/* LCDCap1024x768 */
+ {Panel_1024x768, DefaultLCDCap, 0x88, 0x06, VCLK65_315,
+ 0x6C, 0xC3, 0x35, 0x62,
+ 0x0A, 0xC0, 0x28, 0x10},
+/* LCDCap1280x1024 */
+ {Panel_1280x1024, XGI_LCDDualLink+DefaultLCDCap,
+ 0x70, 0x03, VCLK108_2_315,
+ 0x70, 0x44, 0xF8, 0x2F,
+ 0x0A, 0xC0, 0x30, 0x10},
+/* LCDCap1400x1050 */
+ {Panel_1400x1050, XGI_LCDDualLink+DefaultLCDCap,
+ 0x70, 0x03, VCLK108_2_315,
+ 0x70, 0x44, 0xF8, 0x2F,
+ 0x0A, 0xC0, 0x30, 0x10},
+/* LCDCap1600x1200 */
+ {Panel_1600x1200, XGI_LCDDualLink+DefaultLCDCap,
+ 0xC0, 0x03, VCLK162,
+ 0x43, 0x22, 0x70, 0x24,
+ 0x0A, 0xC0, 0x30, 0x10},
+/* LCDCap1024x768x75 */
+ {Panel_1024x768x75, DefaultLCDCap, 0x60, 0, VCLK78_75,
+ 0x2B, 0x61, 0x2B, 0x61,
+ 0x0A, 0xC0, 0x28, 0x10},
+/* LCDCap1280x1024x75 */
+ {Panel_1280x1024x75, XGI_LCDDualLink+DefaultLCDCap,
+ 0x90, 0x03, VCLK135_5,
+ 0x54, 0x42, 0x4A, 0x61,
+ 0x0A, 0xC0, 0x30, 0x10},
+/* LCDCapDefault */
+ {0xFF, DefaultLCDCap, 0x88, 0x06, VCLK65_315,
+ 0x6C, 0xC3, 0x35, 0x62,
+ 0x0A, 0xC0, 0x28, 0x10}
+};
+
+static const struct XGI330_LCDCapStruct XGI_LCDCapList[] = {
+/* LCDCap1024x768 */
+ {Panel_1024x768, DefaultLCDCap, 0x88, 0x06, VCLK65_315,
+ 0x6C, 0xC3, 0x35, 0x62,
+ 0x0A, 0xC0, 0x28, 0x10},
+/* LCDCap1280x1024 */
+ {Panel_1280x1024, DefaultLCDCap,
+ 0x70, 0x03, VCLK108_2_315,
+ 0x70, 0x44, 0xF8, 0x2F,
+ 0x0A, 0xC0, 0x30, 0x10},
+/* LCDCap1400x1050 */
+ {Panel_1400x1050, DefaultLCDCap,
+ 0x70, 0x03, VCLK108_2_315,
+ 0x70, 0x44, 0xF8, 0x2F,
+ 0x0A, 0xC0, 0x30, 0x10},
+/* LCDCap1600x1200 */
+ {Panel_1600x1200, DefaultLCDCap,
+ 0xC0, 0x03, VCLK162,
+ 0x5A, 0x23, 0x5A, 0x23,
+ 0x0A, 0xC0, 0x30, 0x10},
+/* LCDCap1024x768x75 */
+ {Panel_1024x768x75, DefaultLCDCap, 0x60, 0, VCLK78_75,
+ 0x2B, 0x61, 0x2B, 0x61,
+ 0x0A, 0xC0, 0x28, 0x10},
+/* LCDCap1280x1024x75 */
+ {Panel_1280x1024x75, DefaultLCDCap,
+ 0x90, 0x03, VCLK135_5,
+ 0x54, 0x42, 0x4A, 0x61,
+ 0x0A, 0xC0, 0x30, 0x10},
+/* LCDCapDefault */
+ {0xFF, DefaultLCDCap, 0x88, 0x06, VCLK65_315,
+ 0x6C, 0xC3, 0x35, 0x62,
+ 0x0A, 0xC0, 0x28, 0x10}
+};
+
+const struct XGI_Ext2Struct XGI330_RefIndex[] = {
+ {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
+ 0x00, 0x10, 0x59, 320, 200},/* 00 */
+ {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
+ 0x00, 0x10, 0x00, 320, 400},/* 01 */
+ {Mode32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175,
+ 0x04, 0x20, 0x50, 320, 240},/* 02 */
+ {Mode32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40,
+ 0x05, 0x32, 0x51, 400, 300},/* 03 */
+ {Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384,
+ VCLK65_315, 0x06, 0x43, 0x52, 512, 384},/* 04 */
+ {Mode32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175,
+ 0x00, 0x14, 0x2f, 640, 400},/* 05 */
+ {Mode32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175,
+ 0x04, 0x24, 0x2e, 640, 480},/* 06 640x480x60Hz (LCD 640x480x60z) */
+ {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5,
+ 0x04, 0x24, 0x2e, 640, 480},/* 07 640x480x72Hz (LCD 640x480x70Hz) */
+ {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5,
+ 0x47, 0x24, 0x2e, 640, 480},/* 08 640x480x75Hz (LCD 640x480x75Hz) */
+ {Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36,
+ 0x8A, 0x24, 0x2e, 640, 480},/* 09 640x480x85Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163,
+ 0x00, 0x24, 0x2e, 640, 480},/* 0a 640x480x100Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406,
+ 0x00, 0x24, 0x2e, 640, 480},/* 0b 640x480x120Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852,
+ 0x00, 0x24, 0x2e, 640, 480},/* 0c 640x480x160Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6,
+ 0x00, 0x24, 0x2e, 640, 480},/* 0d 640x480x200Hz */
+ {Mode32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36,
+ 0x05, 0x36, 0x6a, 800, 600},/* 0e 800x600x56Hz */
+ {Mode32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40,
+ 0x05, 0x36, 0x6a, 800, 600},/* 0f 800x600x60Hz (LCD 800x600x60Hz) */
+ {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50,
+ 0x48, 0x36, 0x6a, 800, 600},/* 10 800x600x72Hz (LCD 800x600x70Hz) */
+ {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5,
+ 0x8B, 0x36, 0x6a, 800, 600},/* 11 800x600x75Hz (LCD 800x600x75Hz) */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25,
+ 0x00, 0x36, 0x6a, 800, 600},/* 12 800x600x85Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179,
+ 0x00, 0x36, 0x6a, 800, 600},/* 13 800x600x100Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95,
+ 0x00, 0x36, 0x6a, 800, 600},/* 14 800x600x120Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406,
+ 0x00, 0x36, 0x6a, 800, 600},/* 15 800x600x160Hz */
+ {Mode32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9,
+ 0x00, 0x47, 0x37, 1024, 768},/* 16 1024x768x43Hz */
+ /* 17 1024x768x60Hz (LCD 1024x768x60Hz) */
+ {Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60,
+ VCLK65_315, 0x06, 0x47, 0x37, 1024, 768},
+ {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75,
+ 0x49, 0x47, 0x37, 1024, 768},/* 18 1024x768x70Hz (LCD 1024x768x70Hz) */
+ {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75,
+ 0x00, 0x47, 0x37, 1024, 768},/* 19 1024x768x75Hz (LCD 1024x768x75Hz) */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5,
+ 0x8C, 0x47, 0x37, 1024, 768},/* 1a 1024x768x85Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309,
+ 0x00, 0x47, 0x37, 1024, 768},/* 1b 1024x768x100Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054,
+ 0x00, 0x47, 0x37, 1024, 768},/* 1c 1024x768x120Hz */
+ {Mode32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2_315,
+ 0x08, 0x58, 0x7b, 1280, 960},/* 1d 1280x960x60Hz */
+ {Mode32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75,
+ 0x00, 0x58, 0x3a, 1280, 1024},/* 1e 1280x1024x43Hz */
+ {Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2_315,
+ 0x07, 0x58, 0x3a, 1280, 1024},/*1f 1280x1024x60Hz (LCD 1280x1024x60Hz)*/
+ {Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5,
+ 0x00, 0x58, 0x3a, 1280, 1024},/*20 1280x1024x75Hz (LCD 1280x1024x75Hz)*/
+ {Mode32Bpp + SyncPP, RES1280x1024x85, VCLK157_5,
+ 0x00, 0x58, 0x3a, 1280, 1024},/* 21 1280x1024x85Hz */
+ /* 22 1600x1200x60Hz */
+ {Mode32Bpp + SupportLCD + SyncPP + SupportCRT2in301C,
+ RES1600x1200x60, VCLK162, 0x09, 0x7A, 0x3c, 1600, 1200},
+ {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175,
+ 0x00, 0x69, 0x3c, 1600, 1200},/* 23 1600x1200x65Hz */
+ {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189,
+ 0x00, 0x69, 0x3c, 1600, 1200},/* 24 1600x1200x70Hz */
+ {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5,
+ 0x00, 0x69, 0x3c, 1600, 1200},/* 25 1600x1200x75Hz */
+ {Mode32Bpp + SyncPP, RES1600x1200x85, VCLK229_5,
+ 0x00, 0x69, 0x3c, 1600, 1200},/* 26 1600x1200x85Hz */
+ {Mode32Bpp + SyncPP, RES1600x1200x100, VCLK269_655,
+ 0x00, 0x69, 0x3c, 1600, 1200},/* 27 1600x1200x100Hz */
+ {Mode32Bpp + SyncPP, RES1600x1200x120, VCLK323_586,
+ 0x00, 0x69, 0x3c, 1600, 1200},/* 28 1600x1200x120Hz */
+ {Mode32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234,
+ 0x00, 0x00, 0x68, 1920, 1440},/* 29 1920x1440x60Hz */
+ {Mode32Bpp + SyncPN, RES1920x1440x65, VCLK254_817,
+ 0x00, 0x00, 0x68, 1920, 1440},/* 2a 1920x1440x65Hz */
+ {Mode32Bpp + SyncPN, RES1920x1440x70, VCLK277_015,
+ 0x00, 0x00, 0x68, 1920, 1440},/* 2b 1920x1440x70Hz */
+ {Mode32Bpp + SyncPN, RES1920x1440x75, VCLK291_132,
+ 0x00, 0x00, 0x68, 1920, 1440},/* 2c 1920x1440x75Hz */
+ {Mode32Bpp + SyncPN, RES1920x1440x85, VCLK330_615,
+ 0x00, 0x00, 0x68, 1920, 1440},/* 2d 1920x1440x85Hz */
+ {Mode16Bpp + SyncPN, RES1920x1440x100, VCLK388_631,
+ 0x00, 0x00, 0x68, 1920, 1440},/* 2e 1920x1440x100Hz */
+ {Mode32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952,
+ 0x00, 0x00, 0x6c, 2048, 1536},/* 2f 2048x1536x60Hz */
+ {Mode32Bpp + SyncPN, RES2048x1536x65, VCLK291_766,
+ 0x00, 0x00, 0x6c, 2048, 1536},/* 30 2048x1536x65Hz */
+ {Mode32Bpp + SyncPN, RES2048x1536x70, VCLK315_195,
+ 0x00, 0x00, 0x6c, 2048, 1536},/* 31 2048x1536x70Hz */
+ {Mode32Bpp + SyncPN, RES2048x1536x75, VCLK340_477,
+ 0x00, 0x00, 0x6c, 2048, 1536},/* 32 2048x1536x75Hz */
+ {Mode16Bpp + SyncPN, RES2048x1536x85, VCLK375_847,
+ 0x00, 0x00, 0x6c, 2048, 1536},/* 33 2048x1536x85Hz */
+ {Mode32Bpp + SupportHiVision + SupportRAMDAC2 +
+ SyncPP + SupportYPbPr750p, RES800x480x60, VCLK39_77,
+ 0x08, 0x00, 0x70, 800, 480},/* 34 800x480x60Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5,
+ 0x08, 0x00, 0x70, 800, 480},/* 35 800x480x75Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25,
+ 0x08, 0x00, 0x70, 800, 480},/* 36 800x480x85Hz */
+ {Mode32Bpp + SupportHiVision + SupportRAMDAC2 +
+ SyncPP + SupportYPbPr750p, RES1024x576x60, VCLK65_315,
+ 0x09, 0x00, 0x71, 1024, 576},/* 37 1024x576x60Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75,
+ 0x09, 0x00, 0x71, 1024, 576},/* 38 1024x576x75Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5,
+ 0x09, 0x00, 0x71, 1024, 576},/* 39 1024x576x85Hz */
+ {Mode32Bpp + SupportHiVision + SupportRAMDAC2 +
+ SyncPP + SupportYPbPr750p, RES1280x720x60, VCLK108_2_315,
+ 0x0A, 0x00, 0x75, 1280, 720},/* 3a 1280x720x60Hz*/
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5,
+ 0x0A, 0x00, 0x75, 1280, 720},/* 3b 1280x720x75Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5,
+ 0x0A, 0x00, 0x75, 1280, 720},/* 3c 1280x720x85Hz */
+ {Mode32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322,
+ 0x06, 0x00, 0x31, 720, 480},/* 3d 720x480x60Hz */
+ {Mode32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36,
+ 0x06, 0x00, 0x32, 720, 576},/* 3e 720x576x56Hz */
+ {Mode32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I,
+ VCLK35_2, 0x00, 0x00, 0x00, 856, 480},/* 3f 856x480x79I */
+ {Mode32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2,
+ 0x00, 0x00, 0x00, 856, 480},/* 40 856x480x60Hz */
+ {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60,
+ VCLK79_411, 0x08, 0x48, 0x23, 1280, 768},/* 41 1280x768x60Hz */
+ {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60,
+ VCLK122_61, 0x08, 0x69, 0x26, 1400, 1050},/* 42 1400x1050x60Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350,
+ 0x37, 0x00, 0x20, 1152, 864},/* 43 1152x864x60Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385,
+ 0x37, 0x00, 0x20, 1152, 864},/* 44 1152x864x75Hz */
+ {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75,
+ VCLK125_999, 0x3A, 0x88, 0x7b, 1280, 960},/* 45 1280x960x75Hz */
+ {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85,
+ VCLK148_5, 0x0A, 0x88, 0x7b, 1280, 960},/* 46 1280x960x85Hz */
+ {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120,
+ VCLK217_325, 0x3A, 0x88, 0x7b, 1280, 960},/* 47 1280x960x120Hz */
+ {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054,
+ 0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */
+};
+
+static const unsigned char XGI330_ScreenOffset[] = {
+ 0x14, 0x19, 0x20, 0x28, 0x32, 0x40,
+ 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35,
+ 0x57, 0x48
+};
+
+static const struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = {
+ { 320, 200, 8, 8},
+ { 320, 240, 8, 8},
+ { 320, 400, 8, 8},
+ { 400, 300, 8, 8},
+ { 512, 384, 8, 8},
+ { 640, 400, 8, 16},
+ { 640, 480, 8, 16},
+ { 800, 600, 8, 16},
+ {1024, 768, 8, 16},
+ {1280, 1024, 8, 16},
+ {1600, 1200, 8, 16},
+ {1920, 1440, 8, 16},
+ {2048, 1536, 8, 16},
+ { 720, 480, 8, 16},
+ { 720, 576, 8, 16},
+ {1280, 960, 8, 16},
+ { 800, 480, 8, 16},
+ {1024, 576, 8, 16},
+ {1280, 720, 8, 16},
+ { 856, 480, 8, 16},
+ {1280, 768, 8, 16},
+ {1400, 1050, 8, 16},
+ {1152, 864, 8, 16}
+};
+
+const struct SiS_VCLKData XGI_VCLKData[] = {
+ /* SR2B,SR2C,SR2D */
+ {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */
+ {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */
+ {0x57, 0xE4, 31}, /* 02 (31.500MHz) */
+ {0xC3, 0xC8, 36}, /* 03 (36.000MHz) */
+ {0x42, 0xE2, 40}, /* 04 (40.000MHz) */
+ {0xFE, 0xCD, 43}, /* 05 (43.163MHz) */
+ {0x5D, 0xC4, 44}, /* 06 (44.900MHz) */
+ {0x52, 0xE2, 49}, /* 07 (49.500MHz) */
+ {0x53, 0xE2, 50}, /* 08 (50.000MHz) */
+ {0x74, 0x67, 52}, /* 09 (52.406MHz) */
+ {0x6D, 0x66, 56}, /* 0A (56.250MHz) */
+ {0x6C, 0xC3, 65}, /* 0B (65.000MHz) */
+ {0x46, 0x44, 67}, /* 0C (67.765MHz) */
+ {0xB1, 0x46, 68}, /* 0D (68.179MHz) */
+ {0xD3, 0x4A, 72}, /* 0E (72.852MHz) */
+ {0x29, 0x61, 75}, /* 0F (75.000MHz) */
+ {0x6E, 0x46, 76}, /* 10 (75.800MHz) */
+ {0x2B, 0x61, 78}, /* 11 (78.750MHz) */
+ {0x31, 0x42, 79}, /* 12 (79.411MHz) */
+ {0xAB, 0x44, 83}, /* 13 (83.950MHz) */
+ {0x46, 0x25, 84}, /* 14 (84.800MHz) */
+ {0x78, 0x29, 86}, /* 15 (86.600MHz) */
+ {0x62, 0x44, 94}, /* 16 (94.500MHz) */
+ {0x2B, 0x41, 104}, /* 17 (104.998MHz) */
+ {0x3A, 0x23, 105}, /* 18 (105.882MHz) */
+ {0x70, 0x44, 108}, /* 19 (107.862MHz) */
+ {0x3C, 0x23, 109}, /* 1A (109.175MHz) */
+ {0x5E, 0x43, 113}, /* 1B (113.309MHz) */
+ {0xBC, 0x44, 116}, /* 1C (116.406MHz) */
+ {0xE0, 0x46, 132}, /* 1D (132.258MHz) */
+ {0x54, 0x42, 135}, /* 1E (135.500MHz) */
+ {0x9C, 0x22, 139}, /* 1F (139.275MHz) */
+ {0x41, 0x22, 157}, /* 20 (157.500MHz) */
+ {0x70, 0x24, 162}, /* 21 (161.793MHz) */
+ {0x30, 0x21, 175}, /* 22 (175.000MHz) */
+ {0x4E, 0x22, 189}, /* 23 (188.520MHz) */
+ {0xDE, 0x26, 194}, /* 24 (194.400MHz) */
+ {0x62, 0x06, 202}, /* 25 (202.500MHz) */
+ {0x3F, 0x03, 229}, /* 26 (229.500MHz) */
+ {0xB8, 0x06, 234}, /* 27 (233.178MHz) */
+ {0x34, 0x02, 253}, /* 28 (252.699MHz) */
+ {0x58, 0x04, 255}, /* 29 (254.817MHz) */
+ {0x24, 0x01, 265}, /* 2A (265.728MHz) */
+ {0x9B, 0x02, 267}, /* 2B (266.952MHz) */
+ {0x70, 0x05, 270}, /* 2C (269.65567MHz) */
+ {0x25, 0x01, 272}, /* 2D (272.04199MHz) */
+ {0x9C, 0x02, 277}, /* 2E (277.015MHz) */
+ {0x27, 0x01, 286}, /* 2F (286.359985MHz) */
+ {0xB3, 0x04, 291}, /* 30 (291.13266MHz) */
+ {0xBC, 0x05, 292}, /* 31 (291.766MHz) */
+ {0xF6, 0x0A, 310}, /* 32 (309.789459MHz) */
+ {0x95, 0x01, 315}, /* 33 (315.195MHz) */
+ {0xF0, 0x09, 324}, /* 34 (323.586792MHz) */
+ {0xFE, 0x0A, 331}, /* 35 (330.615631MHz) */
+ {0xF3, 0x09, 332}, /* 36 (332.177612MHz) */
+ {0x5E, 0x03, 340}, /* 37 (340.477MHz) */
+ {0xE8, 0x07, 376}, /* 38 (375.847504MHz) */
+ {0xDE, 0x06, 389}, /* 39 (388.631439MHz) */
+ {0x52, 0x2A, 54}, /* 3A (54.000MHz) */
+ {0x52, 0x6A, 27}, /* 3B (27.000MHz) */
+ {0x62, 0x24, 70}, /* 3C (70.874991MHz) */
+ {0x62, 0x64, 70}, /* 3D (70.1048912MHz) */
+ {0xA8, 0x4C, 30}, /* 3E (30.1048912MHz) */
+ {0x20, 0x26, 33}, /* 3F (33.7499957MHz) */
+ {0x31, 0xc2, 39}, /* 40 (39.77MHz) */
+ {0x11, 0x21, 30}, /* 41 (30MHz) }// NTSC 1024X768 */
+ {0x2E, 0x48, 25}, /* 42 (25.175MHz) }// ScaleLCD */
+ {0x24, 0x46, 25}, /* 43 (25.175MHz) */
+ {0x26, 0x64, 28}, /* 44 (28.322MHz) */
+ {0x37, 0x64, 40}, /* 45 (40.000MHz) */
+ {0xA1, 0x42, 108}, /* 46 (95.000MHz) }// QVGA */
+ {0x37, 0x61, 100}, /* 47 (100.00MHz) */
+ {0x78, 0x27, 108}, /* 48 (108.200MHz) */
+ {0xBF, 0xC8, 35}, /* 49 (35.2MHz) */
+ {0x66, 0x43, 123}, /* 4A (122.61Mhz) */
+ {0x2C, 0x61, 80}, /* 4B (80.350Mhz) */
+ {0x3B, 0x61, 108}, /* 4C (107.385Mhz) */
+ {0x69, 0x61, 191}, /* 4D (190.96MHz ) */
+ {0x4F, 0x22, 192}, /* 4E (192.069MHz) */
+ {0x28, 0x26, 322}, /* 4F (322.273MHz) */
+ {0x5C, 0x6B, 27}, /* 50 (27.74HMz) */
+ {0x57, 0x24, 126}, /* 51 (125.999MHz) */
+ {0x5C, 0x42, 148}, /* 52 (148.5MHz) */
+ {0x42, 0x61, 120}, /* 53 (120.839MHz) */
+ {0x62, 0x61, 178}, /* 54 (178.992MHz) */
+ {0x59, 0x22, 217}, /* 55 (217.325MHz) */
+ {0x29, 0x01, 300}, /* 56 (299.505Mhz) */
+ {0x52, 0x63, 74}, /* 57 (74.25MHz) */
+ {0xFF, 0x00, 0} /* End mark */
+};
+
+static const struct SiS_VBVCLKData XGI_VBVCLKData[] = {
+ {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */
+ {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */
+ {0x57, 0xE4, 31}, /* 02 (31.500MHz) */
+ {0xC3, 0xC8, 36}, /* 03 (36.000MHz) */
+ {0x42, 0x47, 40}, /* 04 (40.000MHz) */
+ {0xFE, 0xCD, 43}, /* 05 (43.163MHz) */
+ {0x5D, 0xC4, 44}, /* 06 (44.900MHz) */
+ {0x52, 0x47, 49}, /* 07 (49.500MHz) */
+ {0x53, 0x47, 50}, /* 08 (50.000MHz) */
+ {0x74, 0x67, 52}, /* 09 (52.406MHz) */
+ {0x6D, 0x66, 56}, /* 0A (56.250MHz) */
+ {0x35, 0x62, 65}, /* 0B (65.000MHz) */
+ {0x46, 0x44, 67}, /* 0C (67.765MHz) */
+ {0xB1, 0x46, 68}, /* 0D (68.179MHz) */
+ {0xD3, 0x4A, 72}, /* 0E (72.852MHz) */
+ {0x29, 0x61, 75}, /* 0F (75.000MHz) */
+ {0x6D, 0x46, 75}, /* 10 (75.800MHz) */
+ {0x41, 0x43, 78}, /* 11 (78.750MHz) */
+ {0x31, 0x42, 79}, /* 12 (79.411MHz) */
+ {0xAB, 0x44, 83}, /* 13 (83.950MHz) */
+ {0x46, 0x25, 84}, /* 14 (84.800MHz) */
+ {0x78, 0x29, 86}, /* 15 (86.600MHz) */
+ {0x62, 0x44, 94}, /* 16 (94.500MHz) */
+ {0x2B, 0x22, 104}, /* 17 (104.998MHz) */
+ {0x49, 0x24, 105}, /* 18 (105.882MHz) */
+ {0xF8, 0x2F, 108}, /* 19 (108.279MHz) */
+ {0x3C, 0x23, 109}, /* 1A (109.175MHz) */
+ {0x5E, 0x43, 113}, /* 1B (113.309MHz) */
+ {0xBC, 0x44, 116}, /* 1C (116.406MHz) */
+ {0xE0, 0x46, 132}, /* 1D (132.258MHz) */
+ {0xD4, 0x28, 135}, /* 1E (135.220MHz) */
+ {0xEA, 0x2A, 139}, /* 1F (139.275MHz) */
+ {0x41, 0x22, 157}, /* 20 (157.500MHz) */
+ {0x70, 0x24, 162}, /* 21 (161.793MHz) */
+ {0x30, 0x21, 175}, /* 22 (175.000MHz) */
+ {0x4E, 0x22, 189}, /* 23 (188.520MHz) */
+ {0xDE, 0x26, 194}, /* 24 (194.400MHz) */
+ {0x70, 0x07, 202}, /* 25 (202.500MHz) */
+ {0x3F, 0x03, 229}, /* 26 (229.500MHz) */
+ {0xB8, 0x06, 234}, /* 27 (233.178MHz) */
+ {0x34, 0x02, 253}, /* 28 (252.699997 MHz) */
+ {0x58, 0x04, 255}, /* 29 (254.817MHz) */
+ {0x24, 0x01, 265}, /* 2A (265.728MHz) */
+ {0x9B, 0x02, 267}, /* 2B (266.952MHz) */
+ {0x70, 0x05, 270}, /* 2C (269.65567 MHz) */
+ {0x25, 0x01, 272}, /* 2D (272.041992 MHz) */
+ {0x9C, 0x02, 277}, /* 2E (277.015MHz) */
+ {0x27, 0x01, 286}, /* 2F (286.359985 MHz) */
+ {0x3C, 0x02, 291}, /* 30 (291.132660 MHz) */
+ {0xEF, 0x0A, 292}, /* 31 (291.766MHz) */
+ {0xF6, 0x0A, 310}, /* 32 (309.789459 MHz) */
+ {0x95, 0x01, 315}, /* 33 (315.195MHz) */
+ {0xF0, 0x09, 324}, /* 34 (323.586792 MHz) */
+ {0xFE, 0x0A, 331}, /* 35 (330.615631 MHz) */
+ {0xF3, 0x09, 332}, /* 36 (332.177612 MHz) */
+ {0xEA, 0x08, 340}, /* 37 (340.477MHz) */
+ {0xE8, 0x07, 376}, /* 38 (375.847504 MHz) */
+ {0xDE, 0x06, 389}, /* 39 (388.631439 MHz) */
+ {0x52, 0x2A, 54}, /* 3A (54.000MHz) */
+ {0x52, 0x6A, 27}, /* 3B (27.000MHz) */
+ {0x62, 0x24, 70}, /* 3C (70.874991MHz) */
+ {0x62, 0x64, 70}, /* 3D (70.1048912MHz) */
+ {0xA8, 0x4C, 30}, /* 3E (30.1048912MHz) */
+ {0x20, 0x26, 33}, /* 3F (33.7499957MHz) */
+ {0x31, 0xc2, 39}, /* 40 (39.77MHz) */
+ {0x11, 0x21, 30}, /* 41 (30MHz) }// NTSC 1024X768 */
+ {0x2E, 0x48, 25}, /* 42 (25.175MHz) }// ScaleLCD */
+ {0x24, 0x46, 25}, /* 43 (25.175MHz) */
+ {0x26, 0x64, 28}, /* 44 (28.322MHz) */
+ {0x37, 0x64, 40}, /* 45 (40.000MHz) */
+ {0xA1, 0x42, 108}, /* 46 (95.000MHz) }// QVGA */
+ {0x37, 0x61, 100}, /* 47 (100.00MHz) */
+ {0x78, 0x27, 108}, /* 48 (108.200MHz) */
+ {0xBF, 0xC8, 35 }, /* 49 (35.2MHz) */
+ {0x66, 0x43, 123}, /* 4A (122.61Mhz) */
+ {0x2C, 0x61, 80 }, /* 4B (80.350Mhz) */
+ {0x3B, 0x61, 108}, /* 4C (107.385Mhz) */
+ {0x69, 0x61, 191}, /* 4D (190.96MHz ) */
+ {0x4F, 0x22, 192}, /* 4E (192.069MHz) */
+ {0x28, 0x26, 322}, /* 4F (322.273MHz) */
+ {0x5C, 0x6B, 27}, /* 50 (27.74HMz) */
+ {0x57, 0x24, 126}, /* 51 (125.999MHz) */
+ {0x5C, 0x42, 148}, /* 52 (148.5MHz) */
+ {0x42, 0x61, 120}, /* 53 (120.839MHz) */
+ {0x62, 0x61, 178}, /* 54 (178.992MHz) */
+ {0x59, 0x22, 217}, /* 55 (217.325MHz) */
+ {0x29, 0x01, 300}, /* 56 (299.505Mhz) */
+ {0x52, 0x63, 74}, /* 57 (74.25MHz) */
+ {0xFF, 0x00, 0} /* End mark */
+};
+
+#define XGI301TVDelay 0x22
+#define XGI301LCDDelay 0x12
+
+static const unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */
+ 0x04, /* ; 0 Adaptive */
+ 0x00, /* ; 1 new anti-flicker ? */
+
+ 0x04, /* ; 0 Adaptive */
+ 0x08, /* ; 1 new anti-flicker ? */
+
+ 0x04, /* ; 0 ? */
+ 0x00 /* ; 1 new anti-flicker ? */
+};
+
+
+static const unsigned char TVEdgeList[] = {
+ 0x00, /* ; 0 NTSC No Edge enhance */
+ 0x04, /* ; 1 NTSC Adaptive Edge enhance */
+ 0x00, /* ; 0 PAL No Edge enhance */
+ 0x04, /* ; 1 PAL Adaptive Edge enhance */
+ 0x00, /* ; 0 HiTV */
+ 0x00 /* ; 1 HiTV */
+};
+
+static const unsigned long TVPhaseList[] = {
+ 0x08BAED21, /* ; 0 NTSC phase */
+ 0x00E3052A, /* ; 1 PAL phase */
+ 0x9B2EE421, /* ; 2 PAL-M phase */
+ 0xBA3EF421, /* ; 3 PAL-N phase */
+ 0xA7A28B1E, /* ; 4 NTSC 1024x768 */
+ 0xE00A831E, /* ; 5 PAL-M 1024x768 */
+ 0x00000000, /* ; 6 reserved */
+ 0x00000000, /* ; 7 reserved */
+ 0xD67BF021, /* ; 8 NTSC phase */
+ 0xE986092A, /* ; 9 PAL phase */
+ 0xA4EFE621, /* ; A PAL-M phase */
+ 0x4694F621, /* ; B PAL-N phase */
+ 0x8BDE711C, /* ; C NTSC 1024x768 */
+ 0xE00A831E /* ; D PAL-M 1024x768 */
+};
+
+static const unsigned char NTSCYFilter1[] = {
+ 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
+ 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
+ 0xEB, 0x04, 0x25, 0x18, /* 2 : 640x text mode */
+ 0xF1, 0x04, 0x1F, 0x18, /* 3 : 720x text mode */
+ 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */
+ 0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */
+ 0xEB, 0x15, 0x25, 0xF6 /* 6 : 800x gra. mode */
+};
+
+static const unsigned char PALYFilter1[] = {
+ 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
+ 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
+ 0xF1, 0xF7, 0x1F, 0x32, /* 2 : 640x text mode */
+ 0xF3, 0x00, 0x1D, 0x20, /* 3 : 720x text mode */
+ 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */
+ 0xF1, 0xF7, 0x1F, 0x32, /* 5 : 640x gra. mode */
+ 0xFC, 0xFB, 0x14, 0x2A /* 6 : 800x gra. mode */
+};
+
+static const unsigned char xgifb_palmn_yfilter1[] = {
+ 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
+ 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
+ 0xEB, 0x04, 0x10, 0x18, /* 2 : 640x text mode */
+ 0xF7, 0x06, 0x19, 0x14, /* 3 : 720x text mode */
+ 0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */
+ 0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */
+ 0xEB, 0x15, 0x25, 0xF6, /* 6 : 800x gra. mode */
+ 0xFF, 0xFF, 0xFF, 0xFF /* End of Table */
+};
+
+static const unsigned char xgifb_yfilter2[] = {
+ 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */
+ 0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */
+ 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */
+ 0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 3 : 720x text mode */
+ 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 4 : 320x gra. mode */
+ 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 5 : 640x gra. mode */
+ 0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38, /* 6 : 800x gra. mode */
+ 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28 /* 7 : 1024xgra. mode */
+};
+
+static const unsigned char XGI_NTSC1024AdjTime[] = {
+ 0xa7, 0x07, 0xf2, 0x6e, 0x17, 0x8b, 0x73, 0x53,
+ 0x13, 0x40, 0x34, 0xF4, 0x63, 0xBB, 0xCC, 0x7A,
+ 0x58, 0xe4, 0x73, 0xd0, 0x13
+};
+
+static const struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = {
+ {0, {
+ 0x00, 0x20, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x7F, /* ; C0-C7 */
+ 0x7D, 0x20, 0x04, 0x7F, 0x7D, 0x1F, 0x06, 0x7E, /* ; C8-CF */
+ 0x7C, 0x1D, 0x09, 0x7E, 0x7C, 0x1B, 0x0B, 0x7E, /* ; D0-D7 */
+ 0x7C, 0x19, 0x0E, 0x7D, 0x7C, 0x17, 0x11, 0x7C, /* ; D8-DF */
+ 0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x11, 0x17, 0x7C, /* ; E0-E7 */
+ 0x7D, 0x0E, 0x19, 0x7C, 0x7E, 0x0B, 0x1B, 0x7C, /* ; EA-EF */
+ 0x7E, 0x09, 0x1D, 0x7C, 0x7F, 0x06, 0x1F, 0x7C, /* ; F0-F7 */
+ 0x7F, 0x04, 0x20, 0x7D, 0x00, 0x02, 0x20, 0x7E /* ; F8-FF */
+ }
+ }
+};
+
+static const struct XGI301C_Tap4TimingStruct PALTap4Timing[] = {
+ {600, {
+ 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */
+ 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */
+ 0x00, 0x18, 0x0C, 0x7C, 0x7F, 0x17, 0x0E, 0x7C, /* ; D0-D7 */
+ 0x7E, 0x16, 0x0F, 0x7D, 0x7E, 0x14, 0x11, 0x7D, /* ; D8-DF */
+ 0x7D, 0x13, 0x13, 0x7D, 0x7D, 0x11, 0x14, 0x7E, /* ; E0-E7 */
+ 0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */
+ 0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */
+ 0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04 /* ; F8-FF */
+ }
+ },
+ {768, {
+ 0x08, 0x12, 0x08, 0x7E, 0x07, 0x12, 0x09, 0x7E, /* ; C0-C7 */
+ 0x06, 0x12, 0x0A, 0x7E, 0x05, 0x11, 0x0B, 0x7F, /* ; C8-CF */
+ 0x04, 0x11, 0x0C, 0x7F, 0x03, 0x11, 0x0C, 0x00, /* ; D0-D7 */
+ 0x03, 0x10, 0x0D, 0x00, 0x02, 0x0F, 0x0E, 0x01, /* ; D8-DF */
+ 0x01, 0x0F, 0x0F, 0x01, 0x01, 0x0E, 0x0F, 0x02, /* ; E0-E7 */
+ 0x00, 0x0D, 0x10, 0x03, 0x7F, 0x0C, 0x11, 0x04, /* ; EA-EF */
+ 0x7F, 0x0C, 0x11, 0x04, 0x7F, 0x0B, 0x11, 0x05, /* ; F0-F7 */
+ 0x7E, 0x0A, 0x12, 0x06, 0x7E, 0x09, 0x12, 0x07 /* ; F8-FF */
+ }
+ },
+ {0xFFFF, {
+ 0x04, 0x1A, 0x04, 0x7E, 0x02, 0x1B, 0x05, 0x7E, /* ; C0-C7 */
+ 0x01, 0x1A, 0x07, 0x7E, 0x00, 0x1A, 0x09, 0x7D, /* ; C8-CF */
+ 0x7F, 0x19, 0x0B, 0x7D, 0x7E, 0x18, 0x0D, 0x7D, /* ; D0-D7 */
+ 0x7D, 0x17, 0x10, 0x7C, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */
+ 0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */
+ 0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0D, 0x18, 0x7F, /* ; EA-EF */
+ 0x7D, 0x0B, 0x19, 0x7F, 0x7D, 0x09, 0x1A, 0x00, /* ; F0-F7 */
+ 0x7D, 0x07, 0x1A, 0x02, 0x7E, 0x05, 0x1B, 0x02 /* ; F8-FF */
+ }
+ }
+};
+
+static const struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = {
+ {480, {
+ 0x04, 0x1A, 0x04, 0x7E, 0x03, 0x1A, 0x06, 0x7D, /* ; C0-C7 */
+ 0x01, 0x1A, 0x08, 0x7D, 0x00, 0x19, 0x0A, 0x7D, /* ; C8-CF */
+ 0x7F, 0x19, 0x0C, 0x7C, 0x7E, 0x18, 0x0E, 0x7C, /* ; D0-D7 */
+ 0x7E, 0x17, 0x10, 0x7B, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */
+ 0x7D, 0x13, 0x13, 0x7D, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */
+ 0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0E, 0x18, 0x7E, /* ; EA-EF */
+ 0x7D, 0x0C, 0x19, 0x7E, 0x7D, 0x0A, 0x19, 0x00, /* ; F0-F7 */
+ 0x7D, 0x08, 0x1A, 0x01, 0x7E, 0x06, 0x1A, 0x02 /* ; F8-FF */
+ }
+ },
+ {600, {
+ 0x07, 0x14, 0x07, 0x7E, 0x06, 0x14, 0x09, 0x7D, /* ; C0-C7 */
+ 0x05, 0x14, 0x0A, 0x7D, 0x04, 0x13, 0x0B, 0x7E, /* ; C8-CF */
+ 0x03, 0x13, 0x0C, 0x7E, 0x02, 0x12, 0x0D, 0x7F, /* ; D0-D7 */
+ 0x01, 0x12, 0x0E, 0x7F, 0x01, 0x11, 0x0F, 0x7F, /* ; D8-DF */
+ 0x01, 0x10, 0x10, 0x00, 0x7F, 0x0F, 0x11, 0x01, /* ; E0-E7 */
+ 0x7F, 0x0E, 0x12, 0x01, 0x7E, 0x0D, 0x12, 0x03, /* ; EA-EF */
+ 0x7E, 0x0C, 0x13, 0x03, 0x7E, 0x0B, 0x13, 0x04, /* ; F0-F7 */
+ 0x7E, 0x0A, 0x14, 0x04, 0x7D, 0x09, 0x14, 0x06 /* ; F8-FF */
+ }
+ },
+ {0xFFFF, {
+ 0x09, 0x0F, 0x09, 0x7F, 0x08, 0x0F, 0x09, 0x00, /* ; C0-C7 */
+ 0x07, 0x0F, 0x0A, 0x00, 0x06, 0x0F, 0x0A, 0x01, /* ; C8-CF */
+ 0x06, 0x0E, 0x0B, 0x01, 0x05, 0x0E, 0x0B, 0x02, /* ; D0-D7 */
+ 0x04, 0x0E, 0x0C, 0x02, 0x04, 0x0D, 0x0C, 0x03, /* ; D8-DF */
+ 0x03, 0x0D, 0x0D, 0x03, 0x02, 0x0C, 0x0D, 0x05, /* ; E0-E7 */
+ 0x02, 0x0C, 0x0E, 0x04, 0x01, 0x0B, 0x0E, 0x06, /* ; EA-EF */
+ 0x01, 0x0B, 0x0E, 0x06, 0x00, 0x0A, 0x0F, 0x07, /* ; F0-F7 */
+ 0x00, 0x0A, 0x0F, 0x07, 0x00, 0x09, 0x0F, 0x08 /* ; F8-FF */
+ }
+ }
+};
+
+static const struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = {
+ {0xFFFF, {
+ 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */
+ 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */
+ 0x00, 0x18, 0x0C, 0x7C, 0x7F, 0x17, 0x0E, 0x7C, /* ; D0-D7 */
+ 0x7E, 0x16, 0x0F, 0x7D, 0x7E, 0x14, 0x11, 0x7D, /* ; D8-DF */
+ 0x7D, 0x13, 0x13, 0x7D, 0x7D, 0x11, 0x14, 0x7E, /* ; E0-E7 */
+ 0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */
+ 0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */
+ 0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04 /* F8-FF */
+ }
+ }
+};
+#endif
diff --git a/src/drivers/xgi/common/vb_util.c b/src/drivers/xgi/common/vb_util.c
new file mode 100644
index 0000000000..a705696638
--- /dev/null
+++ b/src/drivers/xgi/common/vb_util.c
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken from the Linux xgifb driver (v3.18.5)
+ * Coreboot-specific includes added at top
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "xgi_coreboot.h"
+
+#include "vgatypes.h"
+#include "vb_util.h"
+
+void xgifb_reg_set(unsigned long port, u8 index, u8 data)
+{
+ outb(index, port);
+ outb(data, port + 1);
+}
+
+u8 xgifb_reg_get(unsigned long port, u8 index)
+{
+ u8 data;
+
+ outb(index, port);
+ data = inb(port + 1);
+ return data;
+}
+
+void xgifb_reg_and_or(unsigned long port, u8 index,
+ unsigned data_and, unsigned data_or)
+{
+ u8 temp;
+
+ temp = xgifb_reg_get(port, index); /* XGINew_Part1Port index 02 */
+ temp = (temp & data_and) | data_or;
+ xgifb_reg_set(port, index, temp);
+}
+
+void xgifb_reg_and(unsigned long port, u8 index, unsigned data_and)
+{
+ u8 temp;
+
+ temp = xgifb_reg_get(port, index); /* XGINew_Part1Port index 02 */
+ temp &= data_and;
+ xgifb_reg_set(port, index, temp);
+}
+
+void xgifb_reg_or(unsigned long port, u8 index, unsigned data_or)
+{
+ u8 temp;
+
+ temp = xgifb_reg_get(port, index); /* XGINew_Part1Port index 02 */
+ temp |= data_or;
+ xgifb_reg_set(port, index, temp);
+}
diff --git a/src/drivers/xgi/common/vb_util.h b/src/drivers/xgi/common/vb_util.h
new file mode 100644
index 0000000000..6fe9029991
--- /dev/null
+++ b/src/drivers/xgi/common/vb_util.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken verbatim from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VBUTIL_
+#define _VBUTIL_
+extern void xgifb_reg_set(unsigned long, u8, u8);
+extern u8 xgifb_reg_get(unsigned long, u8);
+extern void xgifb_reg_or(unsigned long, u8, unsigned);
+extern void xgifb_reg_and(unsigned long, u8, unsigned);
+extern void xgifb_reg_and_or(unsigned long, u8, unsigned, unsigned);
+#endif
+
diff --git a/src/drivers/xgi/common/vgatypes.h b/src/drivers/xgi/common/vgatypes.h
new file mode 100644
index 0000000000..7d6772d17a
--- /dev/null
+++ b/src/drivers/xgi/common/vgatypes.h
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * File taken verbatim from the Linux xgifb driver (v3.18.5)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VGATYPES_
+#define _VGATYPES_
+
+enum XGI_VB_CHIP_TYPE {
+ VB_CHIP_Legacy = 0,
+ VB_CHIP_301,
+ VB_CHIP_301B,
+ VB_CHIP_301LV,
+ VB_CHIP_302,
+ VB_CHIP_302B,
+ VB_CHIP_302LV,
+ VB_CHIP_301C,
+ VB_CHIP_302ELV,
+ VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
+ MAX_VB_CHIP
+};
+
+struct xgi_hw_device_info {
+ unsigned long ulExternalChip; /* NO VB or other video bridge*/
+ /* if ujVBChipID = VB_CHIP_UNKNOWN, */
+
+ void __iomem *pjVideoMemoryAddress;/* base virtual memory address */
+ /* of Linear VGA memory */
+
+ unsigned long ulVideoMemorySize; /* size, in bytes, of the
+ memory on the board */
+
+ unsigned char jChipType; /* Used to Identify Graphics Chip */
+ /* defined in the data structure type */
+ /* "XGI_CHIP_TYPE" */
+
+ unsigned char jChipRevision; /* Used to Identify Graphics
+ Chip Revision */
+
+ unsigned char ujVBChipID; /* the ID of video bridge */
+ /* defined in the data structure type */
+ /* "XGI_VB_CHIP_TYPE" */
+
+ unsigned long ulCRT2LCDType; /* defined in the data structure type */
+};
+
+/* Additional IOCTL for communication xgifb <> X driver */
+/* If changing this, xgifb.h must also be changed (for xgifb) */
+#endif
+
diff --git a/src/drivers/xgi/common/vstruct.h b/src/drivers/xgi/common/vstruct.h
new file mode 100644
index 0000000000..ea94d214dc
--- /dev/null
+++ b/src/drivers/xgi/common/vstruct.h
@@ -0,0 +1,551 @@
+/* $XFree86$ */
+/* $XdotOrg$ */
+/*
+ * General structure definitions for universal mode switching modules
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) 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.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ */
+
+#ifndef _VSTRUCT_H_
+#define _VSTRUCT_H_
+
+struct SiS_PanelDelayTbl {
+ unsigned char timer[2];
+};
+
+struct SiS_LCDData {
+ unsigned short RVBHCMAX;
+ unsigned short RVBHCFACT;
+ unsigned short VGAHT;
+ unsigned short VGAVT;
+ unsigned short LCDHT;
+ unsigned short LCDVT;
+};
+
+struct SiS_TVData {
+ unsigned short RVBHCMAX;
+ unsigned short RVBHCFACT;
+ unsigned short VGAHT;
+ unsigned short VGAVT;
+ unsigned short TVHDE;
+ unsigned short TVVDE;
+ unsigned short RVBHRS;
+ unsigned char FlickerMode;
+ unsigned short HALFRVBHRS;
+ unsigned short RVBHRS2;
+ unsigned char RY1COE;
+ unsigned char RY2COE;
+ unsigned char RY3COE;
+ unsigned char RY4COE;
+};
+
+struct SiS_LVDSData {
+ unsigned short VGAHT;
+ unsigned short VGAVT;
+ unsigned short LCDHT;
+ unsigned short LCDVT;
+};
+
+struct SiS_LVDSDes {
+ unsigned short LCDHDES;
+ unsigned short LCDVDES;
+};
+
+struct SiS_LVDSCRT1Data {
+ unsigned char CR[15];
+};
+
+struct SiS_CHTVRegData {
+ unsigned char Reg[16];
+};
+
+struct SiS_St {
+ unsigned char St_ModeID;
+ unsigned short St_ModeFlag;
+ unsigned char St_StTableIndex;
+ unsigned char St_CRT2CRTC;
+ unsigned char St_ResInfo;
+ unsigned char VB_StTVFlickerIndex;
+ unsigned char VB_StTVEdgeIndex;
+ unsigned char VB_StTVYFilterIndex;
+ unsigned char St_PDC;
+};
+
+struct SiS_VBMode {
+ unsigned char ModeID;
+ unsigned char VB_TVDelayIndex;
+ unsigned char VB_TVFlickerIndex;
+ unsigned char VB_TVPhaseIndex;
+ unsigned char VB_TVYFilterIndex;
+ unsigned char VB_LCDDelayIndex;
+ unsigned char _VB_LCDHIndex;
+ unsigned char _VB_LCDVIndex;
+};
+
+struct SiS_StandTable_S {
+ unsigned char CRT_COLS;
+ unsigned char ROWS;
+ unsigned char CHAR_HEIGHT;
+ unsigned short CRT_LEN;
+ unsigned char SR[4];
+ unsigned char MISC;
+ unsigned char CRTC[0x19];
+ unsigned char ATTR[0x14];
+ unsigned char GRC[9];
+};
+
+struct SiS_Ext {
+ unsigned char Ext_ModeID;
+ unsigned short Ext_ModeFlag;
+ unsigned short Ext_VESAID;
+ unsigned char Ext_RESINFO;
+ unsigned char VB_ExtTVFlickerIndex;
+ unsigned char VB_ExtTVEdgeIndex;
+ unsigned char VB_ExtTVYFilterIndex;
+ unsigned char VB_ExtTVYFilterIndexROM661;
+ unsigned char REFindex;
+ char ROMMODEIDX661;
+};
+
+struct SiS_Ext2 {
+ unsigned short Ext_InfoFlag;
+ unsigned char Ext_CRT1CRTC;
+ unsigned char Ext_CRTVCLK;
+ unsigned char Ext_CRT2CRTC;
+ unsigned char Ext_CRT2CRTC_NS;
+ unsigned char ModeID;
+ unsigned short XRes;
+ unsigned short YRes;
+ unsigned char Ext_PDC;
+ unsigned char Ext_FakeCRT2CRTC;
+ unsigned char Ext_FakeCRT2Clk;
+ unsigned char Ext_CRT1CRTC_NORM;
+ unsigned char Ext_CRTVCLK_NORM;
+ unsigned char Ext_CRT1CRTC_WIDE;
+ unsigned char Ext_CRTVCLK_WIDE;
+};
+
+struct SiS_Part2PortTbl {
+ unsigned char CR[12];
+};
+
+struct SiS_CRT1Table {
+ unsigned char CR[17];
+};
+
+struct SiS_MCLKData {
+ unsigned char SR28,SR29,SR2A;
+ unsigned short CLOCK;
+};
+
+struct SiS_VCLKData {
+ unsigned char SR2B,SR2C;
+ unsigned short CLOCK;
+};
+
+struct SiS_VBVCLKData {
+ unsigned char Part4_A,Part4_B;
+ unsigned short CLOCK;
+};
+
+struct SiS_StResInfo_S {
+ unsigned short HTotal;
+ unsigned short VTotal;
+};
+
+struct SiS_ModeResInfo_S {
+ unsigned short HTotal;
+ unsigned short VTotal;
+ unsigned char XChar;
+ unsigned char YChar;
+};
+
+/* Defines for SiS_CustomT */
+/* Never change these for sisfb compatibility */
+#define CUT_NONE 0
+#define CUT_FORCENONE 1
+#define CUT_BARCO1366 2
+#define CUT_BARCO1024 3
+#define CUT_COMPAQ1280 4
+#define CUT_COMPAQ12802 5
+#define CUT_PANEL848 6
+#define CUT_CLEVO1024 7
+#define CUT_CLEVO10242 8
+#define CUT_CLEVO1400 9
+#define CUT_CLEVO14002 10
+#define CUT_UNIWILL1024 11
+#define CUT_ASUSL3000D 12
+#define CUT_UNIWILL10242 13
+#define CUT_ACER1280 14
+#define CUT_COMPAL1400_1 15
+#define CUT_COMPAL1400_2 16
+#define CUT_ASUSA2H_1 17
+#define CUT_ASUSA2H_2 18
+#define CUT_UNKNOWNLCD 19
+#define CUT_AOP8060 20
+#define CUT_PANEL856 21
+
+struct SiS_Private
+{
+ unsigned char ChipType;
+ unsigned char ChipRevision;
+ void *ivideo;
+ unsigned char *VirtualRomBase;
+ bool UseROM;
+ unsigned char SISIOMEMTYPE *VideoMemoryAddress;
+ unsigned int VideoMemorySize;
+ SISIOADDRESS IOAddress;
+ SISIOADDRESS IOAddress2; /* For dual chip XGI volari */
+
+ SISIOADDRESS RelIO;
+ SISIOADDRESS SiS_P3c4;
+ SISIOADDRESS SiS_P3d4;
+ SISIOADDRESS SiS_P3c0;
+ SISIOADDRESS SiS_P3ce;
+ SISIOADDRESS SiS_P3c2;
+ SISIOADDRESS SiS_P3ca;
+ SISIOADDRESS SiS_P3c6;
+ SISIOADDRESS SiS_P3c7;
+ SISIOADDRESS SiS_P3c8;
+ SISIOADDRESS SiS_P3c9;
+ SISIOADDRESS SiS_P3cb;
+ SISIOADDRESS SiS_P3cc;
+ SISIOADDRESS SiS_P3cd;
+ SISIOADDRESS SiS_P3da;
+ SISIOADDRESS SiS_Part1Port;
+ SISIOADDRESS SiS_Part2Port;
+ SISIOADDRESS SiS_Part3Port;
+ SISIOADDRESS SiS_Part4Port;
+ SISIOADDRESS SiS_Part5Port;
+ SISIOADDRESS SiS_VidCapt;
+ SISIOADDRESS SiS_VidPlay;
+ unsigned short SiS_IF_DEF_LVDS;
+ unsigned short SiS_IF_DEF_CH70xx;
+ unsigned short SiS_IF_DEF_CONEX;
+ unsigned short SiS_IF_DEF_TRUMPION;
+ unsigned short SiS_IF_DEF_DSTN;
+ unsigned short SiS_IF_DEF_FSTN;
+ unsigned short SiS_SysFlags;
+ unsigned char SiS_VGAINFO;
+ bool SiS_UseROM;
+ bool SiS_ROMNew;
+ bool SiS_XGIROM;
+ bool SiS_NeedRomModeData;
+ bool PanelSelfDetected;
+ bool DDCPortMixup;
+ int SiS_CHOverScan;
+ bool SiS_CHSOverScan;
+ bool SiS_ChSW;
+ bool SiS_UseLCDA;
+ int SiS_UseOEM;
+ unsigned int SiS_CustomT;
+ int SiS_UseWide, SiS_UseWideCRT2;
+ int SiS_TVBlue;
+ unsigned short SiS_Backup70xx;
+ bool HaveEMI;
+ bool HaveEMILCD;
+ bool OverruleEMI;
+ unsigned char EMI_30,EMI_31,EMI_32,EMI_33;
+ unsigned short SiS_EMIOffset;
+ unsigned short SiS_PWDOffset;
+ short PDC, PDCA;
+ unsigned char SiS_MyCR63;
+ unsigned short SiS_CRT1Mode;
+ unsigned short SiS_flag_clearbuffer;
+ int SiS_RAMType;
+ unsigned char SiS_ChannelAB;
+ unsigned char SiS_DataBusWidth;
+ unsigned short SiS_ModeType;
+ unsigned short SiS_VBInfo;
+ unsigned short SiS_TVMode;
+ unsigned short SiS_LCDResInfo;
+ unsigned short SiS_LCDTypeInfo;
+ unsigned short SiS_LCDInfo;
+ unsigned short SiS_LCDInfo661;
+ unsigned short SiS_VBType;
+ unsigned short SiS_VBExtInfo;
+ unsigned short SiS_YPbPr;
+ unsigned short SiS_SelectCRT2Rate;
+ unsigned short SiS_SetFlag;
+ unsigned short SiS_RVBHCFACT;
+ unsigned short SiS_RVBHCMAX;
+ unsigned short SiS_RVBHRS;
+ unsigned short SiS_RVBHRS2;
+ unsigned short SiS_VGAVT;
+ unsigned short SiS_VGAHT;
+ unsigned short SiS_VT;
+ unsigned short SiS_HT;
+ unsigned short SiS_VGAVDE;
+ unsigned short SiS_VGAHDE;
+ unsigned short SiS_VDE;
+ unsigned short SiS_HDE;
+ unsigned short SiS_NewFlickerMode;
+ unsigned short SiS_RY1COE;
+ unsigned short SiS_RY2COE;
+ unsigned short SiS_RY3COE;
+ unsigned short SiS_RY4COE;
+ unsigned short SiS_LCDHDES;
+ unsigned short SiS_LCDVDES;
+ SISIOADDRESS SiS_DDC_Port;
+ unsigned short SiS_DDC_Index;
+ unsigned short SiS_DDC_Data;
+ unsigned short SiS_DDC_NData;
+ unsigned short SiS_DDC_Clk;
+ unsigned short SiS_DDC_NClk;
+ unsigned short SiS_DDC_DeviceAddr;
+ unsigned short SiS_DDC_ReadAddr;
+ unsigned short SiS_DDC_SecAddr;
+ unsigned short SiS_ChrontelInit;
+ bool SiS_SensibleSR11;
+ unsigned short SiS661LCD2TableSize;
+
+ unsigned short SiS_PanelMinLVDS;
+ unsigned short SiS_PanelMin301;
+
+ const struct SiS_St *SiS_SModeIDTable;
+ const struct SiS_StandTable_S *SiS_StandTable;
+ const struct SiS_Ext *SiS_EModeIDTable;
+ const struct SiS_Ext2 *SiS_RefIndex;
+ const struct SiS_VBMode *SiS_VBModeIDTable;
+ const struct SiS_CRT1Table *SiS_CRT1Table;
+ const struct SiS_MCLKData *SiS_MCLKData_0;
+ const struct SiS_MCLKData *SiS_MCLKData_1;
+ struct SiS_VCLKData *SiS_VCLKData;
+ struct SiS_VBVCLKData *SiS_VBVCLKData;
+ const struct SiS_StResInfo_S *SiS_StResInfo;
+ const struct SiS_ModeResInfo_S *SiS_ModeResInfo;
+
+ const unsigned char *pSiS_OutputSelect;
+ const unsigned char *pSiS_SoftSetting;
+
+ const unsigned char *SiS_SR15;
+
+ const struct SiS_PanelDelayTbl *SiS_PanelDelayTbl;
+ const struct SiS_PanelDelayTbl *SiS_PanelDelayTblLVDS;
+
+ /* SiS bridge */
+
+ const struct SiS_LCDData *SiS_ExtLCD1024x768Data;
+ const struct SiS_LCDData *SiS_St2LCD1024x768Data;
+ const struct SiS_LCDData *SiS_LCD1280x720Data;
+ const struct SiS_LCDData *SiS_StLCD1280x768_2Data;
+ const struct SiS_LCDData *SiS_ExtLCD1280x768_2Data;
+ const struct SiS_LCDData *SiS_LCD1280x800Data;
+ const struct SiS_LCDData *SiS_LCD1280x800_2Data;
+ const struct SiS_LCDData *SiS_LCD1280x854Data;
+ const struct SiS_LCDData *SiS_LCD1280x960Data;
+ const struct SiS_LCDData *SiS_ExtLCD1280x1024Data;
+ const struct SiS_LCDData *SiS_St2LCD1280x1024Data;
+ const struct SiS_LCDData *SiS_StLCD1400x1050Data;
+ const struct SiS_LCDData *SiS_ExtLCD1400x1050Data;
+ const struct SiS_LCDData *SiS_StLCD1600x1200Data;
+ const struct SiS_LCDData *SiS_ExtLCD1600x1200Data;
+ const struct SiS_LCDData *SiS_LCD1680x1050Data;
+ const struct SiS_LCDData *SiS_NoScaleData;
+ const struct SiS_TVData *SiS_StPALData;
+ const struct SiS_TVData *SiS_ExtPALData;
+ const struct SiS_TVData *SiS_StNTSCData;
+ const struct SiS_TVData *SiS_ExtNTSCData;
+ const struct SiS_TVData *SiS_St1HiTVData;
+ const struct SiS_TVData *SiS_St2HiTVData;
+ const struct SiS_TVData *SiS_ExtHiTVData;
+ const struct SiS_TVData *SiS_St525iData;
+ const struct SiS_TVData *SiS_St525pData;
+ const struct SiS_TVData *SiS_St750pData;
+ const struct SiS_TVData *SiS_Ext525iData;
+ const struct SiS_TVData *SiS_Ext525pData;
+ const struct SiS_TVData *SiS_Ext750pData;
+ const unsigned char *SiS_NTSCTiming;
+ const unsigned char *SiS_PALTiming;
+ const unsigned char *SiS_HiTVExtTiming;
+ const unsigned char *SiS_HiTVSt1Timing;
+ const unsigned char *SiS_HiTVSt2Timing;
+ const unsigned char *SiS_HiTVGroup3Data;
+ const unsigned char *SiS_HiTVGroup3Simu;
+#if 0
+ const unsigned char *SiS_HiTVTextTiming;
+ const unsigned char *SiS_HiTVGroup3Text;
+#endif
+
+ const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_1;
+ const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_2;
+ const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_3;
+
+ /* LVDS, Chrontel */
+
+ const struct SiS_LVDSData *SiS_LVDS320x240Data_1;
+ const struct SiS_LVDSData *SiS_LVDS320x240Data_2;
+ const struct SiS_LVDSData *SiS_LVDS640x480Data_1;
+ const struct SiS_LVDSData *SiS_LVDS800x600Data_1;
+ const struct SiS_LVDSData *SiS_LVDS1024x600Data_1;
+ const struct SiS_LVDSData *SiS_LVDS1024x768Data_1;
+ const struct SiS_LVDSData *SiS_LVDSBARCO1366Data_1;
+ const struct SiS_LVDSData *SiS_LVDSBARCO1366Data_2;
+ const struct SiS_LVDSData *SiS_LVDSBARCO1024Data_1;
+ const struct SiS_LVDSData *SiS_LVDS848x480Data_1;
+ const struct SiS_LVDSData *SiS_LVDS848x480Data_2;
+ const struct SiS_LVDSData *SiS_CHTVUNTSCData;
+ const struct SiS_LVDSData *SiS_CHTVONTSCData;
+ const struct SiS_LVDSData *SiS_CHTVUPALData;
+ const struct SiS_LVDSData *SiS_CHTVOPALData;
+ const struct SiS_LVDSData *SiS_CHTVUPALMData;
+ const struct SiS_LVDSData *SiS_CHTVOPALMData;
+ const struct SiS_LVDSData *SiS_CHTVUPALNData;
+ const struct SiS_LVDSData *SiS_CHTVOPALNData;
+ const struct SiS_LVDSData *SiS_CHTVSOPALData;
+
+ const struct SiS_LVDSDes *SiS_PanelType04_1a;
+ const struct SiS_LVDSDes *SiS_PanelType04_2a;
+ const struct SiS_LVDSDes *SiS_PanelType04_1b;
+ const struct SiS_LVDSDes *SiS_PanelType04_2b;
+
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_1;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_2;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_2_H;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_3;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_3_H;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1640x480_1;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1640x480_1_H;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1UNTSC;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1ONTSC;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1UPAL;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1OPAL;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1SOPAL;
+
+ const struct SiS_CHTVRegData *SiS_CHTVReg_UNTSC;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_ONTSC;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_UPAL;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_OPAL;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_UPALM;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_OPALM;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_UPALN;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_OPALN;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_SOPAL;
+
+ const unsigned char *SiS_CHTVVCLKUNTSC;
+ const unsigned char *SiS_CHTVVCLKONTSC;
+ const unsigned char *SiS_CHTVVCLKUPAL;
+ const unsigned char *SiS_CHTVVCLKOPAL;
+ const unsigned char *SiS_CHTVVCLKUPALM;
+ const unsigned char *SiS_CHTVVCLKOPALM;
+ const unsigned char *SiS_CHTVVCLKUPALN;
+ const unsigned char *SiS_CHTVVCLKOPALN;
+ const unsigned char *SiS_CHTVVCLKSOPAL;
+
+ unsigned short PanelXRes, PanelHT;
+ unsigned short PanelYRes, PanelVT;
+ unsigned short PanelHRS, PanelHRE;
+ unsigned short PanelVRS, PanelVRE;
+ unsigned short PanelVCLKIdx300;
+ unsigned short PanelVCLKIdx315;
+ bool Alternate1600x1200;
+
+ bool UseCustomMode;
+ bool CRT1UsesCustomMode;
+ unsigned short CHDisplay;
+ unsigned short CHSyncStart;
+ unsigned short CHSyncEnd;
+ unsigned short CHTotal;
+ unsigned short CHBlankStart;
+ unsigned short CHBlankEnd;
+ unsigned short CVDisplay;
+ unsigned short CVSyncStart;
+ unsigned short CVSyncEnd;
+ unsigned short CVTotal;
+ unsigned short CVBlankStart;
+ unsigned short CVBlankEnd;
+ unsigned int CDClock;
+ unsigned int CFlags;
+ unsigned char CCRT1CRTC[17];
+ unsigned char CSR2B;
+ unsigned char CSR2C;
+ unsigned short CSRClock;
+ unsigned short CSRClock_CRT1;
+ unsigned short CModeFlag;
+ unsigned short CModeFlag_CRT1;
+ unsigned short CInfoFlag;
+
+ int LVDSHL;
+
+ bool Backup;
+ unsigned char Backup_Mode;
+ unsigned char Backup_14;
+ unsigned char Backup_15;
+ unsigned char Backup_16;
+ unsigned char Backup_17;
+ unsigned char Backup_18;
+ unsigned char Backup_19;
+ unsigned char Backup_1a;
+ unsigned char Backup_1b;
+ unsigned char Backup_1c;
+ unsigned char Backup_1d;
+
+ unsigned char Init_P4_0E;
+
+ int UsePanelScaler;
+ int CenterScreen;
+
+ unsigned short CP_Vendor, CP_Product;
+ bool CP_HaveCustomData;
+ int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
+ int CP_MaxX, CP_MaxY, CP_MaxClock;
+ unsigned char CP_PrefSR2B, CP_PrefSR2C;
+ unsigned short CP_PrefClock;
+ bool CP_Supports64048075;
+ int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
+ int CP_HTotal[7], CP_VTotal[7];
+ int CP_HSyncStart[7], CP_VSyncStart[7];
+ int CP_HSyncEnd[7], CP_VSyncEnd[7];
+ int CP_HBlankStart[7], CP_VBlankStart[7];
+ int CP_HBlankEnd[7], CP_VBlankEnd[7];
+ int CP_Clock[7];
+ bool CP_DataValid[7];
+ bool CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
+};
+
+#endif
+
diff --git a/src/drivers/xgi/common/xgi_coreboot.c b/src/drivers/xgi/common/xgi_coreboot.c
new file mode 100755
index 0000000000..84ed81abd1
--- /dev/null
+++ b/src/drivers/xgi/common/xgi_coreboot.c
@@ -0,0 +1,436 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * xgifb_probe taken from the Linux xgifb driver (v3.18.5) and adapted for coreboot
+ * xgifb_modeset cobbled together from other portions of the same driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <delay.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/io.h>
+#include <vbe.h>
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+#include <pc80/vga.h>
+
+#include "xgi_coreboot.h"
+#include "vstruct.h"
+
+#include "XGIfb.h"
+#include "XGI_main.h"
+#include "vb_init.h"
+#include "vb_util.h"
+#include "vb_setmode.h"
+
+#include "XGI_main.c"
+
+static int xgi_vbe_valid;
+static struct lb_framebuffer xgi_fb;
+
+int xgifb_probe(struct pci_dev *pdev, struct xgifb_video_info *xgifb_info)
+{
+ u8 reg, reg1;
+ u8 CR48, CR38;
+ int ret;
+ struct xgi_hw_device_info *hw_info;
+ unsigned long video_size_max;
+
+ hw_info = &xgifb_info->hw_info;
+ xgifb_info->chip_id = pdev->device;
+ pci_read_config_byte(pdev,
+ PCI_REVISION_ID,
+ &xgifb_info->revision_id);
+ hw_info->jChipRevision = xgifb_info->revision_id;
+
+ xgifb_info->subsysvendor = pdev->subsystem_vendor;
+ xgifb_info->subsysdevice = pdev->subsystem_device;
+
+ video_size_max = pci_resource_len(pdev, 0);
+ xgifb_info->video_base = pci_resource_start(pdev, 0);
+ xgifb_info->mmio_base = pci_resource_start(pdev, 1);
+ xgifb_info->mmio_size = pci_resource_len(pdev, 1);
+ xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30;
+ dev_info(&pdev->dev, "Relocate IO address: %Lx [%08lx]\n",
+ (u64) pci_resource_start(pdev, 2),
+ xgifb_info->vga_base);
+
+ if (XGIfb_crt2type != -1) {
+ xgifb_info->display2 = XGIfb_crt2type;
+ xgifb_info->display2_force = true;
+ }
+
+ XGIRegInit(&xgifb_info->dev_info, xgifb_info->vga_base);
+
+ xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
+ reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD);
+
+ if (reg1 != 0xa1) {
+ dev_err(&pdev->dev, "I/O error\n");
+ ret = -5;
+ goto error_disable;
+ }
+
+ switch (xgifb_info->chip_id) {
+ case PCI_DEVICE_ID_XGI_20:
+ xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
+ CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
+ if (CR48&GPIOG_READ)
+ xgifb_info->chip = XG21;
+ else
+ xgifb_info->chip = XG20;
+ break;
+ case PCI_DEVICE_ID_XGI_40:
+ xgifb_info->chip = XG40;
+ break;
+ case PCI_DEVICE_ID_XGI_42:
+ xgifb_info->chip = XG42;
+ break;
+ case PCI_DEVICE_ID_XGI_27:
+ xgifb_info->chip = XG27;
+ break;
+ default:
+ ret = -19;
+ goto error_disable;
+ }
+
+ dev_info(&pdev->dev, "chipid = %x\n", xgifb_info->chip);
+ hw_info->jChipType = xgifb_info->chip;
+
+ if (XGIfb_get_dram_size(xgifb_info)) {
+ xgifb_info->video_size = min_t(unsigned long, video_size_max,
+ SZ_16M);
+ } else if (xgifb_info->video_size > video_size_max) {
+ xgifb_info->video_size = video_size_max;
+ }
+
+ /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
+ xgifb_reg_or(XGISR,
+ IND_SIS_PCI_ADDRESS_SET,
+ (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
+ /* Enable 2D accelerator engine */
+ xgifb_reg_or(XGISR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
+
+ hw_info->ulVideoMemorySize = xgifb_info->video_size;
+
+ xgifb_info->video_vbase = hw_info->pjVideoMemoryAddress = (void*)(intptr_t)xgifb_info->video_base;
+ xgifb_info->mmio_vbase = (void*)(intptr_t)xgifb_info->mmio_base;
+
+ dev_info(&pdev->dev,
+ "Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n",
+ (u64) xgifb_info->video_base,
+ xgifb_info->video_vbase,
+ xgifb_info->video_size / 1024);
+
+ dev_info(&pdev->dev,
+ "MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n",
+ (u64) xgifb_info->mmio_base, xgifb_info->mmio_vbase,
+ xgifb_info->mmio_size / 1024);
+
+ pci_set_drvdata(pdev, xgifb_info);
+ if (!XGIInitNew(pdev))
+ dev_err(&pdev->dev, "XGIInitNew() failed!\n");
+
+ xgifb_info->mtrr = -1;
+
+ xgifb_info->hasVB = HASVB_NONE;
+ if ((xgifb_info->chip == XG20) ||
+ (xgifb_info->chip == XG27)) {
+ xgifb_info->hasVB = HASVB_NONE;
+ } else if (xgifb_info->chip == XG21) {
+ CR38 = xgifb_reg_get(XGICR, 0x38);
+ if ((CR38 & 0xE0) == 0xC0)
+ xgifb_info->display2 = XGIFB_DISP_LCD;
+ else if ((CR38 & 0xE0) == 0x60)
+ xgifb_info->hasVB = HASVB_CHRONTEL;
+ else
+ xgifb_info->hasVB = HASVB_NONE;
+ } else {
+ XGIfb_get_VB_type(xgifb_info);
+ }
+
+ hw_info->ujVBChipID = VB_CHIP_UNKNOWN;
+
+ hw_info->ulExternalChip = 0;
+
+ switch (xgifb_info->hasVB) {
+ case HASVB_301:
+ reg = xgifb_reg_get(XGIPART4, 0x01);
+ if (reg >= 0xE0) {
+ hw_info->ujVBChipID = VB_CHIP_302LV;
+ dev_info(&pdev->dev,
+ "XGI302LV bridge detected (revision 0x%02x)\n",
+ reg);
+ } else if (reg >= 0xD0) {
+ hw_info->ujVBChipID = VB_CHIP_301LV;
+ dev_info(&pdev->dev,
+ "XGI301LV bridge detected (revision 0x%02x)\n",
+ reg);
+ } else {
+ hw_info->ujVBChipID = VB_CHIP_301;
+ dev_info(&pdev->dev, "XGI301 bridge detected\n");
+ }
+ break;
+ case HASVB_302:
+ reg = xgifb_reg_get(XGIPART4, 0x01);
+ if (reg >= 0xE0) {
+ hw_info->ujVBChipID = VB_CHIP_302LV;
+ dev_info(&pdev->dev,
+ "XGI302LV bridge detected (revision 0x%02x)\n",
+ reg);
+ } else if (reg >= 0xD0) {
+ hw_info->ujVBChipID = VB_CHIP_301LV;
+ dev_info(&pdev->dev,
+ "XGI302LV bridge detected (revision 0x%02x)\n",
+ reg);
+ } else if (reg >= 0xB0) {
+ reg1 = xgifb_reg_get(XGIPART4, 0x23);
+
+ hw_info->ujVBChipID = VB_CHIP_302B;
+
+ } else {
+ hw_info->ujVBChipID = VB_CHIP_302;
+ dev_info(&pdev->dev, "XGI302 bridge detected\n");
+ }
+ break;
+ case HASVB_LVDS:
+ hw_info->ulExternalChip = 0x1;
+ dev_info(&pdev->dev, "LVDS transmitter detected\n");
+ break;
+ case HASVB_TRUMPION:
+ hw_info->ulExternalChip = 0x2;
+ dev_info(&pdev->dev, "Trumpion Zurac LVDS scaler detected\n");
+ break;
+ case HASVB_CHRONTEL:
+ hw_info->ulExternalChip = 0x4;
+ dev_info(&pdev->dev, "Chrontel TV encoder detected\n");
+ break;
+ case HASVB_LVDS_CHRONTEL:
+ hw_info->ulExternalChip = 0x5;
+ dev_info(&pdev->dev,
+ "LVDS transmitter and Chrontel TV encoder detected\n");
+ break;
+ default:
+ dev_info(&pdev->dev, "No or unknown bridge type detected\n");
+ break;
+ }
+
+ if (xgifb_info->hasVB != HASVB_NONE)
+ XGIfb_detect_VB(xgifb_info);
+ else if (xgifb_info->chip != XG21)
+ xgifb_info->display2 = XGIFB_DISP_NONE;
+
+ if (xgifb_info->display2 == XGIFB_DISP_LCD) {
+ if (!enable_dstn) {
+ reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
+ reg &= 0x0f;
+ hw_info->ulCRT2LCDType = XGI310paneltype[reg];
+ }
+ }
+
+ xgifb_info->mode_idx = -1;
+
+ /* FIXME coreboot does not provide sscanf, needed by XGIfb_search_mode */
+ /* if (mode)
+ XGIfb_search_mode(xgifb_info, mode);
+ else */if (vesa != -1)
+ XGIfb_search_vesamode(xgifb_info, vesa);
+
+ if (xgifb_info->mode_idx >= 0)
+ xgifb_info->mode_idx =
+ XGIfb_validate_mode(xgifb_info, xgifb_info->mode_idx);
+
+ if (xgifb_info->mode_idx < 0) {
+ if (xgifb_info->display2 == XGIFB_DISP_LCD &&
+ xgifb_info->chip == XG21)
+ xgifb_info->mode_idx =
+ XGIfb_GetXG21DefaultLVDSModeIdx(xgifb_info);
+ else
+ xgifb_info->mode_idx = DEFAULT_MODE;
+ }
+
+ if (xgifb_info->mode_idx < 0) {
+ dev_err(&pdev->dev, "No supported video mode found\n");
+ ret = -22;
+ goto error_1;
+ }
+
+ /* set default refresh rate */
+ xgifb_info->refresh_rate = refresh_rate;
+ if (xgifb_info->refresh_rate == 0)
+ xgifb_info->refresh_rate = 60;
+ if (XGIfb_search_refresh_rate(xgifb_info,
+ xgifb_info->refresh_rate) == 0) {
+ xgifb_info->rate_idx = 1;
+ xgifb_info->refresh_rate = 60;
+ }
+
+ xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
+ xgifb_info->video_vwidth =
+ xgifb_info->video_width =
+ XGIbios_mode[xgifb_info->mode_idx].xres;
+ xgifb_info->video_vheight =
+ xgifb_info->video_height =
+ XGIbios_mode[xgifb_info->mode_idx].yres;
+ xgifb_info->org_x = xgifb_info->org_y = 0;
+ xgifb_info->video_linelength =
+ xgifb_info->video_width *
+ (xgifb_info->video_bpp >> 3);
+ switch (xgifb_info->video_bpp) {
+ case 8:
+ xgifb_info->DstColor = 0x0000;
+ xgifb_info->XGI310_AccelDepth = 0x00000000;
+ xgifb_info->video_cmap_len = 256;
+ break;
+ case 16:
+ xgifb_info->DstColor = 0x8000;
+ xgifb_info->XGI310_AccelDepth = 0x00010000;
+ xgifb_info->video_cmap_len = 16;
+ break;
+ case 32:
+ xgifb_info->DstColor = 0xC000;
+ xgifb_info->XGI310_AccelDepth = 0x00020000;
+ xgifb_info->video_cmap_len = 16;
+ break;
+ default:
+ xgifb_info->video_cmap_len = 16;
+ pr_info("Unsupported depth %d\n",
+ xgifb_info->video_bpp);
+ break;
+ }
+
+ pr_info("Default mode is %dx%dx%d (%dHz)\n",
+ xgifb_info->video_width,
+ xgifb_info->video_height,
+ xgifb_info->video_bpp,
+ xgifb_info->refresh_rate);
+
+ return 0;
+
+error_1:
+error_disable:
+ free(xgifb_info);
+ return ret;
+}
+
+int xgifb_modeset(struct pci_dev *pdev, struct xgifb_video_info *xgifb_info)
+{
+ struct xgi_hw_device_info *hw_info;
+
+ hw_info = &xgifb_info->hw_info;
+
+#if IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT)
+ /* Set mode */
+ XGIfb_pre_setmode(xgifb_info);
+ if (XGISetModeNew(xgifb_info, hw_info,
+ XGIbios_mode[xgifb_info->mode_idx].mode_no)
+ == 0) {
+ pr_err("Setting mode[0x%x] failed\n",
+ XGIbios_mode[xgifb_info->mode_idx].mode_no);
+ return -22;
+ }
+ xgifb_info->video_linelength =
+ xgifb_info->video_width *
+ (xgifb_info->video_bpp >> 3);
+
+ xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+ xgifb_reg_set(XGICR, 0x13, (xgifb_info->video_linelength & 0x00ff));
+ xgifb_reg_set(XGISR,
+ 0x0E,
+ (xgifb_info->video_linelength & 0xff00) >> 8);
+
+ XGIfb_post_setmode(xgifb_info);
+
+ pr_debug("Set new mode: %dx%dx%d-%d\n",
+ XGIbios_mode[xgifb_info->mode_idx].xres,
+ XGIbios_mode[xgifb_info->mode_idx].yres,
+ XGIbios_mode[xgifb_info->mode_idx].bpp,
+ xgifb_info->refresh_rate);
+
+ /* Set LinuxBIOS framebuffer information */
+ xgi_vbe_valid = 1;
+ xgi_fb.physical_address = xgifb_info->video_base;
+ xgi_fb.x_resolution = xgifb_info->video_width;
+ xgi_fb.y_resolution = xgifb_info->video_height;
+ xgi_fb.bytes_per_line = xgifb_info->video_width * xgifb_info->video_bpp;
+ xgi_fb.bits_per_pixel = xgifb_info->video_bpp;
+
+ xgi_fb.reserved_mask_pos = 0;
+ xgi_fb.reserved_mask_size = 0;
+ switch(xgifb_info->video_bpp){
+ case 32:
+ case 24:
+ /* packed into 4-byte words */
+ xgi_fb.reserved_mask_pos = 24;
+ xgi_fb.reserved_mask_size = 8;
+ xgi_fb.red_mask_pos = 16;
+ xgi_fb.red_mask_size = 8;
+ xgi_fb.green_mask_pos = 8;
+ xgi_fb.green_mask_size = 8;
+ xgi_fb.blue_mask_pos = 0;
+ xgi_fb.blue_mask_size = 8;
+ break;
+ case 16:
+ /* packed into 2-byte words */
+ xgi_fb.red_mask_pos = 11;
+ xgi_fb.red_mask_size = 5;
+ xgi_fb.green_mask_pos = 5;
+ xgi_fb.green_mask_size = 6;
+ xgi_fb.blue_mask_pos = 0;
+ xgi_fb.blue_mask_size = 5;
+ break;
+ default:
+ printk(BIOS_SPEW, "%s: unsupported BPP %d\n", __func__,
+ xgifb_info->video_bpp);
+ xgi_vbe_valid = 0;
+ }
+#else
+ /* FIXME
+ * Text mode does not work
+ */
+ vga_io_init();
+ vga_textmode_init();
+#endif
+
+ return 0;
+}
+
+int vbe_mode_info_valid(void)
+{
+ return xgi_vbe_valid;
+}
+
+void fill_lb_framebuffer(struct lb_framebuffer *framebuffer)
+{
+ *framebuffer = xgi_fb;
+}
+
+struct xgifb_video_info *xgifb_video_info_ptr;
+
+struct xgifb_video_info *pci_get_drvdata(struct pci_dev *pdev) {
+ return xgifb_video_info_ptr;
+}
+
+void pci_set_drvdata(struct pci_dev *pdev, struct xgifb_video_info *data) {
+ xgifb_video_info_ptr = data;
+} \ No newline at end of file
diff --git a/src/drivers/xgi/common/xgi_coreboot.h b/src/drivers/xgi/common/xgi_coreboot.h
new file mode 100644
index 0000000000..524615ccaf
--- /dev/null
+++ b/src/drivers/xgi/common/xgi_coreboot.h
@@ -0,0 +1,289 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Portions marked below taken from XGI/SiS Linux kernel drivers */
+
+#ifndef _XGI_COREBOOT_
+#define _XGI_COREBOOT_
+
+#include <delay.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+#include "initdef.h"
+
+/* Begin code taken from Linux kernel 3.18.5 */
+
+/* For 315/Xabre series */
+#define COMMAND_QUEUE_AREA_SIZE (512 * 1024) /* 512K */
+#define COMMAND_QUEUE_AREA_SIZE_Z7 (128 * 1024) /* 128k for XGI Z7 */
+#define HW_CURSOR_AREA_SIZE_315 16384 /* 16K */
+#define COMMAND_QUEUE_THRESHOLD 0x1F
+
+#define SIS_OH_ALLOC_SIZE 4000
+#define SENTINEL 0x7fffffff
+
+#define SEQ_ADR 0x14
+#define SEQ_DATA 0x15
+#define DAC_ADR 0x18
+#define DAC_DATA 0x19
+#define CRTC_ADR 0x24
+#define CRTC_DATA 0x25
+#define DAC2_ADR (0x16-0x30)
+#define DAC2_DATA (0x17-0x30)
+#define VB_PART1_ADR (0x04-0x30)
+#define VB_PART1_DATA (0x05-0x30)
+#define VB_PART2_ADR (0x10-0x30)
+#define VB_PART2_DATA (0x11-0x30)
+#define VB_PART3_ADR (0x12-0x30)
+#define VB_PART3_DATA (0x13-0x30)
+#define VB_PART4_ADR (0x14-0x30)
+#define VB_PART4_DATA (0x15-0x30)
+
+#define SISSR ivideo->SiS_Pr.SiS_P3c4
+#define SISCR ivideo->SiS_Pr.SiS_P3d4
+#define SISDACA ivideo->SiS_Pr.SiS_P3c8
+#define SISDACD ivideo->SiS_Pr.SiS_P3c9
+#define SISPART1 ivideo->SiS_Pr.SiS_Part1Port
+#define SISPART2 ivideo->SiS_Pr.SiS_Part2Port
+#define SISPART3 ivideo->SiS_Pr.SiS_Part3Port
+#define SISPART4 ivideo->SiS_Pr.SiS_Part4Port
+#define SISPART5 ivideo->SiS_Pr.SiS_Part5Port
+#define SISDAC2A SISPART5
+#define SISDAC2D (SISPART5 + 1)
+#define SISMISCR (ivideo->SiS_Pr.RelIO + 0x1c)
+#define SISMISCW ivideo->SiS_Pr.SiS_P3c2
+#define SISINPSTAT (ivideo->SiS_Pr.RelIO + 0x2a)
+#define SISPEL ivideo->SiS_Pr.SiS_P3c6
+#define SISVGAENABLE (ivideo->SiS_Pr.RelIO + 0x13)
+#define SISVID (ivideo->SiS_Pr.RelIO + 0x02 - 0x30)
+#define SISCAP (ivideo->SiS_Pr.RelIO + 0x00 - 0x30)
+
+#define IND_SIS_PASSWORD 0x05 /* SRs */
+#define IND_SIS_COLOR_MODE 0x06
+#define IND_SIS_RAMDAC_CONTROL 0x07
+#define IND_SIS_DRAM_SIZE 0x14
+#define IND_SIS_MODULE_ENABLE 0x1E
+#define IND_SIS_PCI_ADDRESS_SET 0x20
+#define IND_SIS_TURBOQUEUE_ADR 0x26
+#define IND_SIS_TURBOQUEUE_SET 0x27
+#define IND_SIS_POWER_ON_TRAP 0x38
+#define IND_SIS_POWER_ON_TRAP2 0x39
+#define IND_SIS_CMDQUEUE_SET 0x26
+#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
+
+#define IND_SIS_AGP_IO_PAD 0x48
+
+#define SIS_CRT2_WENABLE_300 0x24 /* Part1 */
+#define SIS_CRT2_WENABLE_315 0x2F
+
+#define SIS_PASSWORD 0x86 /* SR05 */
+
+#define SIS_INTERLACED_MODE 0x20 /* SR06 */
+#define SIS_8BPP_COLOR_MODE 0x0
+#define SIS_15BPP_COLOR_MODE 0x1
+#define SIS_16BPP_COLOR_MODE 0x2
+#define SIS_32BPP_COLOR_MODE 0x4
+
+#define SIS_ENABLE_2D 0x40 /* SR1E */
+
+#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
+#define SIS_PCI_ADDR_ENABLE 0x80
+
+#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330/340 series SR26 */
+#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
+#define SIS_MMIO_CMD_ENABLE 0x20
+#define SIS_CMD_QUEUE_SIZE_512k 0x00
+#define SIS_CMD_QUEUE_SIZE_1M 0x04
+#define SIS_CMD_QUEUE_SIZE_2M 0x08
+#define SIS_CMD_QUEUE_SIZE_4M 0x0C
+#define SIS_CMD_QUEUE_RESET 0x01
+#define SIS_CMD_AUTO_CORR 0x02
+
+#define SIS_CMD_QUEUE_SIZE_Z7_64k 0x00 /* XGI Z7 */
+#define SIS_CMD_QUEUE_SIZE_Z7_128k 0x04
+
+#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
+#define SIS_MODE_SELECT_CRT2 0x02
+#define SIS_VB_OUTPUT_COMPOSITE 0x04
+#define SIS_VB_OUTPUT_SVIDEO 0x08
+#define SIS_VB_OUTPUT_SCART 0x10
+#define SIS_VB_OUTPUT_LCD 0x20
+#define SIS_VB_OUTPUT_CRT2 0x40
+#define SIS_VB_OUTPUT_HIVISION 0x80
+
+#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */
+#define SIS_DRIVER_MODE 0x40
+
+#define SIS_VB_COMPOSITE 0x01 /* CR32 */
+#define SIS_VB_SVIDEO 0x02
+#define SIS_VB_SCART 0x04
+#define SIS_VB_LCD 0x08
+#define SIS_VB_CRT2 0x10
+#define SIS_CRT1 0x20
+#define SIS_VB_HIVISION 0x40
+#define SIS_VB_YPBPR 0x80
+#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
+ SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
+
+#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */
+#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_LVDS 0x02
+#define SIS_EXTERNAL_CHIP_TRUMPION 0x03
+#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
+#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05
+#define SIS310_EXTERNAL_CHIP_LVDS 0x02
+#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
+
+#define SIS_AGP_2X 0x20 /* CR48 */
+
+/* vbflags, private entries (others in sisfb.h) */
+#define VB_CONEXANT 0x00000800 /* 661 series only */
+#define VB_TRUMPION VB_CONEXANT /* 300 series only */
+#define VB_302ELV 0x00004000
+#define VB_301 0x00100000 /* Video bridge type */
+#define VB_301B 0x00200000
+#define VB_302B 0x00400000
+#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */
+#define VB_LVDS 0x01000000
+#define VB_CHRONTEL 0x02000000
+#define VB_301LV 0x04000000
+#define VB_302LV 0x08000000
+#define VB_301C 0x10000000
+
+#define VB_SISBRIDGE (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
+#define VB_VIDEOBRIDGE (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
+
+enum _SIS_LCD_TYPE {
+ LCD_INVALID = 0,
+ LCD_800x600,
+ LCD_1024x768,
+ LCD_1280x1024,
+ LCD_1280x960,
+ LCD_640x480,
+ LCD_1600x1200,
+ LCD_1920x1440,
+ LCD_2048x1536,
+ LCD_320x240, /* FSTN */
+ LCD_1400x1050,
+ LCD_1152x864,
+ LCD_1152x768,
+ LCD_1280x768,
+ LCD_1024x600,
+ LCD_320x240_2, /* DSTN */
+ LCD_320x240_3, /* DSTN */
+ LCD_848x480,
+ LCD_1280x800,
+ LCD_1680x1050,
+ LCD_1280x720,
+ LCD_1280x854,
+ LCD_CUSTOM,
+ LCD_UNKNOWN
+};
+
+/* End code taken from Linux kernel 3.18.5 */
+
+/* coreboot <--> kernel code interface */
+#define __iomem
+#define SISIOMEMTYPE
+typedef unsigned long SISIOADDRESS;
+typedef u64 phys_addr_t;
+#define pci_dev device
+
+#define SZ_16M 0x01000000
+
+#define min_t(type, x, y) ({ \
+ type __min1 = (x); \
+ type __min2 = (y); \
+ __min1 < __min2 ? __min1 : __min2; })
+
+#define dev_info(dev, format, arg...) printk(BIOS_INFO, "XGI VGA: " format, ##arg)
+#define dev_dbg(dev, format, arg...) printk(BIOS_DEBUG, "XGI VGA: " format, ##arg)
+#define dev_err(dev, format, arg...) printk(BIOS_ERR, "XGI VGA: " format, ##arg)
+
+#define pr_info(format, arg...) printk(BIOS_INFO, "XGI VGA: " format, ##arg)
+#define pr_debug(format, arg...) printk(BIOS_INFO, "XGI VGA: " format, ##arg)
+#define pr_err(format, arg...) printk(BIOS_ERR, "XGI VGA: " format, ##arg)
+
+static inline void writel(u32 val, volatile void *addr) {
+ *(u32*)addr = val;
+}
+
+static inline u32 readl(const volatile void *addr) {
+ return *(u32*)addr;
+}
+
+static inline int pci_read_config_dword(struct pci_dev *dev, int where,
+ u32 *val)
+{
+ *val = pci_read_config32(dev, where);
+ return 0;
+}
+
+static inline int pci_read_config_byte(struct pci_dev *dev, int where,
+ u8 *val)
+{
+ *val = pci_read_config8(dev, where);
+ return 0;
+}
+
+static inline struct resource* resource_at_bar(struct pci_dev *dev, u8 bar) {
+ struct resource *res = dev->resource_list;
+ int i;
+ for (i = 0; i < bar; i++) {
+ res = res->next;
+ if (res == NULL)
+ return NULL;
+ }
+
+ return res;
+}
+
+static inline resource_t pci_resource_len(struct pci_dev *dev, u8 bar) {
+ struct resource *res = resource_at_bar(dev, bar);
+ if (res)
+ return res->size;
+ else
+ return 0;
+}
+
+static inline resource_t pci_resource_start(struct pci_dev *dev, u8 bar) {
+ struct resource *res = resource_at_bar(dev, bar);
+ if (res)
+ return res->base;
+ else
+ return 0;
+}
+
+struct xgifb_video_info *pci_get_drvdata(struct pci_dev *pdev);
+void pci_set_drvdata(struct pci_dev *pdev, struct xgifb_video_info *data);
+
+int xgifb_probe(struct pci_dev *pdev, struct xgifb_video_info *xgifb_info);
+int xgifb_modeset(struct pci_dev *pdev, struct xgifb_video_info *xgifb_info);
+
+#endif \ No newline at end of file
diff --git a/src/drivers/xgi/z9s/Kconfig b/src/drivers/xgi/z9s/Kconfig
new file mode 100644
index 0000000000..bae03d718a
--- /dev/null
+++ b/src/drivers/xgi/z9s/Kconfig
@@ -0,0 +1,14 @@
+config DRIVERS_XGI_Z9S
+ bool
+
+if DRIVERS_XGI_Z9S
+
+config DEVICE_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select DRIVERS_XGI_Z79_COMMON
+
+config NATIVE_VGA_INIT_USE_EDID
+ bool
+ default n
+
+endif # DRIVERS_XGI_Z9S
diff --git a/src/drivers/xgi/z9s/Makefile.inc b/src/drivers/xgi/z9s/Makefile.inc
new file mode 100644
index 0000000000..c7ee85c2a5
--- /dev/null
+++ b/src/drivers/xgi/z9s/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_XGI_Z9S) += z9s.c \ No newline at end of file
diff --git a/src/drivers/xgi/z9s/z9s.c b/src/drivers/xgi/z9s/z9s.c
new file mode 100644
index 0000000000..095489ed8c
--- /dev/null
+++ b/src/drivers/xgi/z9s/z9s.c
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <delay.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/io.h>
+#include <edid.h>
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+#include "../common/xgi_coreboot.h"
+#include "../common/XGIfb.h"
+
+static void xgi_z9s_init(struct device *dev)
+{
+ u8 ret;
+ struct xgifb_video_info *xgifb_info;
+
+ printk(BIOS_INFO, "XGI Z9s: initializing video device\n");
+ xgifb_info = malloc(sizeof(*xgifb_info));
+ ret = xgifb_probe(dev, xgifb_info);
+ if (!ret)
+ xgifb_modeset(dev, xgifb_info);
+ free(xgifb_info);
+}
+
+static struct device_operations xgi_z9s_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = xgi_z9s_init,
+ .scan_bus = 0,
+};
+
+static const struct pci_driver xgi_z9s_driver __pci_driver = {
+ .ops = &xgi_z9s_ops,
+ .vendor = PCI_VENDOR_ID_XGI,
+ .device = PCI_DEVICE_ID_XGI_20,
+};