TI DaVinci EMAC: Clear statistics register properly.
[firefly-linux-kernel-4.4.55.git] / drivers / video / via / hw.c
index c8960003f47dc4e0e8ed4de2e0b62c91633af8ae..3e083ff67ae20b458704f89c1a56ceab061d2278 100644 (file)
 
 #include "global.h"
 
-static const struct pci_device_id_info pciidlist[] = {
-       {PCI_VIA_VENDOR_ID, UNICHROME_CLE266_DID, UNICHROME_CLE266},
-       {PCI_VIA_VENDOR_ID, UNICHROME_PM800_DID, UNICHROME_PM800},
-       {PCI_VIA_VENDOR_ID, UNICHROME_K400_DID, UNICHROME_K400},
-       {PCI_VIA_VENDOR_ID, UNICHROME_K800_DID, UNICHROME_K800},
-       {PCI_VIA_VENDOR_ID, UNICHROME_CN700_DID, UNICHROME_CN700},
-       {PCI_VIA_VENDOR_ID, UNICHROME_P4M890_DID, UNICHROME_P4M890},
-       {PCI_VIA_VENDOR_ID, UNICHROME_K8M890_DID, UNICHROME_K8M890},
-       {PCI_VIA_VENDOR_ID, UNICHROME_CX700_DID, UNICHROME_CX700},
-       {PCI_VIA_VENDOR_ID, UNICHROME_P4M900_DID, UNICHROME_P4M900},
-       {PCI_VIA_VENDOR_ID, UNICHROME_CN750_DID, UNICHROME_CN750},
-       {PCI_VIA_VENDOR_ID, UNICHROME_VX800_DID, UNICHROME_VX800},
-       {0, 0, 0}
-};
-
-struct offset offset_reg = {
-       /* IGA1 Offset Register */
-       {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } },
-       /* IGA2 Offset Register */
-       {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } }
-};
-
 static struct pll_map pll_value[] = {
-       {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M},
-       {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M},
-       {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M},
-       {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M},
-       {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M},
-       {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M},
-       {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M},
-       {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M},
-       {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M},
-       {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M},
-       {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M},
-       {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, CX700_45_250M},
-       {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, CX700_46_000M},
-       {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, CX700_46_996M},
-       {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, CX700_48_000M},
-       {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M},
-       {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M},
-       {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M},
-       {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, CX700_52_977M},
-       {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M},
-       {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, CX700_60_466M},
-       {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, CX700_61_500M},
-       {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M},
-       {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, CX700_65_178M},
-       {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, CX700_66_750M},
-       {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M},
-       {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, CX700_69_924M},
-       {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, CX700_70_159M},
-       {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, CX700_72_000M},
-       {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M},
-       {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M},
-       {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M},
-       {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M},
-       {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, CX700_84_750M},
-       {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M},
-       {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, CX700_88_750M},
-       {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M},
-       {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, CX700_97_750M},
+       {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M,
+        CX700_25_175M, VX855_25_175M},
+       {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M,
+        CX700_29_581M, VX855_29_581M},
+       {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M,
+        CX700_26_880M, VX855_26_880M},
+       {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M,
+        CX700_31_490M, VX855_31_490M},
+       {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M,
+        CX700_31_500M, VX855_31_500M},
+       {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M,
+        CX700_31_728M, VX855_31_728M},
+       {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M,
+        CX700_32_668M, VX855_32_668M},
+       {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M,
+        CX700_36_000M, VX855_36_000M},
+       {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M,
+        CX700_40_000M, VX855_40_000M},
+       {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M,
+        CX700_41_291M, VX855_41_291M},
+       {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M,
+        CX700_43_163M, VX855_43_163M},
+       {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M,
+        CX700_45_250M, VX855_45_250M},
+       {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M,
+        CX700_46_000M, VX855_46_000M},
+       {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M,
+        CX700_46_996M, VX855_46_996M},
+       {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M,
+        CX700_48_000M, VX855_48_000M},
+       {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M,
+        CX700_48_875M, VX855_48_875M},
+       {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M,
+        CX700_49_500M, VX855_49_500M},
+       {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M,
+        CX700_52_406M, VX855_52_406M},
+       {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M,
+        CX700_52_977M, VX855_52_977M},
+       {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M,
+        CX700_56_250M, VX855_56_250M},
+       {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M,
+        CX700_60_466M, VX855_60_466M},
+       {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M,
+        CX700_61_500M, VX855_61_500M},
+       {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M,
+        CX700_65_000M, VX855_65_000M},
+       {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M,
+        CX700_65_178M, VX855_65_178M},
+       {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M,
+        CX700_66_750M, VX855_66_750M},
+       {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M,
+        CX700_68_179M, VX855_68_179M},
+       {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M,
+        CX700_69_924M, VX855_69_924M},
+       {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M,
+        CX700_70_159M, VX855_70_159M},
+       {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M,
+        CX700_72_000M, VX855_72_000M},
+       {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M,
+        CX700_78_750M, VX855_78_750M},
+       {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M,
+        CX700_80_136M, VX855_80_136M},
+       {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M,
+        CX700_83_375M, VX855_83_375M},
+       {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M,
+        CX700_83_950M, VX855_83_950M},
+       {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M,
+        CX700_84_750M, VX855_84_750M},
+       {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M,
+        CX700_85_860M, VX855_85_860M},
+       {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M,
+        CX700_88_750M, VX855_88_750M},
+       {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M,
+        CX700_94_500M, VX855_94_500M},
+       {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M,
+        CX700_97_750M, VX855_97_750M},
        {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M,
-        CX700_101_000M},
+        CX700_101_000M, VX855_101_000M},
        {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M,
-        CX700_106_500M},
+        CX700_106_500M, VX855_106_500M},
        {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M,
-        CX700_108_000M},
+        CX700_108_000M, VX855_108_000M},
        {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M,
-        CX700_113_309M},
+        CX700_113_309M, VX855_113_309M},
        {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M,
-        CX700_118_840M},
+        CX700_118_840M, VX855_118_840M},
        {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M,
-        CX700_119_000M},
+        CX700_119_000M, VX855_119_000M},
        {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M,
-        CX700_121_750M},
+        CX700_121_750M, 0},
        {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M,
-        CX700_125_104M},
+        CX700_125_104M, 0},
        {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M,
-        CX700_133_308M},
+        CX700_133_308M, 0},
        {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M,
-        CX700_135_000M},
+        CX700_135_000M, VX855_135_000M},
        {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M,
-        CX700_136_700M},
+        CX700_136_700M, VX855_136_700M},
        {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M,
-        CX700_138_400M},
+        CX700_138_400M, VX855_138_400M},
        {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M,
-        CX700_146_760M},
+        CX700_146_760M, VX855_146_760M},
        {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M,
-        CX700_153_920M},
+        CX700_153_920M, VX855_153_920M},
        {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M,
-        CX700_156_000M},
+        CX700_156_000M, VX855_156_000M},
        {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M,
-        CX700_157_500M},
+        CX700_157_500M, VX855_157_500M},
        {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M,
-        CX700_162_000M},
+        CX700_162_000M, VX855_162_000M},
        {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M,
-        CX700_187_000M},
+        CX700_187_000M, VX855_187_000M},
        {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M,
-        CX700_193_295M},
+        CX700_193_295M, VX855_193_295M},
        {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M,
-        CX700_202_500M},
+        CX700_202_500M, VX855_202_500M},
        {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M,
-        CX700_204_000M},
+        CX700_204_000M, VX855_204_000M},
        {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M,
-        CX700_218_500M},
+        CX700_218_500M, VX855_218_500M},
        {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M,
-        CX700_234_000M},
+        CX700_234_000M, VX855_234_000M},
        {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M,
-        CX700_267_250M},
+        CX700_267_250M, VX855_267_250M},
        {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M,
-        CX700_297_500M},
-       {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M},
+        CX700_297_500M, VX855_297_500M},
+       {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M,
+        CX700_74_481M, VX855_74_481M},
        {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M,
-        CX700_172_798M},
+        CX700_172_798M, VX855_172_798M},
        {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M,
-        CX700_122_614M},
-       {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, CX700_74_270M},
+        CX700_122_614M, VX855_122_614M},
+       {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M,
+        CX700_74_270M, 0},
        {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M,
-        CX700_148_500M}
+        CX700_148_500M, VX855_148_500M}
 };
 
 static struct fifo_depth_select display_fifo_depth_reg = {
@@ -508,7 +526,8 @@ static void set_dvi_output_path(int set_iga, int output_interface);
 static void set_lcd_output_path(int set_iga, int output_interface);
 static int search_mode_setting(int ModeInfoIndex);
 static void load_fix_bit_crtc_reg(void);
-static void init_gfx_chip_info(void);
+static void init_gfx_chip_info(struct pci_dev *pdev,
+                               const struct pci_device_id *pdi);
 static void init_tmds_chip_info(void);
 static void init_lvds_chip_info(void);
 static void device_screen_off(void);
@@ -518,7 +537,6 @@ static void device_off(void);
 static void device_on(void);
 static void enable_second_display_channel(void);
 static void disable_second_display_channel(void);
-static int get_fb_size_from_pci(void);
 
 void viafb_write_reg(u8 index, u16 io_port, u8 data)
 {
@@ -629,70 +647,43 @@ void viafb_set_iga_path(void)
        }
 }
 
-void viafb_set_start_addr(void)
+void viafb_set_primary_address(u32 addr)
 {
-       unsigned long offset = 0, tmp = 0, size = 0;
-       unsigned long length;
-
-       DEBUG_MSG(KERN_INFO "viafb_set_start_addr!\n");
-       viafb_unlock_crt();
-       /* update starting address of IGA1 */
-       viafb_write_reg(CR0C, VIACR, 0x00);     /*initial starting address */
-       viafb_write_reg(CR0D, VIACR, 0x00);
-       viafb_write_reg(CR34, VIACR, 0x00);
-       viafb_write_reg_mask(CR48, VIACR, 0x00, 0x1F);
-
-       if (viafb_dual_fb) {
-               viaparinfo->iga_path = IGA1;
-               viaparinfo1->iga_path = IGA2;
-       }
-
-       if (viafb_SAMM_ON == 1) {
-               if (!viafb_dual_fb) {
-                       if (viafb_second_size)
-                               size = viafb_second_size * 1024 * 1024;
-                       else
-                               size = 8 * 1024 * 1024;
-               } else {
+       DEBUG_MSG(KERN_DEBUG "viafb_set_primary_address(0x%08X)\n", addr);
+       viafb_write_reg(CR0D, VIACR, addr & 0xFF);
+       viafb_write_reg(CR0C, VIACR, (addr >> 8) & 0xFF);
+       viafb_write_reg(CR34, VIACR, (addr >> 16) & 0xFF);
+       viafb_write_reg_mask(CR48, VIACR, (addr >> 24) & 0x1F, 0x1F);
+}
 
-                       size = viaparinfo1->memsize;
-               }
-               offset = viafb_second_offset;
-               DEBUG_MSG(KERN_INFO
-                         "viafb_second_size=%lx, second start_adddress=%lx\n",
-                         size, offset);
-       }
-       if (viafb_SAMM_ON == 1) {
-               offset = offset >> 3;
-
-               tmp = viafb_read_reg(VIACR, 0x62) & 0x01;
-               tmp |= (offset & 0x7F) << 1;
-               viafb_write_reg(CR62, VIACR, tmp);
-               viafb_write_reg(CR63, VIACR, ((offset & 0x7F80) >> 7));
-               viafb_write_reg(CR64, VIACR, ((offset & 0x7F8000) >> 15));
-               viafb_write_reg(CRA3, VIACR, ((offset & 0x3800000) >> 23));
-       } else {
-               /* update starting address */
-               viafb_write_reg(CR62, VIACR, 0x00);
-               viafb_write_reg(CR63, VIACR, 0x00);
-               viafb_write_reg(CR64, VIACR, 0x00);
-               viafb_write_reg(CRA3, VIACR, 0x00);
-       }
+void viafb_set_secondary_address(u32 addr)
+{
+       DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_address(0x%08X)\n", addr);
+       /* secondary display supports only quadword aligned memory */
+       viafb_write_reg_mask(CR62, VIACR, (addr >> 2) & 0xFE, 0xFE);
+       viafb_write_reg(CR63, VIACR, (addr >> 10) & 0xFF);
+       viafb_write_reg(CR64, VIACR, (addr >> 18) & 0xFF);
+       viafb_write_reg_mask(CRA3, VIACR, (addr >> 26) & 0x07, 0x07);
+}
 
-       if (viafb_SAMM_ON == 1) {
-               if (viafb_accel) {
-                       if (!viafb_dual_fb)
-                               length = size - viaparinfo->fbmem_used;
-                       else
-                               length = size - viaparinfo1->fbmem_used;
-               } else
-                       length = size;
-               offset = (unsigned long)(void *)viafb_FB_MM +
-                       viafb_second_offset;
-               memset((void *)offset, 0, length);
-       }
+void viafb_set_primary_pitch(u32 pitch)
+{
+       DEBUG_MSG(KERN_DEBUG "viafb_set_primary_pitch(0x%08X)\n", pitch);
+       /* spec does not say that first adapter skips 3 bits but old
+        * code did it and seems to be reasonable in analogy to 2nd adapter
+        */
+       pitch = pitch >> 3;
+       viafb_write_reg(0x13, VIACR, pitch & 0xFF);
+       viafb_write_reg_mask(0x35, VIACR, (pitch >> (8 - 5)) & 0xE0, 0xE0);
+}
 
-       viafb_lock_crt();
+void viafb_set_secondary_pitch(u32 pitch)
+{
+       DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_pitch(0x%08X)\n", pitch);
+       pitch = pitch >> 3;
+       viafb_write_reg(0x66, VIACR, pitch & 0xFF);
+       viafb_write_reg_mask(0x67, VIACR, (pitch >> 8) & 0x03, 0x03);
+       viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80);
 }
 
 void viafb_set_output_path(int device, int set_iga, int output_interface)
@@ -1123,30 +1114,6 @@ void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
        }
 }
 
-void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga)
-{
-       int reg_value;
-       int viafb_load_reg_num;
-       struct io_register *reg;
-
-       switch (set_iga) {
-       case IGA1_IGA2:
-       case IGA1:
-               reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte);
-               viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num;
-               reg = offset_reg.iga1_offset_reg.reg;
-               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
-               if (set_iga == IGA1)
-                       break;
-       case IGA2:
-               reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte);
-               viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
-               reg = offset_reg.iga2_offset_reg.reg;
-               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
-               break;
-       }
-}
-
 void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
 {
        int reg_value;
@@ -1277,6 +1244,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
                            VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
                }
 
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
+                       iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH;
+                       iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD;
+                       iga1_fifo_high_threshold =
+                           VX855_IGA1_FIFO_HIGH_THRESHOLD;
+                       iga1_display_queue_expire_num =
+                           VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
                /* Set Display FIFO Depath Select */
                reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
                viafb_load_reg_num =
@@ -1408,6 +1384,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
                            VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
                }
 
+               if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
+                       iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH;
+                       iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD;
+                       iga2_fifo_high_threshold =
+                           VX855_IGA2_FIFO_HIGH_THRESHOLD;
+                       iga2_display_queue_expire_num =
+                           VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+               }
+
                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
                        /* Set Display FIFO Depath Select */
                        reg_value =
@@ -1496,6 +1481,8 @@ u32 viafb_get_clk_value(int clk)
                        case UNICHROME_P4M900:
                        case UNICHROME_VX800:
                                return pll_value[i].cx700_pll;
+                       case UNICHROME_VX855:
+                               return pll_value[i].vx855_pll;
                        }
                }
        }
@@ -1529,6 +1516,7 @@ void viafb_set_vclock(u32 CLK, int set_iga)
                case UNICHROME_P4M890:
                case UNICHROME_P4M900:
                case UNICHROME_VX800:
+               case UNICHROME_VX855:
                        viafb_write_reg(SR44, VIASR, CLK / 0x10000);
                        DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000);
                        viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100);
@@ -1557,6 +1545,7 @@ void viafb_set_vclock(u32 CLK, int set_iga)
                case UNICHROME_P4M890:
                case UNICHROME_P4M900:
                case UNICHROME_VX800:
+               case UNICHROME_VX855:
                        viafb_write_reg(SR4A, VIASR, CLK / 0x10000);
                        viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100);
                        viafb_write_reg(SR4C, VIASR, CLK % 0x100);
@@ -1916,7 +1905,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
        load_fix_bit_crtc_reg();
        viafb_lock_crt();
        viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
-       viafb_load_offset_reg(h_addr, bpp_byte, set_iga);
        viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
 
        /* load FIFO */
@@ -1933,9 +1921,10 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
 
 }
 
-void viafb_init_chip_info(void)
+void viafb_init_chip_info(struct pci_dev *pdev,
+                         const struct pci_device_id *pdi)
 {
-       init_gfx_chip_info();
+       init_gfx_chip_info(pdev, pdi);
        init_tmds_chip_info();
        init_lvds_chip_info();
 
@@ -2008,24 +1997,12 @@ void viafb_update_device_setting(int hres, int vres,
        }
 }
 
-static void init_gfx_chip_info(void)
+static void init_gfx_chip_info(struct pci_dev *pdev,
+                              const struct pci_device_id *pdi)
 {
-       struct pci_dev *pdev = NULL;
-       u32 i;
        u8 tmp;
 
-       /* Indentify GFX Chip Name */
-       for (i = 0; pciidlist[i].vendor != 0; i++) {
-               pdev = pci_get_device(pciidlist[i].vendor,
-                       pciidlist[i].device, 0);
-               if (pdev)
-                       break;
-       }
-
-       if (!pciidlist[i].vendor)
-               return ;
-
-       viaparinfo->chip_info->gfx_chip_name = pciidlist[i].chip_index;
+       viaparinfo->chip_info->gfx_chip_name = pdi->driver_data;
 
        /* Check revision of CLE266 Chip */
        if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
@@ -2056,8 +2033,6 @@ static void init_gfx_chip_info(void)
                                CX700_REVISION_700;
                }
        }
-
-       pci_dev_put(pdev);
 }
 
 static void init_tmds_chip_info(void)
@@ -2271,11 +2246,12 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
                break;
 
        case UNICHROME_CX700:
-               viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
-
        case UNICHROME_VX800:
-               viafb_write_regx(VX800_ModeXregs, NUM_TOTAL_VX800_ModeXregs);
+               viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
+               break;
 
+       case UNICHROME_VX855:
+               viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);
                break;
        }
 
@@ -2291,7 +2267,8 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
                outb(VPIT.SR[i - 1], VIASR + 1);
        }
 
-       viafb_set_start_addr();
+       viafb_set_primary_address(0);
+       viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
        viafb_set_iga_path();
 
        /* Write CRTC */
@@ -2371,6 +2348,9 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
                }
        }
 
+       viafb_set_primary_pitch(viafbinfo->fix.line_length);
+       viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
+               : viafbinfo->fix.line_length);
        /* Update Refresh Rate Setting */
 
        /* Clear On Screen */
@@ -2545,38 +2525,6 @@ void viafb_crt_enable(void)
        viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4);
 }
 
-void viafb_get_mmio_info(unsigned long *mmio_base,
-       unsigned long *mmio_len)
-{
-       struct pci_dev *pdev = NULL;
-       u32 vendor, device;
-       u32 i;
-
-       for (i = 0; pciidlist[i].vendor != 0; i++)
-               if (viaparinfo->chip_info->gfx_chip_name ==
-                       pciidlist[i].chip_index)
-                       break;
-
-       if (!pciidlist[i].vendor)
-               return ;
-
-       vendor = pciidlist[i].vendor;
-       device = pciidlist[i].device;
-
-       pdev = pci_get_device(vendor, device, NULL);
-
-       if (!pdev) {
-               *mmio_base = 0;
-               *mmio_len = 0;
-               return ;
-       }
-
-       *mmio_base = pci_resource_start(pdev, 1);
-       *mmio_len = pci_resource_len(pdev, 1);
-
-       pci_dev_put(pdev);
-}
-
 static void enable_second_display_channel(void)
 {
        /* to enable second display channel. */
@@ -2593,44 +2541,7 @@ static void disable_second_display_channel(void)
        viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
 }
 
-void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len)
-{
-       struct pci_dev *pdev = NULL;
-       u32 vendor, device;
-       u32 i;
-
-       for (i = 0; pciidlist[i].vendor != 0; i++)
-               if (viaparinfo->chip_info->gfx_chip_name ==
-                       pciidlist[i].chip_index)
-                       break;
-
-       if (!pciidlist[i].vendor)
-               return ;
-
-       vendor = pciidlist[i].vendor;
-       device = pciidlist[i].device;
-
-       pdev = pci_get_device(vendor, device, NULL);
-
-       if (!pdev) {
-               *fb_base = viafb_read_reg(VIASR, SR30) << 24;
-               *fb_len = viafb_get_memsize();
-               DEBUG_MSG(KERN_INFO "Get FB info from SR30!\n");
-               DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
-               DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
-               return ;
-       }
-
-       *fb_base = (unsigned int)pci_resource_start(pdev, 0);
-       *fb_len = get_fb_size_from_pci();
-       DEBUG_MSG(KERN_INFO "Get FB info from PCI system!\n");
-       DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
-       DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
-
-       pci_dev_put(pdev);
-}
-
-static int get_fb_size_from_pci(void)
+int viafb_get_fb_size_from_pci(void)
 {
        unsigned long configid, deviceid, FBSize = 0;
        int VideoMemSize;
@@ -2656,6 +2567,7 @@ static int get_fb_size_from_pci(void)
                case P4M890_FUNCTION3:
                case P4M900_FUNCTION3:
                case VX800_FUNCTION3:
+               case VX855_FUNCTION3:
                        /*case CN750_FUNCTION3: */
                        outl(configid + 0xA0, (unsigned long)0xCF8);
                        FBSize = inl((unsigned long)0xCFC);
@@ -2719,6 +2631,10 @@ static int get_fb_size_from_pci(void)
                        VideoMemSize = (256 << 20);     /*256M */
                        break;
 
+               case 0x00007000:        /* Only on VX855/875 */
+                       VideoMemSize = (512 << 20);     /*512M */
+                       break;
+
                default:
                        VideoMemSize = (32 << 20);      /*32M */
                        break;
@@ -2788,24 +2704,6 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
        }
 }
 
-void viafb_memory_pitch_patch(struct fb_info *info)
-{
-       if (info->var.xres != info->var.xres_virtual) {
-               viafb_load_offset_reg(info->var.xres_virtual,
-                               info->var.bits_per_pixel >> 3, IGA1);
-
-               if (viafb_SAMM_ON) {
-                       viafb_load_offset_reg(viafb_second_virtual_xres,
-                               viafb_bpp1 >> 3,
-                                       IGA2);
-               } else {
-                       viafb_load_offset_reg(info->var.xres_virtual,
-                                       info->var.bits_per_pixel >> 3, IGA2);
-               }
-
-       }
-}
-
 /*According var's xres, yres fill var's other timing information*/
 void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
                          int mode_index)