]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
staging: xgifb: vb_init: move functions to avoid forward declarations
authorAaro Koskinen <aaro.koskinen@iki.fi>
Sun, 13 Mar 2011 10:26:06 +0000 (12:26 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 14 Mar 2011 18:52:24 +0000 (11:52 -0700)
Move functions to avoid forward declarations.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/xgifb/vb_init.c

index 4bbcff6aedfe49f33046349da92a7e9f5e6f01d8..7b8e00defd5079dcfc1596959d0af77f0e9982ea 100644 (file)
@@ -37,1623 +37,1604 @@ static unsigned short XGINew_DDRDRAM_TYPE20[12][5] = {
        { 2, 12,  9,  8, 0x35},
        { 2, 12,  8,  4, 0x31} };
 
-static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *, struct vb_device_info *);
-static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
-static void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension,
-                                     unsigned long, struct vb_device_info *);
-static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
-                                    struct vb_device_info *pVBInfo);
-
-static int XGINew_DDRSizing340(struct xgi_hw_device_info *, struct vb_device_info *);
-static int      XGINew_RAMType;                /*int      ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
-static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo);
-static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo);
-static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
-static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
-static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo);
-static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
-static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo);
-static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
+static int XGINew_RAMType;
 
 static void DelayUS(unsigned long MicroSeconds)
 {
        udelay(MicroSeconds);
 }
 
-unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension)
+static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
+                                       struct vb_device_info *pVBInfo)
 {
-       struct vb_device_info VBINF;
-       struct vb_device_info *pVBInfo = &VBINF;
-       unsigned char i, temp = 0, temp1;
-       /* VBIOSVersion[5]; */
-       volatile unsigned char *pVideoMemory;
-
-       /* unsigned long j, k; */
-
-       unsigned long Temp;
+       unsigned char data, temp;
 
-       pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+       if (HwDeviceExtension->jChipType < XG20) {
+               if (*pVBInfo->pSoftSetting & SoftDRAMType) {
+                       data = *pVBInfo->pSoftSetting & 0x07;
+                       return data;
+               } else {
+                       data = XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02;
 
-       pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+                       if (data == 0)
+                               data = (XGINew_GetReg1(pVBInfo->P3c4, 0x3A) & 0x02) >> 1;
 
-       pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
+                       return data;
+               }
+       } else if (HwDeviceExtension->jChipType == XG27) {
+               if (*pVBInfo->pSoftSetting & SoftDRAMType) {
+                       data = *pVBInfo->pSoftSetting & 0x07;
+                       return data;
+               }
+               temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3B);
 
-       pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
+               if ((temp & 0x88) == 0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+                       data = 0; /* DDR */
+               else
+                       data = 1; /* DDRII */
+               return data;
+       } else if (HwDeviceExtension->jChipType == XG21) {
+               XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */
+               DelayUS(800);
+               XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */
+               temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */
+               /* HOTPLUG_SUPPORT */
+               /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */
+               if (temp & 0x01) /* DVI read GPIOH */
+                       data = 1; /* DDRII */
+               else
+                       data = 0; /* DDR */
+               /* ~HOTPLUG_SUPPORT */
+               XGINew_SetRegOR(pVBInfo->P3d4, 0xB4, 0x02);
+               return data;
+       } else {
+               data = XGINew_GetReg1(pVBInfo->P3d4, 0x97) & 0x01;
 
-       /* Newdebugcode(0x99); */
+               if (data == 1)
+                       data++;
 
+               return data;
+       }
+}
 
-       /* if (pVBInfo->ROMAddr == 0) */
-       /* return(0); */
+static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
+{
+       XGINew_SetReg1(P3c4, 0x18, 0x01);
+       XGINew_SetReg1(P3c4, 0x19, 0x20);
+       XGINew_SetReg1(P3c4, 0x16, 0x00);
+       XGINew_SetReg1(P3c4, 0x16, 0x80);
 
-       if (pVBInfo->FBAddr == NULL) {
-               printk("\n pVBInfo->FBAddr == 0 ");
-               return 0;
-       }
-       printk("1");
-       if (pVBInfo->BaseAddr == 0) {
-               printk("\npVBInfo->BaseAddr == 0 ");
-               return 0;
+       if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */
+               DelayUS(3000); /* Delay 67 x 3 Delay15us */
+               XGINew_SetReg1(P3c4, 0x18, 0x00);
+               XGINew_SetReg1(P3c4, 0x19, 0x20);
+               XGINew_SetReg1(P3c4, 0x16, 0x00);
+               XGINew_SetReg1(P3c4, 0x16, 0x80);
        }
-       printk("2");
 
-       XGINew_SetReg3((pVBInfo->BaseAddr + 0x12), 0x67); /* 3c2 <- 67 ,ynlai */
-
-       pVBInfo->ISXPDOS = 0;
-       printk("3");
+       DelayUS(60);
+       XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+       XGINew_SetReg1(P3c4, 0x19, 0x01);
+       XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]);
+       XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]);
+       DelayUS(1000);
+       XGINew_SetReg1(P3c4, 0x1B, 0x03);
+       DelayUS(500);
+       XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+       XGINew_SetReg1(P3c4, 0x19, 0x00);
+       XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[2]);
+       XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[3]);
+       XGINew_SetReg1(P3c4, 0x1B, 0x00);
+}
 
-       printk("4");
+static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension,
+               struct vb_device_info *pVBInfo)
+{
 
-       /* VBIOSVersion[4] = 0x0; */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A);
 
-       /* 09/07/99 modify by domao */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30);
 
-       pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
-       pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
-       pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
-       pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
-       pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
-       pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
-       pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
-       pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
-       pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
-       pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
-       pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
-       pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
-       pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
-       pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
-       pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
-       pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
-       pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
-       printk("5");
+       /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
+       /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
+       if (HwDeviceExtension->jChipType == XG42) {
+               if ((pVBInfo->MCLKData[XGINew_RAMType].SR28 == 0x1C)
+                               && (pVBInfo->MCLKData[XGINew_RAMType].SR29 == 0x01)
+                               && (((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x1C)
+                                               && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))
+                                       || ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22)
+                                               && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))))
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
+       }
+}
 
-       if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
-               XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
+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;
+       XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+       XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
 
-       InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+       /* Set Double Frequency */
+       /* XGINew_SetReg1(P3d4, 0x97, 0x11); *//* CR97 */
+       XGINew_SetReg1(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */
 
-       /* ReadVBIOSData */
-       ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
+       DelayUS(200);
 
-       /* 1.Openkey */
-       XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
-       printk("6");
+       XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */
+       XGINew_SetReg1(P3c4, 0x19, 0x80); /* Set SR19 */
+       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+       DelayUS(15);
+       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+       DelayUS(15);
 
-       /* GetXG21Sense (GPIO) */
-       if (HwDeviceExtension->jChipType == XG21)
-               XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo);
+       XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */
+       XGINew_SetReg1(P3c4, 0x19, 0xC0); /* Set SR19 */
+       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+       DelayUS(15);
+       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+       DelayUS(15);
 
-       if (HwDeviceExtension->jChipType == XG27)
-               XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo);
+       XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */
+       XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */
+       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+       DelayUS(30);
+       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+       DelayUS(15);
 
-       printk("7");
+       XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */
+       XGINew_SetReg1(P3c4, 0x19, 0x0A); /* Set SR19 */
+       XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
+       DelayUS(30);
+       XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
+       XGINew_SetReg1(P3c4, 0x16, 0x80); /* Set SR16 */
+       /* DelayUS(15); */
 
-       /* 2.Reset Extended register */
+       XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B */
+       DelayUS(60);
+       XGINew_SetReg1(P3c4, 0x1B, 0x00); /* Set SR1B */
 
-       for (i = 0x06; i < 0x20; i++)
-               XGINew_SetReg1(pVBInfo->P3c4, i, 0);
+       XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */
+       XGINew_SetReg1(P3c4, 0x19, 0x08); /* Set SR19 */
+       XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
 
-       for (i = 0x21; i <= 0x27; i++)
-               XGINew_SetReg1(pVBInfo->P3c4, i, 0);
+       DelayUS(30);
+       XGINew_SetReg1(P3c4, 0x16, 0x83); /* Set SR16 */
+       DelayUS(15);
 
-       /* for(i = 0x06; i <= 0x27; i++) */
-       /* XGINew_SetReg1(pVBInfo->P3c4, i, 0); */
+       XGINew_SetReg1(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */
+       XGINew_SetReg1(P3c4, 0x19, 0x46); /* Set SR19 */
+       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+       DelayUS(30);
+       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+       DelayUS(15);
 
-       printk("8");
+       XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */
+       XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */
+       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+       DelayUS(30);
+       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+       DelayUS(15);
 
-       if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) {
-               for (i = 0x31; i <= 0x3B; i++)
-                       XGINew_SetReg1(pVBInfo->P3c4, i, 0);
-       } else {
-               for (i = 0x31; i <= 0x3D; i++)
-                       XGINew_SetReg1(pVBInfo->P3c4, i, 0);
-       }
-       printk("9");
+       XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */
+       DelayUS(200);
 
-       if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
-               XGINew_SetReg1(pVBInfo->P3c4, 0x3B, 0xC0);
+}
 
-       /* for (i = 0x30; i <= 0x3F; i++) */
-       /* XGINew_SetReg1(pVBInfo->P3d4, i, 0); */
+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;
 
-       for (i = 0x79; i <= 0x7C; i++)
-               XGINew_SetReg1(pVBInfo->P3d4, i, 0); /* shampoo 0208 */
+       XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+       XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
 
-       printk("10");
+       XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */
 
-       if (HwDeviceExtension->jChipType >= XG20)
-               XGINew_SetReg1(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97);
+       DelayUS(200);
+       XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */
+       XGINew_SetReg1(P3c4, 0x19, 0x80);
+       XGINew_SetReg1(P3c4, 0x16, 0x05);
+       XGINew_SetReg1(P3c4, 0x16, 0x85);
 
-       /* 3.SetMemoryClock
-
-        if (HwDeviceExtension->jChipType >= XG40)
-        XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
-
-        if (HwDeviceExtension->jChipType < XG40)
-        XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);  */
-
-       printk("11");
+       XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */
+       XGINew_SetReg1(P3c4, 0x19, 0xC0);
+       XGINew_SetReg1(P3c4, 0x16, 0x05);
+       XGINew_SetReg1(P3c4, 0x16, 0x85);
 
-       /* 4.SetDefExt1Regs begin */
-       XGINew_SetReg1(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07);
-       if (HwDeviceExtension->jChipType == XG27) {
-               XGINew_SetReg1(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40);
-               XGINew_SetReg1(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41);
-       }
-       XGINew_SetReg1(pVBInfo->P3c4, 0x11, 0x0F);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F);
-       /* XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0x20); */
-       XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
-       XGINew_SetReg1(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */
-       if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */
-               XGINew_SetReg1(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36);
+       XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */
+       XGINew_SetReg1(P3c4, 0x19, 0x40);
+       XGINew_SetReg1(P3c4, 0x16, 0x05);
+       XGINew_SetReg1(P3c4, 0x16, 0x85);
 
-       /* SR11 = 0x0F; */
-       /* XGINew_SetReg1(pVBInfo->P3c4, 0x11, SR11); */
+       /* XGINew_SetReg1(P3c4, 0x18, 0x52); */ /* MRS1 */
+       XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
+       XGINew_SetReg1(P3c4, 0x19, 0x02);
+       XGINew_SetReg1(P3c4, 0x16, 0x05);
+       XGINew_SetReg1(P3c4, 0x16, 0x85);
 
-       printk("12");
+       DelayUS(15);
+       XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */
+       DelayUS(30);
+       XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */
+       DelayUS(100);
 
-       if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
-               /* Set AGP Rate */
-               /*
-               temp1 = XGINew_GetReg1(pVBInfo->P3c4, 0x3B);
-               temp1 &= 0x02;
-               if (temp1 == 0x02) {
-                       XGINew_SetReg4(0xcf8, 0x80000000);
-                       ChipsetID = XGINew_GetReg3(0x0cfc);
-                       XGINew_SetReg4(0xcf8, 0x8000002C);
-                       VendorID = XGINew_GetReg3(0x0cfc);
-                       VendorID &= 0x0000FFFF;
-                       XGINew_SetReg4(0xcf8, 0x8001002C);
-                       GraphicVendorID = XGINew_GetReg3(0x0cfc);
-                       GraphicVendorID &= 0x0000FFFF;
+       /* XGINew_SetReg1(P3c4 ,0x18, 0x52); */ /* MRS2 */
+       XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
+       XGINew_SetReg1(P3c4, 0x19, 0x00);
+       XGINew_SetReg1(P3c4, 0x16, 0x05);
+       XGINew_SetReg1(P3c4, 0x16, 0x85);
 
-                       if (ChipsetID == 0x7301039)
-                               XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x09);
+       DelayUS(200);
+}
 
-                       ChipsetID &= 0x0000FFFF;
+static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo)
+{
 
-                       if ((ChipsetID == 0x700E) || (ChipsetID == 0x1022) || (ChipsetID == 0x1106) || (ChipsetID == 0x10DE)) {
-                               if (ChipsetID == 0x1106) {
-                                       if ((VendorID == 0x1019) && (GraphicVendorID == 0x1019))
-                                               XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0D);
-                                       else
-                                               XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B);
-                               } else {
-                                       XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B);
-                               }
-                       }
-               }
-               */
+       XGINew_SetReg1(P3c4, 0x18, 0x01);
+       XGINew_SetReg1(P3c4, 0x19, 0x40);
+       XGINew_SetReg1(P3c4, 0x16, 0x00);
+       XGINew_SetReg1(P3c4, 0x16, 0x80);
+       DelayUS(60);
 
-               printk("13");
+       XGINew_SetReg1(P3c4, 0x18, 0x00);
+       XGINew_SetReg1(P3c4, 0x19, 0x40);
+       XGINew_SetReg1(P3c4, 0x16, 0x00);
+       XGINew_SetReg1(P3c4, 0x16, 0x80);
+       DelayUS(60);
+       XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+       /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
+       XGINew_SetReg1(P3c4, 0x19, 0x01);
+       XGINew_SetReg1(P3c4, 0x16, 0x03);
+       XGINew_SetReg1(P3c4, 0x16, 0x83);
+       DelayUS(1000);
+       XGINew_SetReg1(P3c4, 0x1B, 0x03);
+       DelayUS(500);
+       /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
+       XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+       XGINew_SetReg1(P3c4, 0x19, 0x00);
+       XGINew_SetReg1(P3c4, 0x16, 0x03);
+       XGINew_SetReg1(P3c4, 0x16, 0x83);
+       XGINew_SetReg1(P3c4, 0x1B, 0x00);
+}
 
-               if (HwDeviceExtension->jChipType >= XG40) {
-                       /* Set AGP customize registers (in SetDefAGPRegs) Start */
-                       for (i = 0x47; i <= 0x4C; i++)
-                               XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]);
+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;
 
-                       for (i = 0x70; i <= 0x71; i++)
-                               XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]);
+       if (HwDeviceExtension->jChipType >= XG20) {
+               XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
+               XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+               XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+               XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
 
-                       for (i = 0x74; i <= 0x77; i++)
-                               XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]);
-                       /* Set AGP customize registers (in SetDefAGPRegs) End */
-                       /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
-                       /*        XGINew_SetReg4(0xcf8 , 0x80000000); */
-                       /*        ChipsetID = XGINew_GetReg3(0x0cfc); */
-                       /*        if (ChipsetID == 0x25308086) */
-                       /*            XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */
+               XGINew_SetReg1(P3d4, 0x98, 0x01);
+               XGINew_SetReg1(P3d4, 0x9A, 0x02);
 
-                       HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */
-                       Temp >>= 20;
-                       Temp &= 0xF;
+               XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo);
+       } else {
+               XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
 
-                       if (Temp == 1)
-                               XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
+               switch (HwDeviceExtension->jChipType) {
+               case XG41:
+               case XG42:
+                       XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+                       XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+                       XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+                       break;
+               default:
+                       XGINew_SetReg1(P3d4, 0x82, 0x88);
+                       XGINew_SetReg1(P3d4, 0x86, 0x00);
+                       XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
+                       XGINew_SetReg1(P3d4, 0x86, 0x88);
+                       XGINew_GetReg1(P3d4, 0x86);
+                       XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]);
+                       XGINew_SetReg1(P3d4, 0x82, 0x77);
+                       XGINew_SetReg1(P3d4, 0x85, 0x00);
+                       XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+                       XGINew_SetReg1(P3d4, 0x85, 0x88);
+                       XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+                       XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+                       XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+                       break;
                }
-               printk("14");
 
-               if (HwDeviceExtension->jChipType < XG40)
-                       XGINew_SetReg1(pVBInfo->P3d4, 0x49, pVBInfo->CR49[0]);
-       } /* != XG20 */
+               XGINew_SetReg1(P3d4, 0x97, 0x00);
+               XGINew_SetReg1(P3d4, 0x98, 0x01);
+               XGINew_SetReg1(P3d4, 0x9A, 0x02);
+               XGINew_DDR1x_MRS_340(P3c4, pVBInfo);
+       }
+}
 
-       /* Set PCI */
-       XGINew_SetReg1(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]);
-       printk("15");
+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;
 
-       if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
-               /* Set VB */
-               XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
-               XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */
-               XGINew_SetReg1(pVBInfo->Part1Port, 0x00, 0x00);
-               temp1 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */
-               temp = (unsigned char) ((temp1 >> 4) & 0x0F);
+       /* keep following setting sequence, each setting in the same reg insert idle */
+       XGINew_SetReg1(P3d4, 0x82, 0x77);
+       XGINew_SetReg1(P3d4, 0x86, 0x00);
+       XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
+       XGINew_SetReg1(P3d4, 0x86, 0x88);
+       XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
+       XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+       XGINew_SetReg1(P3d4, 0x82, 0x77);
+       XGINew_SetReg1(P3d4, 0x85, 0x00);
+       XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+       XGINew_SetReg1(P3d4, 0x85, 0x88);
+       XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+       XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+       if (HwDeviceExtension->jChipType == XG27)
+               XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+       else
+               XGINew_SetReg1(P3d4, 0x82, 0xA8); /* CR82 */
 
-               XGINew_SetReg1(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2));
+       XGINew_SetReg1(P3d4, 0x98, 0x01);
+       XGINew_SetReg1(P3d4, 0x9A, 0x02);
+       if (HwDeviceExtension->jChipType == XG27)
+               XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo);
+       else
+               XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo);
+}
 
-               printk("16");
+static void XGINew_SetDRAMDefaultRegister340(
+               struct xgi_hw_device_info *HwDeviceExtension,
+               unsigned long Port, struct vb_device_info *pVBInfo)
+{
+       unsigned char temp, temp1, temp2, temp3, i, j, k;
 
-               XGINew_SetReg1(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
-       } /* != XG20 */
+       unsigned long P3d4 = Port, P3c4 = Port - 0x10;
 
-       XGINew_SetReg1(pVBInfo->P3c4, 0x27, 0x1F);
+       XGINew_SetReg1(P3d4, 0x6D, pVBInfo->CR40[8][XGINew_RAMType]);
+       XGINew_SetReg1(P3d4, 0x68, pVBInfo->CR40[5][XGINew_RAMType]);
+       XGINew_SetReg1(P3d4, 0x69, pVBInfo->CR40[6][XGINew_RAMType]);
+       XGINew_SetReg1(P3d4, 0x6A, pVBInfo->CR40[7][XGINew_RAMType]);
 
-       if ((HwDeviceExtension->jChipType == XG42)
-                       && XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { /* Not DDR */
-               XGINew_SetReg1(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40);
-               XGINew_SetReg1(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01);
-       } else {
-               XGINew_SetReg1(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31);
-               XGINew_SetReg1(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32);
+       temp2 = 0;
+       for (i = 0; i < 4; i++) {
+               temp = pVBInfo->CR6B[XGINew_RAMType][i]; /* CR6B DQS fine tune delay */
+               for (j = 0; j < 4; j++) {
+                       temp1 = ((temp >> (2 * j)) & 0x03) << 2;
+                       temp2 |= temp1;
+                       XGINew_SetReg1(P3d4, 0x6B, temp2);
+                       XGINew_GetReg1(P3d4, 0x6B); /* Insert read command for delay */
+                       temp2 &= 0xF0;
+                       temp2 += 0x10;
+               }
        }
-       XGINew_SetReg1(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33);
-       printk("17");
 
-       /*
-        if (HwDeviceExtension->jChipType >= XG40)
-        SetPowerConsume (HwDeviceExtension, pVBInfo->P3c4);    */
-
-       if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
-               if (XGI_BridgeIsOn(pVBInfo) == 1) {
-                       if (pVBInfo->IF_DEF_LVDS == 0) {
-                               XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1C);
-                               XGINew_SetReg1(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D);
-                               XGINew_SetReg1(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E);
-                               XGINew_SetReg1(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10);
-                               XGINew_SetReg1(pVBInfo->Part4Port, 0x0F, 0x3F);
-                       }
-
-                       XGI_LockCRT2(HwDeviceExtension, pVBInfo);
+       temp2 = 0;
+       for (i = 0; i < 4; i++) {
+               temp = pVBInfo->CR6E[XGINew_RAMType][i]; /* CR6E DQM fine tune delay */
+               for (j = 0; j < 4; j++) {
+                       temp1 = ((temp >> (2 * j)) & 0x03) << 2;
+                       temp2 |= temp1;
+                       XGINew_SetReg1(P3d4, 0x6E, temp2);
+                       XGINew_GetReg1(P3d4, 0x6E); /* Insert read command for delay */
+                       temp2 &= 0xF0;
+                       temp2 += 0x10;
                }
-       } /* != XG20 */
-       printk("18");
-
-       if (HwDeviceExtension->jChipType < XG40)
-               XGINew_SetReg1(pVBInfo->P3d4, 0x83, 0x00);
-       printk("181");
-
-       printk("182");
+       }
 
-       XGI_SenseCRT1(pVBInfo);
+       temp3 = 0;
+       for (k = 0; k < 4; k++) {
+               XGINew_SetRegANDOR(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */
+               temp2 = 0;
+               for (i = 0; i < 8; i++) {
+                       temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i]; /* CR6F DQ fine tune delay */
+                       for (j = 0; j < 4; j++) {
+                               temp1 = (temp >> (2 * j)) & 0x03;
+                               temp2 |= temp1;
+                               XGINew_SetReg1(P3d4, 0x6F, temp2);
+                               XGINew_GetReg1(P3d4, 0x6F); /* Insert read command for delay */
+                               temp2 &= 0xF8;
+                               temp2 += 0x08;
+                       }
+               }
+               temp3 += 0x01;
+       }
 
-       printk("183");
-       /* XGINew_DetectMonitor(HwDeviceExtension); */
-       pVBInfo->IF_DEF_CH7007 = 0;
-       if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) {
-               printk("184");
-               XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */
-               printk("185");
+       XGINew_SetReg1(P3d4, 0x80, pVBInfo->CR40[9][XGINew_RAMType]); /* CR80 */
+       XGINew_SetReg1(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */
 
+       temp2 = 0x80;
+       temp = pVBInfo->CR89[XGINew_RAMType][0]; /* CR89 terminator type select */
+       for (j = 0; j < 4; j++) {
+               temp1 = (temp >> (2 * j)) & 0x03;
+               temp2 |= temp1;
+               XGINew_SetReg1(P3d4, 0x89, temp2);
+               XGINew_GetReg1(P3d4, 0x89); /* Insert read command for delay */
+               temp2 &= 0xF0;
+               temp2 += 0x10;
        }
-       if (HwDeviceExtension->jChipType == XG21) {
-               printk("186");
 
-               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
-               temp = GetXG21FPBits(pVBInfo);
-               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp);
-               printk("187");
+       temp = pVBInfo->CR89[XGINew_RAMType][1];
+       temp1 = temp & 0x03;
+       temp2 |= temp1;
+       XGINew_SetReg1(P3d4, 0x89, temp2);
 
-       }
-       if (HwDeviceExtension->jChipType == XG27) {
-               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
-               temp = GetXG27FPBits(pVBInfo);
-               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp);
-       }
-       printk("19");
+       temp = pVBInfo->CR40[3][XGINew_RAMType];
+       temp1 = temp & 0x0F;
+       temp2 = (temp >> 4) & 0x07;
+       temp3 = temp & 0x80;
+       XGINew_SetReg1(P3d4, 0x45, temp1); /* CR45 */
+       XGINew_SetReg1(P3d4, 0x99, temp2); /* CR99 */
+       XGINew_SetRegOR(P3d4, 0x40, temp3); /* CR40_D[7] */
+       XGINew_SetReg1(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */
 
-       if (HwDeviceExtension->jChipType >= XG40) {
-               if (HwDeviceExtension->jChipType >= XG40)
-                       XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+       if (HwDeviceExtension->jChipType == XG27)
+               XGINew_SetReg1(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */
 
-               XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo);
+       for (j = 0; j <= 6; j++)
+               XGINew_SetReg1(P3d4, (0x90 + j),
+                               pVBInfo->CR40[14 + j][XGINew_RAMType]); /* CR90 - CR96 */
 
-               printk("20");
-               XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo);
-               printk("21");
-       } /* XG40 */
+       for (j = 0; j <= 2; j++)
+               XGINew_SetReg1(P3d4, (0xC3 + j),
+                               pVBInfo->CR40[21 + j][XGINew_RAMType]); /* CRC3 - CRC5 */
 
-       printk("22");
+       for (j = 0; j < 2; j++)
+               XGINew_SetReg1(P3d4, (0x8A + j),
+                               pVBInfo->CR40[1 + j][XGINew_RAMType]); /* CR8A - CR8B */
 
-       /* SetDefExt2Regs begin */
-       /*
-       AGP = 1;
-       temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x3A);
-       temp &= 0x30;
-       if (temp == 0x30)
-               AGP = 0;
+       if ((HwDeviceExtension->jChipType == XG41) || (HwDeviceExtension->jChipType == XG42))
+               XGINew_SetReg1(P3d4, 0x8C, 0x87);
 
-       if (AGP == 0)
-               *pVBInfo->pSR21 &= 0xEF;
+       XGINew_SetReg1(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */
 
-       XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21);
-       if (AGP == 1)
-               *pVBInfo->pSR22 &= 0x20;
-       XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22);
-       */
-       /* base = 0x80000000; */
-       /* OutPortLong(0xcf8, base); */
-       /* Temp = (InPortLong(0xcfc) & 0xFFFF); */
-       /* if (Temp == 0x1039) { */
-       XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE));
-       /* } else { */
-       /*      XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */
-       /* } */
+       XGINew_SetReg1(P3d4, 0x83, 0x09); /* CR83 */
+       XGINew_SetReg1(P3d4, 0x87, 0x00); /* CR87 */
+       XGINew_SetReg1(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */
+       if (XGINew_RAMType) {
+               /* XGINew_SetReg1(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */
+               XGINew_SetReg1(P3c4, 0x17, 0x80); /* SR17 DDRII */
+               if (HwDeviceExtension->jChipType == XG27)
+                       XGINew_SetReg1(P3c4, 0x17, 0x02); /* SR17 DDRII */
 
-       XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21);
+       } else {
+               XGINew_SetReg1(P3c4, 0x17, 0x00); /* SR17 DDR */
+       }
+       XGINew_SetReg1(P3c4, 0x1A, 0x87); /* SR1A */
 
-       printk("23");
+       temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+       if (temp == 0) {
+               XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
+       } else {
+               XGINew_SetReg1(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */
+               XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
+       }
+       XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */
+}
 
-       XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo);
-       XGINew_SetModeScratch(HwDeviceExtension, pVBInfo);
+static void XGINew_SetDRAMSizingType(int index,
+               unsigned short DRAMTYPE_TABLE[][5],
+               struct vb_device_info *pVBInfo)
+{
+       unsigned short data;
 
-       printk("24");
+       data = DRAMTYPE_TABLE[index][4];
+       XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data);
+       DelayUS(15);
+       /* should delay 50 ns */
+}
 
-       XGINew_SetReg1(pVBInfo->P3d4, 0x8c, 0x87);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31);
-       printk("25");
+static unsigned short XGINew_SetDRAMSizeReg(int index,
+               unsigned short DRAMTYPE_TABLE[][5],
+               struct vb_device_info *pVBInfo)
+{
+       unsigned short data = 0, memsize = 0;
+       int RankSize;
+       unsigned char ChannelNo;
 
-       return 1;
-} /* end of init */
+       RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32;
+       data = XGINew_GetReg1(pVBInfo->P3c4, 0x13);
+       data &= 0x80;
 
-/* ============== alan ====================== */
+       if (data == 0x80)
+               RankSize *= 2;
 
-static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
-                                       struct vb_device_info *pVBInfo)
-{
-       unsigned char data, temp;
+       data = 0;
 
-       if (HwDeviceExtension->jChipType < XG20) {
-               if (*pVBInfo->pSoftSetting & SoftDRAMType) {
-                       data = *pVBInfo->pSoftSetting & 0x07;
-                       return data;
-               } else {
-                       data = XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02;
+       if (XGINew_ChannelAB == 3)
+               ChannelNo = 4;
+       else
+               ChannelNo = XGINew_ChannelAB;
 
-                       if (data == 0)
-                               data = (XGINew_GetReg1(pVBInfo->P3c4, 0x3A) & 0x02) >> 1;
+       if (ChannelNo * RankSize <= 256) {
+               while ((RankSize >>= 1) > 0)
+                       data += 0x10;
 
-                       return data;
-               }
-       } else if (HwDeviceExtension->jChipType == XG27) {
-               if (*pVBInfo->pSoftSetting & SoftDRAMType) {
-                       data = *pVBInfo->pSoftSetting & 0x07;
-                       return data;
-               }
-               temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3B);
+               memsize = data >> 4;
 
-               if ((temp & 0x88) == 0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
-                       data = 0; /* DDR */
-               else
-                       data = 1; /* DDRII */
-               return data;
-       } else if (HwDeviceExtension->jChipType == XG21) {
-               XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */
-               DelayUS(800);
-               XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */
-               temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */
-               /* HOTPLUG_SUPPORT */
-               /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */
-               if (temp & 0x01) /* DVI read GPIOH */
-                       data = 1; /* DDRII */
-               else
-                       data = 0; /* DDR */
-               /* ~HOTPLUG_SUPPORT */
-               XGINew_SetRegOR(pVBInfo->P3d4, 0xB4, 0x02);
-               return data;
-       } else {
-               data = XGINew_GetReg1(pVBInfo->P3d4, 0x97) & 0x01;
+               /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
+               XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
 
-               if (data == 1)
-                       data++;
+               /* data |= XGINew_ChannelAB << 2; */
+               /* data |= (XGINew_DataBusWidth / 64) << 1; */
+               /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */
 
-               return data;
+               /* should delay */
+               /* XGINew_SetDRAMModeRegister340(pVBInfo); */
        }
+       return memsize;
 }
 
-static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
+static unsigned short XGINew_SetDRAMSize20Reg(int index,
+               unsigned short DRAMTYPE_TABLE[][5],
+               struct vb_device_info *pVBInfo)
 {
-       XGINew_SetReg1(P3c4, 0x18, 0x01);
-       XGINew_SetReg1(P3c4, 0x19, 0x20);
-       XGINew_SetReg1(P3c4, 0x16, 0x00);
-       XGINew_SetReg1(P3c4, 0x16, 0x80);
-
-       if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */
-               DelayUS(3000); /* Delay 67 x 3 Delay15us */
-               XGINew_SetReg1(P3c4, 0x18, 0x00);
-               XGINew_SetReg1(P3c4, 0x19, 0x20);
-               XGINew_SetReg1(P3c4, 0x16, 0x00);
-               XGINew_SetReg1(P3c4, 0x16, 0x80);
-       }
+       unsigned short data = 0, memsize = 0;
+       int RankSize;
+       unsigned char ChannelNo;
 
-       DelayUS(60);
-       XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
-       XGINew_SetReg1(P3c4, 0x19, 0x01);
-       XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]);
-       XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]);
-       DelayUS(1000);
-       XGINew_SetReg1(P3c4, 0x1B, 0x03);
-       DelayUS(500);
-       XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
-       XGINew_SetReg1(P3c4, 0x19, 0x00);
-       XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[2]);
-       XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[3]);
-       XGINew_SetReg1(P3c4, 0x1B, 0x00);
-}
+       RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8;
+       data = XGINew_GetReg1(pVBInfo->P3c4, 0x13);
+       data &= 0x80;
 
-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;
-       XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
-       XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
+       if (data == 0x80)
+               RankSize *= 2;
 
-       /* Set Double Frequency */
-       /* XGINew_SetReg1(P3d4, 0x97, 0x11); *//* CR97 */
-       XGINew_SetReg1(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */
+       data = 0;
 
-       DelayUS(200);
+       if (XGINew_ChannelAB == 3)
+               ChannelNo = 4;
+       else
+               ChannelNo = XGINew_ChannelAB;
 
-       XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */
-       XGINew_SetReg1(P3c4, 0x19, 0x80); /* Set SR19 */
-       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
-       DelayUS(15);
-       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
-       DelayUS(15);
+       if (ChannelNo * RankSize <= 256) {
+               while ((RankSize >>= 1) > 0)
+                       data += 0x10;
 
-       XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */
-       XGINew_SetReg1(P3c4, 0x19, 0xC0); /* Set SR19 */
-       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
-       DelayUS(15);
-       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
-       DelayUS(15);
+               memsize = data >> 4;
 
-       XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */
-       XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */
-       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
-       DelayUS(30);
-       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
-       DelayUS(15);
+               /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
+               XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
+               DelayUS(15);
 
-       XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */
-       XGINew_SetReg1(P3c4, 0x19, 0x0A); /* Set SR19 */
-       XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
-       DelayUS(30);
-       XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
-       XGINew_SetReg1(P3c4, 0x16, 0x80); /* Set SR16 */
-       /* DelayUS(15); */
+               /* data |= XGINew_ChannelAB << 2; */
+               /* data |= (XGINew_DataBusWidth / 64) << 1; */
+               /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */
 
-       XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B */
-       DelayUS(60);
-       XGINew_SetReg1(P3c4, 0x1B, 0x00); /* Set SR1B */
+               /* should delay */
+               /* XGINew_SetDRAMModeRegister340(pVBInfo); */
+       }
+       return memsize;
+}
 
-       XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */
-       XGINew_SetReg1(P3c4, 0x19, 0x08); /* Set SR19 */
-       XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
+static int XGINew_ReadWriteRest(unsigned short StopAddr,
+               unsigned short StartAddr, struct vb_device_info *pVBInfo)
+{
+       int i;
+       unsigned long Position = 0;
 
-       DelayUS(30);
-       XGINew_SetReg1(P3c4, 0x16, 0x83); /* Set SR16 */
-       DelayUS(15);
+       *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
 
-       XGINew_SetReg1(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */
-       XGINew_SetReg1(P3c4, 0x19, 0x46); /* Set SR19 */
-       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
-       DelayUS(30);
-       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
-       DelayUS(15);
+       for (i = StartAddr; i <= StopAddr; i++) {
+               Position = 1 << i;
+               *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
+       }
 
-       XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */
-       XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */
-       XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
-       DelayUS(30);
-       XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
-       DelayUS(15);
+       DelayUS(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
 
-       XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */
-       DelayUS(200);
+       Position = 0;
+
+       if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
+               return 0;
 
+       for (i = StartAddr; i <= StopAddr; i++) {
+               Position = 1 << i;
+               if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
+                       return 0;
+       }
+       return 1;
 }
 
-static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension,
-               unsigned long P3c4, struct vb_device_info *pVBInfo)
+static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
 {
-       unsigned long P3d4 = P3c4 + 0x10;
-
-       XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
-       XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
+       unsigned char data;
 
-       XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */
+       data = XGINew_GetReg1(pVBInfo->P3d4, 0x97);
 
-       DelayUS(200);
-       XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */
-       XGINew_SetReg1(P3c4, 0x19, 0x80);
-       XGINew_SetReg1(P3c4, 0x16, 0x05);
-       XGINew_SetReg1(P3c4, 0x16, 0x85);
+       if ((data & 0x10) == 0) {
+               data = XGINew_GetReg1(pVBInfo->P3c4, 0x39);
+               data = (data & 0x02) >> 1;
+               return data;
+       } else {
+               return data & 0x01;
+       }
+}
 
-       XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */
-       XGINew_SetReg1(P3c4, 0x19, 0xC0);
-       XGINew_SetReg1(P3c4, 0x16, 0x05);
-       XGINew_SetReg1(P3c4, 0x16, 0x85);
+static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension,
+               struct vb_device_info *pVBInfo)
+{
+       unsigned char data;
 
-       XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */
-       XGINew_SetReg1(P3c4, 0x19, 0x40);
-       XGINew_SetReg1(P3c4, 0x16, 0x05);
-       XGINew_SetReg1(P3c4, 0x16, 0x85);
+       switch (HwDeviceExtension->jChipType) {
+       case XG20:
+       case XG21:
+               data = XGINew_GetReg1(pVBInfo->P3d4, 0x97);
+               data = data & 0x01;
+               XGINew_ChannelAB = 1; /* XG20 "JUST" one channel */
 
-       /* XGINew_SetReg1(P3c4, 0x18, 0x52); */ /* MRS1 */
-       XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
-       XGINew_SetReg1(P3c4, 0x19, 0x02);
-       XGINew_SetReg1(P3c4, 0x16, 0x05);
-       XGINew_SetReg1(P3c4, 0x16, 0x85);
+               if (data == 0) { /* Single_32_16 */
 
-       DelayUS(15);
-       XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */
-       DelayUS(30);
-       XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */
-       DelayUS(100);
+                       if ((HwDeviceExtension->ulVideoMemorySize - 1)
+                                       > 0x1000000) {
 
-       /* XGINew_SetReg1(P3c4 ,0x18, 0x52); */ /* MRS2 */
-       XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
-       XGINew_SetReg1(P3c4, 0x19, 0x00);
-       XGINew_SetReg1(P3c4, 0x16, 0x05);
-       XGINew_SetReg1(P3c4, 0x16, 0x85);
+                               XGINew_DataBusWidth = 32; /* 32 bits */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
+                               DelayUS(15);
 
-       DelayUS(200);
-}
+                               if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                                       return;
 
-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->ulVideoMemorySize - 1) > 0x800000) {
+                                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */
+                                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
+                                       DelayUS(15);
 
-       if (HwDeviceExtension->jChipType >= XG20) {
-               XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
-               XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
-               XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
-               XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+                                       if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1)
+                                               return;
+                               }
+                       }
 
-               XGINew_SetReg1(P3d4, 0x98, 0x01);
-               XGINew_SetReg1(P3d4, 0x9A, 0x02);
+                       if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
+                               XGINew_DataBusWidth = 16; /* 16 bits */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41);
+                               DelayUS(15);
 
-               XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo);
-       } else {
-               XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
+                               if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+                                       return;
+                               else
+                                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31);
+                               DelayUS(15);
+                       }
 
-               switch (HwDeviceExtension->jChipType) {
-               case XG41:
-               case XG42:
-                       XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
-                       XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
-                       XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
-                       break;
-               default:
-                       XGINew_SetReg1(P3d4, 0x82, 0x88);
-                       XGINew_SetReg1(P3d4, 0x86, 0x00);
-                       XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
-                       XGINew_SetReg1(P3d4, 0x86, 0x88);
-                       XGINew_GetReg1(P3d4, 0x86);
-                       XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]);
-                       XGINew_SetReg1(P3d4, 0x82, 0x77);
-                       XGINew_SetReg1(P3d4, 0x85, 0x00);
-                       XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
-                       XGINew_SetReg1(P3d4, 0x85, 0x88);
-                       XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
-                       XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
-                       XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
-                       break;
-               }
+               } else { /* Dual_16_8 */
+                       if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
 
-               XGINew_SetReg1(P3d4, 0x97, 0x00);
-               XGINew_SetReg1(P3d4, 0x98, 0x01);
-               XGINew_SetReg1(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 */
-       XGINew_SetReg1(P3d4, 0x82, 0x77);
-       XGINew_SetReg1(P3d4, 0x86, 0x00);
-       XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
-       XGINew_SetReg1(P3d4, 0x86, 0x88);
-       XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
-       XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
-       XGINew_SetReg1(P3d4, 0x82, 0x77);
-       XGINew_SetReg1(P3d4, 0x85, 0x00);
-       XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
-       XGINew_SetReg1(P3d4, 0x85, 0x88);
-       XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
-       XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
-       if (HwDeviceExtension->jChipType == XG27)
-               XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
-       else
-               XGINew_SetReg1(P3d4, 0x82, 0xA8); /* CR82 */
-
-       XGINew_SetReg1(P3d4, 0x98, 0x01);
-       XGINew_SetReg1(P3d4, 0x9A, 0x02);
-       if (HwDeviceExtension->jChipType == XG27)
-               XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo);
-       else
-               XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo);
-}
-
-static void XGINew_SetDRAMDefaultRegister340(
-               struct xgi_hw_device_info *HwDeviceExtension,
-               unsigned long Port, struct vb_device_info *pVBInfo)
-{
-       unsigned char temp, temp1, temp2, temp3, i, j, k;
+                               XGINew_DataBusWidth = 16; /* 16 bits */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/
+                               DelayUS(15);
 
-       unsigned long P3d4 = Port, P3c4 = Port - 0x10;
+                               if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+                                       return;
 
-       XGINew_SetReg1(P3d4, 0x6D, pVBInfo->CR40[8][XGINew_RAMType]);
-       XGINew_SetReg1(P3d4, 0x68, pVBInfo->CR40[5][XGINew_RAMType]);
-       XGINew_SetReg1(P3d4, 0x69, pVBInfo->CR40[6][XGINew_RAMType]);
-       XGINew_SetReg1(P3d4, 0x6A, pVBInfo->CR40[7][XGINew_RAMType]);
+                               if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
+                                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
+                                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/
+                                       DelayUS(15);
 
-       temp2 = 0;
-       for (i = 0; i < 4; i++) {
-               temp = pVBInfo->CR6B[XGINew_RAMType][i]; /* CR6B DQS fine tune delay */
-               for (j = 0; j < 4; j++) {
-                       temp1 = ((temp >> (2 * j)) & 0x03) << 2;
-                       temp2 |= temp1;
-                       XGINew_SetReg1(P3d4, 0x6B, temp2);
-                       XGINew_GetReg1(P3d4, 0x6B); /* Insert read command for delay */
-                       temp2 &= 0xF0;
-                       temp2 += 0x10;
-               }
-       }
+                                       if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1)
+                                               return;
+                               }
+                       }
 
-       temp2 = 0;
-       for (i = 0; i < 4; i++) {
-               temp = pVBInfo->CR6E[XGINew_RAMType][i]; /* CR6E DQM fine tune delay */
-               for (j = 0; j < 4; j++) {
-                       temp1 = ((temp >> (2 * j)) & 0x03) << 2;
-                       temp2 |= temp1;
-                       XGINew_SetReg1(P3d4, 0x6E, temp2);
-                       XGINew_GetReg1(P3d4, 0x6E); /* Insert read command for delay */
-                       temp2 &= 0xF0;
-                       temp2 += 0x10;
-               }
-       }
+                       if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
+                               XGINew_DataBusWidth = 8; /* 8 bits */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/
+                               DelayUS(15);
 
-       temp3 = 0;
-       for (k = 0; k < 4; k++) {
-               XGINew_SetRegANDOR(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */
-               temp2 = 0;
-               for (i = 0; i < 8; i++) {
-                       temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i]; /* CR6F DQ fine tune delay */
-                       for (j = 0; j < 4; j++) {
-                               temp1 = (temp >> (2 * j)) & 0x03;
-                               temp2 |= temp1;
-                               XGINew_SetReg1(P3d4, 0x6F, temp2);
-                               XGINew_GetReg1(P3d4, 0x6F); /* Insert read command for delay */
-                               temp2 &= 0xF8;
-                               temp2 += 0x08;
+                               if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1)
+                                       return;
+                               else
+                                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
+                               DelayUS(15);
                        }
                }
-               temp3 += 0x01;
-       }
+               break;
 
-       XGINew_SetReg1(P3d4, 0x80, pVBInfo->CR40[9][XGINew_RAMType]); /* CR80 */
-       XGINew_SetReg1(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */
+       case XG27:
+               XGINew_DataBusWidth = 16; /* 16 bits */
+               XGINew_ChannelAB = 1; /* Single channel */
+               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/
+               break;
+       case XG41:
+               if (XGINew_CheckFrequence(pVBInfo) == 1) {
+                       XGINew_DataBusWidth = 32; /* 32 bits */
+                       XGINew_ChannelAB = 3; /* Quad Channel */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C);
 
-       temp2 = 0x80;
-       temp = pVBInfo->CR89[XGINew_RAMType][0]; /* CR89 terminator type select */
-       for (j = 0; j < 4; j++) {
-               temp1 = (temp >> (2 * j)) & 0x03;
-               temp2 |= temp1;
-               XGINew_SetReg1(P3d4, 0x89, temp2);
-               XGINew_GetReg1(P3d4, 0x89); /* Insert read command for delay */
-               temp2 &= 0xF0;
-               temp2 += 0x10;
-       }
+                       if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
+                               return;
 
-       temp = pVBInfo->CR89[XGINew_RAMType][1];
-       temp1 = temp & 0x03;
-       temp2 |= temp1;
-       XGINew_SetReg1(P3d4, 0x89, temp2);
+                       XGINew_ChannelAB = 2; /* Dual channels */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48);
 
-       temp = pVBInfo->CR40[3][XGINew_RAMType];
-       temp1 = temp & 0x0F;
-       temp2 = (temp >> 4) & 0x07;
-       temp3 = temp & 0x80;
-       XGINew_SetReg1(P3d4, 0x45, temp1); /* CR45 */
-       XGINew_SetReg1(P3d4, 0x99, temp2); /* CR99 */
-       XGINew_SetRegOR(P3d4, 0x40, temp3); /* CR40_D[7] */
-       XGINew_SetReg1(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
 
-       if (HwDeviceExtension->jChipType == XG27)
-               XGINew_SetReg1(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x49);
 
-       for (j = 0; j <= 6; j++)
-               XGINew_SetReg1(P3d4, (0x90 + j),
-                               pVBInfo->CR40[14 + j][XGINew_RAMType]); /* CR90 - CR96 */
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
 
-       for (j = 0; j <= 2; j++)
-               XGINew_SetReg1(P3d4, (0xC3 + j),
-                               pVBInfo->CR40[21 + j][XGINew_RAMType]); /* CRC3 - CRC5 */
+                       XGINew_ChannelAB = 3;
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C);
 
-       for (j = 0; j < 2; j++)
-               XGINew_SetReg1(P3d4, (0x8A + j),
-                               pVBInfo->CR40[1 + j][XGINew_RAMType]); /* CR8A - CR8B */
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
 
-       if ((HwDeviceExtension->jChipType == XG41) || (HwDeviceExtension->jChipType == XG42))
-               XGINew_SetReg1(P3d4, 0x8C, 0x87);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38);
 
-       XGINew_SetReg1(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */
+                       if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1)
+                               return;
+                       else
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x39);
+               } else { /* DDR */
+                       XGINew_DataBusWidth = 64; /* 64 bits */
+                       XGINew_ChannelAB = 2; /* Dual channels */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A);
 
-       XGINew_SetReg1(P3d4, 0x83, 0x09); /* CR83 */
-       XGINew_SetReg1(P3d4, 0x87, 0x00); /* CR87 */
-       XGINew_SetReg1(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */
-       if (XGINew_RAMType) {
-               /* XGINew_SetReg1(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */
-               XGINew_SetReg1(P3c4, 0x17, 0x80); /* SR17 DDRII */
-               if (HwDeviceExtension->jChipType == XG27)
-                       XGINew_SetReg1(P3c4, 0x17, 0x02); /* SR17 DDRII */
+                       if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1)
+                               return;
 
-       } else {
-               XGINew_SetReg1(P3c4, 0x17, 0x00); /* SR17 DDR */
-       }
-       XGINew_SetReg1(P3c4, 0x1A, 0x87); /* SR1A */
+                       XGINew_ChannelAB = 1; /* Single channels */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
 
-       temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
-       if (temp == 0) {
-               XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
-       } else {
-               XGINew_SetReg1(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */
-               XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
-       }
-       XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */
-}
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
 
-static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension,
-               struct vb_device_info *pVBInfo)
-{
-       unsigned short data;
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x53);
 
-       pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
-       pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
 
-       XGISetModeNew(HwDeviceExtension, 0x2e);
+                       XGINew_ChannelAB = 2; /* Dual channels */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A);
 
-       data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */
-       XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
 
-       /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); */
-       /* data |= 0x20 ; */
-       /* XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */
-       XGINew_DDRSizing340(HwDeviceExtension, pVBInfo);
-       data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */
-}
+                       XGINew_ChannelAB = 1; /* Single channels */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
 
-static void XGINew_SetDRAMSizingType(int index,
-               unsigned short DRAMTYPE_TABLE[][5],
-               struct vb_device_info *pVBInfo)
-{
-       unsigned short data;
+                       if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1)
+                               return;
+                       else
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x43);
+               }
 
-       data = DRAMTYPE_TABLE[index][4];
-       XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data);
-       DelayUS(15);
-       /* should delay 50 ns */
-}
+               break;
 
-static unsigned short XGINew_SetDRAMSizeReg(int index,
-               unsigned short DRAMTYPE_TABLE[][5],
-               struct vb_device_info *pVBInfo)
-{
-       unsigned short data = 0, memsize = 0;
-       int RankSize;
-       unsigned char ChannelNo;
-
-       RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32;
-       data = XGINew_GetReg1(pVBInfo->P3c4, 0x13);
-       data &= 0x80;
-
-       if (data == 0x80)
-               RankSize *= 2;
-
-       data = 0;
-
-       if (XGINew_ChannelAB == 3)
-               ChannelNo = 4;
-       else
-               ChannelNo = XGINew_ChannelAB;
+       case XG42:
+               /*
+                XG42 SR14 D[3] Reserve
+                D[2] = 1, Dual Channel
+                = 0, Single Channel
 
-       if (ChannelNo * RankSize <= 256) {
-               while ((RankSize >>= 1) > 0)
-                       data += 0x10;
+                It's Different from Other XG40 Series.
+                */
+               if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */
+                       XGINew_DataBusWidth = 32; /* 32 bits */
+                       XGINew_ChannelAB = 2; /* 2 Channel */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x44);
 
-               memsize = data >> 4;
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
 
-               /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
-               XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x34);
+                       if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+                               return;
 
-               /* data |= XGINew_ChannelAB << 2; */
-               /* data |= (XGINew_DataBusWidth / 64) << 1; */
-               /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */
+                       XGINew_ChannelAB = 1; /* Single Channel */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x40);
 
-               /* should delay */
-               /* XGINew_SetDRAMModeRegister340(pVBInfo); */
-       }
-       return memsize;
-}
+                       if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+                               return;
+                       else {
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30);
+                       }
+               } else { /* DDR */
+                       XGINew_DataBusWidth = 64; /* 64 bits */
+                       XGINew_ChannelAB = 1; /* 1 channels */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
 
-static unsigned short XGINew_SetDRAMSize20Reg(int index,
-               unsigned short DRAMTYPE_TABLE[][5],
-               struct vb_device_info *pVBInfo)
-{
-       unsigned short data = 0, memsize = 0;
-       int RankSize;
-       unsigned char ChannelNo;
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
+                       else {
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
+                       }
+               }
 
-       RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8;
-       data = XGINew_GetReg1(pVBInfo->P3c4, 0x13);
-       data &= 0x80;
+               break;
 
-       if (data == 0x80)
-               RankSize *= 2;
+       default: /* XG40 */
 
-       data = 0;
+               if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */
+                       XGINew_DataBusWidth = 32; /* 32 bits */
+                       XGINew_ChannelAB = 3;
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C);
 
-       if (XGINew_ChannelAB == 3)
-               ChannelNo = 4;
-       else
-               ChannelNo = XGINew_ChannelAB;
+                       if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
+                               return;
 
-       if (ChannelNo * RankSize <= 256) {
-               while ((RankSize >>= 1) > 0)
-                       data += 0x10;
+                       XGINew_ChannelAB = 2; /* 2 channels */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48);
 
-               memsize = data >> 4;
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+                               return;
 
-               /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
-               XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
-               DelayUS(15);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C);
 
-               /* data |= XGINew_ChannelAB << 2; */
-               /* data |= (XGINew_DataBusWidth / 64) << 1; */
-               /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */
+                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) {
+                               XGINew_ChannelAB = 3; /* 4 channels */
+                       } else {
+                               XGINew_ChannelAB = 2; /* 2 channels */
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38);
+                       }
+               } else { /* DDR */
+                       XGINew_DataBusWidth = 64; /* 64 bits */
+                       XGINew_ChannelAB = 2; /* 2 channels */
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A);
 
-               /* should delay */
-               /* XGINew_SetDRAMModeRegister340(pVBInfo); */
+                       if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) {
+                               return;
+                       } else {
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A);
+                       }
+               }
+               break;
        }
-       return memsize;
 }
 
-static int XGINew_ReadWriteRest(unsigned short StopAddr,
-               unsigned short StartAddr, struct vb_device_info *pVBInfo)
+static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension,
+               struct vb_device_info *pVBInfo)
 {
        int i;
-       unsigned long Position = 0;
-
-       *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
-
-       for (i = StartAddr; i <= StopAddr; i++) {
-               Position = 1 << i;
-               *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
-       }
+       unsigned short memsize, addr;
 
-       DelayUS(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */
+       XGINew_CheckChannel(HwDeviceExtension, pVBInfo);
 
-       Position = 0;
+       if (HwDeviceExtension->jChipType >= XG20) {
+               for (i = 0; i < 12; i++) {
+                       XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
+                       memsize = XGINew_SetDRAMSize20Reg(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
+                       if (memsize == 0)
+                               continue;
 
-       if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
-               return 0;
+                       addr = memsize + (XGINew_ChannelAB - 2) + 20;
+                       if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
+                               continue;
 
-       for (i = StartAddr; i <= StopAddr; i++) {
-               Position = 1 << i;
-               if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
-                       return 0;
-       }
-       return 1;
-}
+                       if (XGINew_ReadWriteRest(addr, 5, pVBInfo) == 1)
+                               return 1;
+               }
+       } else {
+               for (i = 0; i < 4; i++) {
+                       XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
+                       memsize = XGINew_SetDRAMSizeReg(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
 
-static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
-{
-       unsigned char data;
+                       if (memsize == 0)
+                               continue;
 
-       data = XGINew_GetReg1(pVBInfo->P3d4, 0x97);
+                       addr = memsize + (XGINew_ChannelAB - 2) + 20;
+                       if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
+                               continue;
 
-       if ((data & 0x10) == 0) {
-               data = XGINew_GetReg1(pVBInfo->P3c4, 0x39);
-               data = (data & 0x02) >> 1;
-               return data;
-       } else {
-               return data & 0x01;
+                       if (XGINew_ReadWriteRest(addr, 9, pVBInfo) == 1)
+                               return 1;
+               }
        }
+       return 0;
 }
 
-static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension,
+static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension,
                struct vb_device_info *pVBInfo)
 {
-       unsigned char data;
-
-       switch (HwDeviceExtension->jChipType) {
-       case XG20:
-       case XG21:
-               data = XGINew_GetReg1(pVBInfo->P3d4, 0x97);
-               data = data & 0x01;
-               XGINew_ChannelAB = 1; /* XG20 "JUST" one channel */
-
-               if (data == 0) { /* Single_32_16 */
-
-                       if ((HwDeviceExtension->ulVideoMemorySize - 1)
-                                       > 0x1000000) {
+       unsigned short data;
 
-                               XGINew_DataBusWidth = 32; /* 32 bits */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
-                               DelayUS(15);
+       pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+       pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
 
-                               if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                                       return;
+       XGISetModeNew(HwDeviceExtension, 0x2e);
 
-                               if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
-                                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */
-                                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
-                                       DelayUS(15);
+       data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */
+       XGI_DisplayOff(HwDeviceExtension, pVBInfo);
 
-                                       if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1)
-                                               return;
-                               }
-                       }
+       /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); */
+       /* data |= 0x20 ; */
+       /* XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */
+       XGINew_DDRSizing340(HwDeviceExtension, pVBInfo);
+       data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */
+}
 
-                       if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
-                               XGINew_DataBusWidth = 16; /* 16 bits */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41);
-                               DelayUS(15);
+static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo)
+{
+       volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
+       unsigned long i;
+       unsigned char j, k;
+       /* Volari customize data area end */
 
-                               if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
-                                       return;
-                               else
-                                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31);
-                               DelayUS(15);
+       if (ChipType == XG21) {
+               pVBInfo->IF_DEF_LVDS = 0;
+               if (pVideoMemory[0x65] & 0x1) {
+                       pVBInfo->IF_DEF_LVDS = 1;
+                       i = pVideoMemory[0x316] | (pVideoMemory[0x317] << 8);
+                       j = pVideoMemory[i - 1];
+                       if (j != 0xff) {
+                               k = 0;
+                               do {
+                                       pVBInfo->XG21_LVDSCapList[k].LVDS_Capability
+                                               = pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].LVDSHT
+                                               = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].LVDSVT
+                                               = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].LVDSHDE
+                                               = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].LVDSVDE
+                                               = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].LVDSHFP
+                                               = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].LVDSVFP
+                                               = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC
+                                               = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC
+                                               = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
+                                       pVBInfo->XG21_LVDSCapList[k].VCLKData1
+                                               = pVideoMemory[i + 18];
+                                       pVBInfo->XG21_LVDSCapList[k].VCLKData2
+                                               = pVideoMemory[i + 19];
+                                       pVBInfo->XG21_LVDSCapList[k].PSC_S1
+                                               = pVideoMemory[i + 20];
+                                       pVBInfo->XG21_LVDSCapList[k].PSC_S2
+                                               = pVideoMemory[i + 21];
+                                       pVBInfo->XG21_LVDSCapList[k].PSC_S3
+                                               = pVideoMemory[i + 22];
+                                       pVBInfo->XG21_LVDSCapList[k].PSC_S4
+                                               = pVideoMemory[i + 23];
+                                       pVBInfo->XG21_LVDSCapList[k].PSC_S5
+                                               = pVideoMemory[i + 24];
+                                       i += 25;
+                                       j--;
+                                       k++;
+                               } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList) / sizeof(struct XGI21_LVDSCapStruct))));
+                       } else {
+                               pVBInfo->XG21_LVDSCapList[0].LVDS_Capability
+                                               = pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].LVDSHT
+                                               = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].LVDSVT
+                                               = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].LVDSHDE
+                                               = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].LVDSVDE
+                                               = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].LVDSHFP
+                                               = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].LVDSVFP
+                                               = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC
+                                               = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC
+                                               = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
+                               pVBInfo->XG21_LVDSCapList[0].VCLKData1
+                                               = pVideoMemory[i + 18];
+                               pVBInfo->XG21_LVDSCapList[0].VCLKData2
+                                               = pVideoMemory[i + 19];
+                               pVBInfo->XG21_LVDSCapList[0].PSC_S1
+                                               = pVideoMemory[i + 20];
+                               pVBInfo->XG21_LVDSCapList[0].PSC_S2
+                                               = pVideoMemory[i + 21];
+                               pVBInfo->XG21_LVDSCapList[0].PSC_S3
+                                               = pVideoMemory[i + 22];
+                               pVBInfo->XG21_LVDSCapList[0].PSC_S4
+                                               = pVideoMemory[i + 23];
+                               pVBInfo->XG21_LVDSCapList[0].PSC_S5
+                                               = pVideoMemory[i + 24];
                        }
+               }
+       }
+}
 
-               } else { /* Dual_16_8 */
-                       if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
-
-                               XGINew_DataBusWidth = 16; /* 16 bits */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/
-                               DelayUS(15);
-
-                               if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
-                                       return;
+static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
+               struct vb_device_info *pVBInfo)
+{
+       unsigned short tempbx = 0, temp, tempcx, CR3CData;
 
-                               if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
-                                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
-                                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/
-                                       DelayUS(15);
+       temp = XGINew_GetReg1(pVBInfo->P3d4, 0x32);
 
-                                       if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1)
-                                               return;
-                               }
-                       }
+       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);
+       }
 
-                       if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
-                               XGINew_DataBusWidth = 8; /* 8 bits */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/
-                               DelayUS(15);
+       tempcx = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
+       tempcx |= (XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8);
 
-                               if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1)
-                                       return;
-                               else
-                                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
-                               DelayUS(15);
-                       }
+       if (tempbx & tempcx) {
+               CR3CData = XGINew_GetReg1(pVBInfo->P3d4, 0x3c);
+               if (!(CR3CData & DisplayDeviceFromCMOS)) {
+                       tempcx = 0x1FF0;
+                       if (*pVBInfo->pSoftSetting & ModeSoftSetting)
+                               tempbx = 0x1FF0;
                }
-               break;
+       } else {
+               tempcx = 0x1FF0;
+               if (*pVBInfo->pSoftSetting & ModeSoftSetting)
+                       tempbx = 0x1FF0;
+       }
 
-       case XG27:
-               XGINew_DataBusWidth = 16; /* 16 bits */
-               XGINew_ChannelAB = 1; /* Single channel */
-               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/
-               break;
-       case XG41:
-               if (XGINew_CheckFrequence(pVBInfo) == 1) {
-                       XGINew_DataBusWidth = 32; /* 32 bits */
-                       XGINew_ChannelAB = 3; /* Quad Channel */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C);
+       tempbx &= tempcx;
+       XGINew_SetReg1(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF));
+       XGINew_SetReg1(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8));
+}
 
-                       if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
-                               return;
+static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension,
+               struct vb_device_info *pVBInfo)
+{
+       unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data;
 
-                       XGINew_ChannelAB = 2; /* Dual channels */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48);
+       temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
+       temp |= XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8;
+       temp |= (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8;
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
+       if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
+               if (temp & ActiveCRT2)
+                       tempcl = SetCRT2ToRAMDAC;
+       }
 
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x49);
+       if (temp & ActiveLCD) {
+               tempcl |= SetCRT2ToLCD;
+               if (temp & DriverMode) {
+                       if (temp & ActiveTV) {
+                               tempch = SetToLCDA | EnableDualEdge;
+                               temp ^= SetCRT2ToLCD;
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
+                               if ((temp >> 8) & ActiveAVideo)
+                                       tempcl |= SetCRT2ToAVIDEO;
+                               if ((temp >> 8) & ActiveSVideo)
+                                       tempcl |= SetCRT2ToSVIDEO;
+                               if ((temp >> 8) & ActiveSCART)
+                                       tempcl |= SetCRT2ToSCART;
 
-                       XGINew_ChannelAB = 3;
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C);
+                               if (pVBInfo->IF_DEF_HiVision == 1) {
+                                       if ((temp >> 8) & ActiveHiTV)
+                                               tempcl |= SetCRT2ToHiVisionTV;
+                               }
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
+                               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;
 
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38);
+               if (pVBInfo->IF_DEF_HiVision == 1) {
+                       if ((temp >> 8) & ActiveHiTV)
+                               tempcl |= SetCRT2ToHiVisionTV;
+               }
 
-                       if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1)
-                               return;
-                       else
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x39);
-               } else { /* DDR */
-                       XGINew_DataBusWidth = 64; /* 64 bits */
-                       XGINew_ChannelAB = 2; /* Dual channels */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A);
+               if (pVBInfo->IF_DEF_YPbPr == 1) {
+                       if ((temp >> 8) & ActiveYPbPr)
+                               tempch |= SetYPbPr;
+               }
+       }
 
-                       if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1)
-                               return;
+       tempcl |= SetSimuScanMode;
+       if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV)
+                       || (temp & ActiveCRT2)))
+               tempcl ^= (SetSimuScanMode | SwitchToCRT2);
+       if ((temp & ActiveLCD) && (temp & ActiveTV))
+               tempcl ^= (SetSimuScanMode | SwitchToCRT2);
+       XGINew_SetReg1(pVBInfo->P3d4, 0x30, tempcl);
 
-                       XGINew_ChannelAB = 1; /* Single channels */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
+       CR31Data = XGINew_GetReg1(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);
+       XGINew_SetReg1(pVBInfo->P3d4, 0x31, CR31Data);
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
-
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x53);
-
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
+       CR38Data = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+       CR38Data &= ~SetYPbPr;
+       CR38Data |= tempch;
+       XGINew_SetReg1(pVBInfo->P3d4, 0x38, CR38Data);
 
-                       XGINew_ChannelAB = 2; /* Dual channels */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A);
+}
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
+static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension,
+               struct vb_device_info *pVBInfo)
+{
+       unsigned char Temp;
+       volatile unsigned char *pVideoMemory =
+                       (unsigned char *) pVBInfo->ROMAddr;
 
-                       XGINew_ChannelAB = 1; /* Single channels */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
+       pVBInfo->IF_DEF_LVDS = 0;
 
-                       if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1)
-                               return;
+#if 1
+       if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */
+               pVBInfo->IF_DEF_LVDS = 1;
+               XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
+               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */
+       } else {
+#endif
+               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read  */
+               Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0xC0;
+               if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
+                       XGINew_SenseLCD(HwDeviceExtension, pVBInfo);
+                       XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
+                       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */
+                       Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x04;
+                       if (!Temp)
+                               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */
                        else
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x43);
+                               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */
+                       XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */
                }
+#if 1
+       }
+#endif
+}
 
-               break;
+static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension,
+               struct vb_device_info *pVBInfo)
+{
+       unsigned char Temp, bCR4A;
 
-       case XG42:
-               /*
-                XG42 SR14 D[3] Reserve
-                D[2] = 1, Dual Channel
-                = 0, Single Channel
+       pVBInfo->IF_DEF_LVDS = 0;
+       bCR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read  */
+       Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x07;
+       XGINew_SetReg1(pVBInfo->P3d4, 0x4A, bCR4A);
 
-                It's Different from Other XG40 Series.
-                */
-               if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */
-                       XGINew_DataBusWidth = 32; /* 32 bits */
-                       XGINew_ChannelAB = 2; /* 2 Channel */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x44);
+       if (Temp <= 0x02) {
+               pVBInfo->IF_DEF_LVDS = 1;
+               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */
+               XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x21);
+       } else {
+               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */
+       }
+       XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
+}
 
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x34);
-                       if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
-                               return;
+static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
+{
+       unsigned char CR38, CR4A, temp;
 
-                       XGINew_ChannelAB = 1; /* Single Channel */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x40);
+       CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */
+       CR38 = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+       temp = 0;
+       if ((CR38 & 0xE0) > 0x80) {
+               temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
+               temp &= 0x08;
+               temp >>= 3;
+       }
 
-                       if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
-                               return;
-                       else {
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30);
-                       }
-               } else { /* DDR */
-                       XGINew_DataBusWidth = 64; /* 64 bits */
-                       XGINew_ChannelAB = 1; /* 1 channels */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
+       XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
-                       else {
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
-                       }
-               }
+       return temp;
+}
 
-               break;
+static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
+{
+       unsigned char CR4A, temp;
 
-       default: /* XG40 */
+       CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */
+       temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
+       if (temp <= 2)
+               temp &= 0x03;
+       else
+               temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01);
 
-               if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */
-                       XGINew_DataBusWidth = 32; /* 32 bits */
-                       XGINew_ChannelAB = 3;
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C);
+       XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
 
-                       if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
-                               return;
+       return temp;
+}
 
-                       XGINew_ChannelAB = 2; /* 2 channels */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48);
+unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension)
+{
+       struct vb_device_info VBINF;
+       struct vb_device_info *pVBInfo = &VBINF;
+       unsigned char i, temp = 0, temp1;
+       /* VBIOSVersion[5]; */
+       volatile unsigned char *pVideoMemory;
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
-                               return;
+       /* unsigned long j, k; */
 
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C);
+       unsigned long Temp;
 
-                       if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) {
-                               XGINew_ChannelAB = 3; /* 4 channels */
-                       } else {
-                               XGINew_ChannelAB = 2; /* 2 channels */
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38);
-                       }
-               } else { /* DDR */
-                       XGINew_DataBusWidth = 64; /* 64 bits */
-                       XGINew_ChannelAB = 2; /* 2 channels */
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A);
+       pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
 
-                       if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) {
-                               return;
-                       } else {
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
-                               XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A);
-                       }
-               }
-               break;
-       }
-}
+       pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
 
-static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension,
-               struct vb_device_info *pVBInfo)
-{
-       int i;
-       unsigned short memsize, addr;
+       pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
 
-       XGINew_SetReg1(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */
-       XGINew_SetReg1(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */
-       XGINew_CheckChannel(HwDeviceExtension, pVBInfo);
+       pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
 
-       if (HwDeviceExtension->jChipType >= XG20) {
-               for (i = 0; i < 12; i++) {
-                       XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
-                       memsize = XGINew_SetDRAMSize20Reg(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
-                       if (memsize == 0)
-                               continue;
+       /* Newdebugcode(0x99); */
 
-                       addr = memsize + (XGINew_ChannelAB - 2) + 20;
-                       if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
-                               continue;
 
-                       if (XGINew_ReadWriteRest(addr, 5, pVBInfo) == 1)
-                               return 1;
-               }
-       } else {
-               for (i = 0; i < 4; i++) {
-                       XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
-                       memsize = XGINew_SetDRAMSizeReg(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
+       /* if (pVBInfo->ROMAddr == 0) */
+       /* return(0); */
 
-                       if (memsize == 0)
-                               continue;
+       if (pVBInfo->FBAddr == NULL) {
+               printk("\n pVBInfo->FBAddr == 0 ");
+               return 0;
+       }
+       printk("1");
+       if (pVBInfo->BaseAddr == 0) {
+               printk("\npVBInfo->BaseAddr == 0 ");
+               return 0;
+       }
+       printk("2");
 
-                       addr = memsize + (XGINew_ChannelAB - 2) + 20;
-                       if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
-                               continue;
+       XGINew_SetReg3((pVBInfo->BaseAddr + 0x12), 0x67); /* 3c2 <- 67 ,ynlai */
 
-                       if (XGINew_ReadWriteRest(addr, 9, pVBInfo) == 1)
-                               return 1;
-               }
-       }
-       return 0;
-}
+       pVBInfo->ISXPDOS = 0;
+       printk("3");
 
-static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension,
-               struct vb_device_info *pVBInfo)
-{
+       printk("4");
 
-       XGINew_SetReg1(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A);
+       /* VBIOSVersion[4] = 0x0; */
 
-       XGINew_SetReg1(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F);
-       XGINew_SetReg1(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30);
+       /* 09/07/99 modify by domao */
 
-       /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
-       /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
-       if (HwDeviceExtension->jChipType == XG42) {
-               if ((pVBInfo->MCLKData[XGINew_RAMType].SR28 == 0x1C)
-                               && (pVBInfo->MCLKData[XGINew_RAMType].SR29 == 0x01)
-                               && (((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x1C)
-                                               && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))
-                                       || ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22)
-                                               && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))))
-                       XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
-       }
-}
+       pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+       pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+       pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+       pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+       pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+       pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+       pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+       pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+       pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+       pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+       pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+       pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+       pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+       pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+       pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+       pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+       pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+       printk("5");
 
-static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo)
-{
-       volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
-       unsigned long i;
-       unsigned char j, k;
-       /* Volari customize data area end */
+       if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
+               XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
 
-       if (ChipType == XG21) {
-               pVBInfo->IF_DEF_LVDS = 0;
-               if (pVideoMemory[0x65] & 0x1) {
-                       pVBInfo->IF_DEF_LVDS = 1;
-                       i = pVideoMemory[0x316] | (pVideoMemory[0x317] << 8);
-                       j = pVideoMemory[i - 1];
-                       if (j != 0xff) {
-                               k = 0;
-                               do {
-                                       pVBInfo->XG21_LVDSCapList[k].LVDS_Capability
-                                               = pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].LVDSHT
-                                               = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].LVDSVT
-                                               = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].LVDSHDE
-                                               = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].LVDSVDE
-                                               = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].LVDSHFP
-                                               = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].LVDSVFP
-                                               = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC
-                                               = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC
-                                               = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
-                                       pVBInfo->XG21_LVDSCapList[k].VCLKData1
-                                               = pVideoMemory[i + 18];
-                                       pVBInfo->XG21_LVDSCapList[k].VCLKData2
-                                               = pVideoMemory[i + 19];
-                                       pVBInfo->XG21_LVDSCapList[k].PSC_S1
-                                               = pVideoMemory[i + 20];
-                                       pVBInfo->XG21_LVDSCapList[k].PSC_S2
-                                               = pVideoMemory[i + 21];
-                                       pVBInfo->XG21_LVDSCapList[k].PSC_S3
-                                               = pVideoMemory[i + 22];
-                                       pVBInfo->XG21_LVDSCapList[k].PSC_S4
-                                               = pVideoMemory[i + 23];
-                                       pVBInfo->XG21_LVDSCapList[k].PSC_S5
-                                               = pVideoMemory[i + 24];
-                                       i += 25;
-                                       j--;
-                                       k++;
-                               } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList) / sizeof(struct XGI21_LVDSCapStruct))));
-                       } else {
-                               pVBInfo->XG21_LVDSCapList[0].LVDS_Capability
-                                               = pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].LVDSHT
-                                               = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].LVDSVT
-                                               = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].LVDSHDE
-                                               = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].LVDSVDE
-                                               = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].LVDSHFP
-                                               = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].LVDSVFP
-                                               = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC
-                                               = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC
-                                               = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
-                               pVBInfo->XG21_LVDSCapList[0].VCLKData1
-                                               = pVideoMemory[i + 18];
-                               pVBInfo->XG21_LVDSCapList[0].VCLKData2
-                                               = pVideoMemory[i + 19];
-                               pVBInfo->XG21_LVDSCapList[0].PSC_S1
-                                               = pVideoMemory[i + 20];
-                               pVBInfo->XG21_LVDSCapList[0].PSC_S2
-                                               = pVideoMemory[i + 21];
-                               pVBInfo->XG21_LVDSCapList[0].PSC_S3
-                                               = pVideoMemory[i + 22];
-                               pVBInfo->XG21_LVDSCapList[0].PSC_S4
-                                               = pVideoMemory[i + 23];
-                               pVBInfo->XG21_LVDSCapList[0].PSC_S5
-                                               = pVideoMemory[i + 24];
-                       }
-               }
+       InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+
+       /* ReadVBIOSData */
+       ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
+
+       /* 1.Openkey */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
+       printk("6");
+
+       /* GetXG21Sense (GPIO) */
+       if (HwDeviceExtension->jChipType == XG21)
+               XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo);
+
+       if (HwDeviceExtension->jChipType == XG27)
+               XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo);
+
+       printk("7");
+
+       /* 2.Reset Extended register */
+
+       for (i = 0x06; i < 0x20; i++)
+               XGINew_SetReg1(pVBInfo->P3c4, i, 0);
+
+       for (i = 0x21; i <= 0x27; i++)
+               XGINew_SetReg1(pVBInfo->P3c4, i, 0);
+
+       /* for(i = 0x06; i <= 0x27; i++) */
+       /* XGINew_SetReg1(pVBInfo->P3c4, i, 0); */
+
+       printk("8");
+
+       if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) {
+               for (i = 0x31; i <= 0x3B; i++)
+                       XGINew_SetReg1(pVBInfo->P3c4, i, 0);
+       } else {
+               for (i = 0x31; i <= 0x3D; i++)
+                       XGINew_SetReg1(pVBInfo->P3c4, i, 0);
        }
-}
+       printk("9");
 
-static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo)
-{
+       if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
+               XGINew_SetReg1(pVBInfo->P3c4, 0x3B, 0xC0);
 
-       XGINew_SetReg1(P3c4, 0x18, 0x01);
-       XGINew_SetReg1(P3c4, 0x19, 0x40);
-       XGINew_SetReg1(P3c4, 0x16, 0x00);
-       XGINew_SetReg1(P3c4, 0x16, 0x80);
-       DelayUS(60);
+       /* for (i = 0x30; i <= 0x3F; i++) */
+       /* XGINew_SetReg1(pVBInfo->P3d4, i, 0); */
 
-       XGINew_SetReg1(P3c4, 0x18, 0x00);
-       XGINew_SetReg1(P3c4, 0x19, 0x40);
-       XGINew_SetReg1(P3c4, 0x16, 0x00);
-       XGINew_SetReg1(P3c4, 0x16, 0x80);
-       DelayUS(60);
-       XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
-       /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
-       XGINew_SetReg1(P3c4, 0x19, 0x01);
-       XGINew_SetReg1(P3c4, 0x16, 0x03);
-       XGINew_SetReg1(P3c4, 0x16, 0x83);
-       DelayUS(1000);
-       XGINew_SetReg1(P3c4, 0x1B, 0x03);
-       DelayUS(500);
-       /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
-       XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
-       XGINew_SetReg1(P3c4, 0x19, 0x00);
-       XGINew_SetReg1(P3c4, 0x16, 0x03);
-       XGINew_SetReg1(P3c4, 0x16, 0x83);
-       XGINew_SetReg1(P3c4, 0x1B, 0x00);
-}
+       for (i = 0x79; i <= 0x7C; i++)
+               XGINew_SetReg1(pVBInfo->P3d4, i, 0); /* shampoo 0208 */
 
-static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
-               struct vb_device_info *pVBInfo)
-{
-       unsigned short tempbx = 0, temp, tempcx, CR3CData;
+       printk("10");
 
-       temp = XGINew_GetReg1(pVBInfo->P3d4, 0x32);
+       if (HwDeviceExtension->jChipType >= XG20)
+               XGINew_SetReg1(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97);
 
-       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);
+       /* 3.SetMemoryClock
+
+        if (HwDeviceExtension->jChipType >= XG40)
+        XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+
+        if (HwDeviceExtension->jChipType < XG40)
+        XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);  */
+
+       printk("11");
+
+       /* 4.SetDefExt1Regs begin */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07);
+       if (HwDeviceExtension->jChipType == XG27) {
+               XGINew_SetReg1(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40);
+               XGINew_SetReg1(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41);
        }
+       XGINew_SetReg1(pVBInfo->P3c4, 0x11, 0x0F);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F);
+       /* XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0x20); */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */
+       if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */
+               XGINew_SetReg1(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36);
 
-       tempcx = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
-       tempcx |= (XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8);
+       /* SR11 = 0x0F; */
+       /* XGINew_SetReg1(pVBInfo->P3c4, 0x11, SR11); */
 
-       if (tempbx & tempcx) {
-               CR3CData = XGINew_GetReg1(pVBInfo->P3d4, 0x3c);
-               if (!(CR3CData & DisplayDeviceFromCMOS)) {
-                       tempcx = 0x1FF0;
-                       if (*pVBInfo->pSoftSetting & ModeSoftSetting)
-                               tempbx = 0x1FF0;
+       printk("12");
+
+       if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+               /* Set AGP Rate */
+               /*
+               temp1 = XGINew_GetReg1(pVBInfo->P3c4, 0x3B);
+               temp1 &= 0x02;
+               if (temp1 == 0x02) {
+                       XGINew_SetReg4(0xcf8, 0x80000000);
+                       ChipsetID = XGINew_GetReg3(0x0cfc);
+                       XGINew_SetReg4(0xcf8, 0x8000002C);
+                       VendorID = XGINew_GetReg3(0x0cfc);
+                       VendorID &= 0x0000FFFF;
+                       XGINew_SetReg4(0xcf8, 0x8001002C);
+                       GraphicVendorID = XGINew_GetReg3(0x0cfc);
+                       GraphicVendorID &= 0x0000FFFF;
+
+                       if (ChipsetID == 0x7301039)
+                               XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x09);
+
+                       ChipsetID &= 0x0000FFFF;
+
+                       if ((ChipsetID == 0x700E) || (ChipsetID == 0x1022) || (ChipsetID == 0x1106) || (ChipsetID == 0x10DE)) {
+                               if (ChipsetID == 0x1106) {
+                                       if ((VendorID == 0x1019) && (GraphicVendorID == 0x1019))
+                                               XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0D);
+                                       else
+                                               XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B);
+                               } else {
+                                       XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B);
+                               }
+                       }
                }
-       } else {
-               tempcx = 0x1FF0;
-               if (*pVBInfo->pSoftSetting & ModeSoftSetting)
-                       tempbx = 0x1FF0;
-       }
+               */
 
-       tempbx &= tempcx;
-       XGINew_SetReg1(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF));
-       XGINew_SetReg1(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8));
-}
+               printk("13");
+
+               if (HwDeviceExtension->jChipType >= XG40) {
+                       /* Set AGP customize registers (in SetDefAGPRegs) Start */
+                       for (i = 0x47; i <= 0x4C; i++)
+                               XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]);
+
+                       for (i = 0x70; i <= 0x71; i++)
+                               XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]);
+
+                       for (i = 0x74; i <= 0x77; i++)
+                               XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]);
+                       /* Set AGP customize registers (in SetDefAGPRegs) End */
+                       /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
+                       /*        XGINew_SetReg4(0xcf8 , 0x80000000); */
+                       /*        ChipsetID = XGINew_GetReg3(0x0cfc); */
+                       /*        if (ChipsetID == 0x25308086) */
+                       /*            XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */
+
+                       HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */
+                       Temp >>= 20;
+                       Temp &= 0xF;
+
+                       if (Temp == 1)
+                               XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
+               }
+               printk("14");
 
-static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension,
-               struct vb_device_info *pVBInfo)
-{
-       unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data;
+               if (HwDeviceExtension->jChipType < XG40)
+                       XGINew_SetReg1(pVBInfo->P3d4, 0x49, pVBInfo->CR49[0]);
+       } /* != XG20 */
 
-       temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
-       temp |= XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8;
-       temp |= (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8;
+       /* Set PCI */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]);
+       printk("15");
 
-       if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
-               if (temp & ActiveCRT2)
-                       tempcl = SetCRT2ToRAMDAC;
-       }
+       if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+               /* Set VB */
+               XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
+               XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */
+               XGINew_SetReg1(pVBInfo->Part1Port, 0x00, 0x00);
+               temp1 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */
+               temp = (unsigned char) ((temp1 >> 4) & 0x0F);
 
-       if (temp & ActiveLCD) {
-               tempcl |= SetCRT2ToLCD;
-               if (temp & DriverMode) {
-                       if (temp & ActiveTV) {
-                               tempch = SetToLCDA | EnableDualEdge;
-                               temp ^= SetCRT2ToLCD;
+               XGINew_SetReg1(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2));
 
-                               if ((temp >> 8) & ActiveAVideo)
-                                       tempcl |= SetCRT2ToAVIDEO;
-                               if ((temp >> 8) & ActiveSVideo)
-                                       tempcl |= SetCRT2ToSVIDEO;
-                               if ((temp >> 8) & ActiveSCART)
-                                       tempcl |= SetCRT2ToSCART;
+               printk("16");
 
-                               if (pVBInfo->IF_DEF_HiVision == 1) {
-                                       if ((temp >> 8) & ActiveHiTV)
-                                               tempcl |= SetCRT2ToHiVisionTV;
-                               }
+               XGINew_SetReg1(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
+       } /* != XG20 */
 
-                               if (pVBInfo->IF_DEF_YPbPr == 1) {
-                                       if ((temp >> 8) & ActiveYPbPr)
-                                               tempch |= SetYPbPr;
-                               }
-                       }
-               }
+       XGINew_SetReg1(pVBInfo->P3c4, 0x27, 0x1F);
+
+       if ((HwDeviceExtension->jChipType == XG42)
+                       && XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { /* Not DDR */
+               XGINew_SetReg1(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40);
+               XGINew_SetReg1(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01);
        } else {
-               if ((temp >> 8) & ActiveAVideo)
-                       tempcl |= SetCRT2ToAVIDEO;
-               if ((temp >> 8) & ActiveSVideo)
-                       tempcl |= SetCRT2ToSVIDEO;
-               if ((temp >> 8) & ActiveSCART)
-                       tempcl |= SetCRT2ToSCART;
+               XGINew_SetReg1(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31);
+               XGINew_SetReg1(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32);
+       }
+       XGINew_SetReg1(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33);
+       printk("17");
 
-               if (pVBInfo->IF_DEF_HiVision == 1) {
-                       if ((temp >> 8) & ActiveHiTV)
-                               tempcl |= SetCRT2ToHiVisionTV;
-               }
+       /*
+        if (HwDeviceExtension->jChipType >= XG40)
+        SetPowerConsume (HwDeviceExtension, pVBInfo->P3c4);    */
 
-               if (pVBInfo->IF_DEF_YPbPr == 1) {
-                       if ((temp >> 8) & ActiveYPbPr)
-                               tempch |= SetYPbPr;
+       if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+               if (XGI_BridgeIsOn(pVBInfo) == 1) {
+                       if (pVBInfo->IF_DEF_LVDS == 0) {
+                               XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1C);
+                               XGINew_SetReg1(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D);
+                               XGINew_SetReg1(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E);
+                               XGINew_SetReg1(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10);
+                               XGINew_SetReg1(pVBInfo->Part4Port, 0x0F, 0x3F);
+                       }
+
+                       XGI_LockCRT2(HwDeviceExtension, pVBInfo);
                }
-       }
+       } /* != XG20 */
+       printk("18");
 
-       tempcl |= SetSimuScanMode;
-       if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV)
-                       || (temp & ActiveCRT2)))
-               tempcl ^= (SetSimuScanMode | SwitchToCRT2);
-       if ((temp & ActiveLCD) && (temp & ActiveTV))
-               tempcl ^= (SetSimuScanMode | SwitchToCRT2);
-       XGINew_SetReg1(pVBInfo->P3d4, 0x30, tempcl);
+       if (HwDeviceExtension->jChipType < XG40)
+               XGINew_SetReg1(pVBInfo->P3d4, 0x83, 0x00);
+       printk("181");
 
-       CR31Data = XGINew_GetReg1(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);
-       XGINew_SetReg1(pVBInfo->P3d4, 0x31, CR31Data);
+       printk("182");
 
-       CR38Data = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
-       CR38Data &= ~SetYPbPr;
-       CR38Data |= tempch;
-       XGINew_SetReg1(pVBInfo->P3d4, 0x38, CR38Data);
+       XGI_SenseCRT1(pVBInfo);
 
-}
+       printk("183");
+       /* XGINew_DetectMonitor(HwDeviceExtension); */
+       pVBInfo->IF_DEF_CH7007 = 0;
+       if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) {
+               printk("184");
+               XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */
+               printk("185");
 
-static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension,
-               struct vb_device_info *pVBInfo)
-{
-       unsigned char Temp;
-       volatile unsigned char *pVideoMemory =
-                       (unsigned char *) pVBInfo->ROMAddr;
+       }
+       if (HwDeviceExtension->jChipType == XG21) {
+               printk("186");
 
-       pVBInfo->IF_DEF_LVDS = 0;
+               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
+               temp = GetXG21FPBits(pVBInfo);
+               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp);
+               printk("187");
 
-#if 1
-       if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */
-               pVBInfo->IF_DEF_LVDS = 1;
-               XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
-               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */
-       } else {
-#endif
-               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read  */
-               Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0xC0;
-               if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
-                       XGINew_SenseLCD(HwDeviceExtension, pVBInfo);
-                       XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
-                       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */
-                       Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x04;
-                       if (!Temp)
-                               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */
-                       else
-                               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */
-                       XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */
-               }
-#if 1
        }
-#endif
-}
+       if (HwDeviceExtension->jChipType == XG27) {
+               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
+               temp = GetXG27FPBits(pVBInfo);
+               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp);
+       }
+       printk("19");
 
-static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension,
-               struct vb_device_info *pVBInfo)
-{
-       unsigned char Temp, bCR4A;
+       if (HwDeviceExtension->jChipType >= XG40) {
+               if (HwDeviceExtension->jChipType >= XG40)
+                       XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
 
-       pVBInfo->IF_DEF_LVDS = 0;
-       bCR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
-       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read  */
-       Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x07;
-       XGINew_SetReg1(pVBInfo->P3d4, 0x4A, bCR4A);
+               XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo);
 
-       if (Temp <= 0x02) {
-               pVBInfo->IF_DEF_LVDS = 1;
-               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */
-               XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x21);
-       } else {
-               XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */
-       }
-       XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
+               printk("20");
+               XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo);
+               printk("21");
+       } /* XG40 */
 
-}
+       printk("22");
 
-static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
-{
-       unsigned char CR38, CR4A, temp;
+       /* SetDefExt2Regs begin */
+       /*
+       AGP = 1;
+       temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x3A);
+       temp &= 0x30;
+       if (temp == 0x30)
+               AGP = 0;
 
-       CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
-       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */
-       CR38 = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
-       temp = 0;
-       if ((CR38 & 0xE0) > 0x80) {
-               temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
-               temp &= 0x08;
-               temp >>= 3;
-       }
+       if (AGP == 0)
+               *pVBInfo->pSR21 &= 0xEF;
 
-       XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21);
+       if (AGP == 1)
+               *pVBInfo->pSR22 &= 0x20;
+       XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22);
+       */
+       /* base = 0x80000000; */
+       /* OutPortLong(0xcf8, base); */
+       /* Temp = (InPortLong(0xcfc) & 0xFFFF); */
+       /* if (Temp == 0x1039) { */
+       XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE));
+       /* } else { */
+       /*      XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */
+       /* } */
 
-       return temp;
-}
+       XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21);
 
-static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
-{
-       unsigned char CR4A, temp;
+       printk("23");
 
-       CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
-       XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */
-       temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
-       if (temp <= 2)
-               temp &= 0x03;
-       else
-               temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01);
+       XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo);
+       XGINew_SetModeScratch(HwDeviceExtension, pVBInfo);
 
-       XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
+       printk("24");
 
-       return temp;
-}
+       XGINew_SetReg1(pVBInfo->P3d4, 0x8c, 0x87);
+       XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31);
+       printk("25");
 
+       return 1;
+} /* end of init */