Showing error 844

User: Jiri Slaby
Error type: Resource Leak
Error type description: The code omits to put the resource to the system for reuse
File location: drivers/video/via/hw.c
Line in file: 2021
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2011-11-07 22:40:13 UTC


Source:

   1/*
   2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
   3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
   4
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public
   7 * License as published by the Free Software Foundation;
   8 * either version 2, or (at your option) any later version.
   9
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
  12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
  13 * A PARTICULAR PURPOSE.See the GNU General Public License
  14 * for more details.
  15
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc.,
  19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20 */
  21
  22#include "global.h"
  23
  24static const struct pci_device_id_info pciidlist[] = {
  25        {PCI_VIA_VENDOR_ID, UNICHROME_CLE266_DID, UNICHROME_CLE266},
  26        {PCI_VIA_VENDOR_ID, UNICHROME_PM800_DID, UNICHROME_PM800},
  27        {PCI_VIA_VENDOR_ID, UNICHROME_K400_DID, UNICHROME_K400},
  28        {PCI_VIA_VENDOR_ID, UNICHROME_K800_DID, UNICHROME_K800},
  29        {PCI_VIA_VENDOR_ID, UNICHROME_CN700_DID, UNICHROME_CN700},
  30        {PCI_VIA_VENDOR_ID, UNICHROME_P4M890_DID, UNICHROME_P4M890},
  31        {PCI_VIA_VENDOR_ID, UNICHROME_K8M890_DID, UNICHROME_K8M890},
  32        {PCI_VIA_VENDOR_ID, UNICHROME_CX700_DID, UNICHROME_CX700},
  33        {PCI_VIA_VENDOR_ID, UNICHROME_P4M900_DID, UNICHROME_P4M900},
  34        {PCI_VIA_VENDOR_ID, UNICHROME_CN750_DID, UNICHROME_CN750},
  35        {PCI_VIA_VENDOR_ID, UNICHROME_VX800_DID, UNICHROME_VX800},
  36        {0, 0, 0}
  37};
  38
  39struct offset offset_reg = {
  40        /* IGA1 Offset Register */
  41        {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } },
  42        /* IGA2 Offset Register */
  43        {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } }
  44};
  45
  46static struct pll_map pll_value[] = {
  47        {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M},
  48        {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M},
  49        {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M},
  50        {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M},
  51        {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M},
  52        {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M},
  53        {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M},
  54        {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M},
  55        {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M},
  56        {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M},
  57        {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M},
  58        {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, CX700_45_250M},
  59        {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, CX700_46_000M},
  60        {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, CX700_46_996M},
  61        {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, CX700_48_000M},
  62        {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M},
  63        {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M},
  64        {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M},
  65        {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, CX700_52_977M},
  66        {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M},
  67        {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, CX700_60_466M},
  68        {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, CX700_61_500M},
  69        {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M},
  70        {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, CX700_65_178M},
  71        {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, CX700_66_750M},
  72        {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M},
  73        {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, CX700_69_924M},
  74        {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, CX700_70_159M},
  75        {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, CX700_72_000M},
  76        {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M},
  77        {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M},
  78        {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M},
  79        {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M},
  80        {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, CX700_84_750M},
  81        {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M},
  82        {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, CX700_88_750M},
  83        {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M},
  84        {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, CX700_97_750M},
  85        {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M,
  86         CX700_101_000M},
  87        {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M,
  88         CX700_106_500M},
  89        {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M,
  90         CX700_108_000M},
  91        {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M,
  92         CX700_113_309M},
  93        {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M,
  94         CX700_118_840M},
  95        {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M,
  96         CX700_119_000M},
  97        {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M,
  98         CX700_121_750M},
  99        {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M,
 100         CX700_125_104M},
 101        {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M,
 102         CX700_133_308M},
 103        {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M,
 104         CX700_135_000M},
 105        {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M,
 106         CX700_136_700M},
 107        {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M,
 108         CX700_138_400M},
 109        {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M,
 110         CX700_146_760M},
 111        {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M,
 112         CX700_153_920M},
 113        {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M,
 114         CX700_156_000M},
 115        {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M,
 116         CX700_157_500M},
 117        {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M,
 118         CX700_162_000M},
 119        {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M,
 120         CX700_187_000M},
 121        {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M,
 122         CX700_193_295M},
 123        {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M,
 124         CX700_202_500M},
 125        {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M,
 126         CX700_204_000M},
 127        {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M,
 128         CX700_218_500M},
 129        {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M,
 130         CX700_234_000M},
 131        {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M,
 132         CX700_267_250M},
 133        {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M,
 134         CX700_297_500M},
 135        {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M},
 136        {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M,
 137         CX700_172_798M},
 138        {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M,
 139         CX700_122_614M},
 140        {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, CX700_74_270M},
 141        {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M,
 142         CX700_148_500M}
 143};
 144
 145static struct fifo_depth_select display_fifo_depth_reg = {
 146        /* IGA1 FIFO Depth_Select */
 147        {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
 148        /* IGA2 FIFO Depth_Select */
 149        {IGA2_FIFO_DEPTH_SELECT_REG_NUM,
 150         {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
 151};
 152
 153static struct fifo_threshold_select fifo_threshold_select_reg = {
 154        /* IGA1 FIFO Threshold Select */
 155        {IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
 156        /* IGA2 FIFO Threshold Select */
 157        {IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
 158};
 159
 160static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
 161        /* IGA1 FIFO High Threshold Select */
 162        {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
 163        /* IGA2 FIFO High Threshold Select */
 164        {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
 165};
 166
 167static struct display_queue_expire_num display_queue_expire_num_reg = {
 168        /* IGA1 Display Queue Expire Num */
 169        {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
 170        /* IGA2 Display Queue Expire Num */
 171        {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
 172};
 173
 174/* Definition Fetch Count Registers*/
 175static struct fetch_count fetch_count_reg = {
 176        /* IGA1 Fetch Count Register */
 177        {IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
 178        /* IGA2 Fetch Count Register */
 179        {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
 180};
 181
 182static struct iga1_crtc_timing iga1_crtc_reg = {
 183        /* IGA1 Horizontal Total */
 184        {IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } },
 185        /* IGA1 Horizontal Addressable Video */
 186        {IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } },
 187        /* IGA1 Horizontal Blank Start */
 188        {IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } },
 189        /* IGA1 Horizontal Blank End */
 190        {IGA1_HOR_BLANK_END_REG_NUM,
 191         {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } },
 192        /* IGA1 Horizontal Sync Start */
 193        {IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } },
 194        /* IGA1 Horizontal Sync End */
 195        {IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } },
 196        /* IGA1 Vertical Total */
 197        {IGA1_VER_TOTAL_REG_NUM,
 198         {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } },
 199        /* IGA1 Vertical Addressable Video */
 200        {IGA1_VER_ADDR_REG_NUM,
 201         {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } },
 202        /* IGA1 Vertical Blank Start */
 203        {IGA1_VER_BLANK_START_REG_NUM,
 204         {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } },
 205        /* IGA1 Vertical Blank End */
 206        {IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } },
 207        /* IGA1 Vertical Sync Start */
 208        {IGA1_VER_SYNC_START_REG_NUM,
 209         {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } },
 210        /* IGA1 Vertical Sync End */
 211        {IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } }
 212};
 213
 214static struct iga2_crtc_timing iga2_crtc_reg = {
 215        /* IGA2 Horizontal Total */
 216        {IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } },
 217        /* IGA2 Horizontal Addressable Video */
 218        {IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } },
 219        /* IGA2 Horizontal Blank Start */
 220        {IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } },
 221        /* IGA2 Horizontal Blank End */
 222        {IGA2_HOR_BLANK_END_REG_NUM,
 223         {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } },
 224        /* IGA2 Horizontal Sync Start */
 225        {IGA2_HOR_SYNC_START_REG_NUM,
 226         {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } },
 227        /* IGA2 Horizontal Sync End */
 228        {IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } },
 229        /* IGA2 Vertical Total */
 230        {IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } },
 231        /* IGA2 Vertical Addressable Video */
 232        {IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } },
 233        /* IGA2 Vertical Blank Start */
 234        {IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } },
 235        /* IGA2 Vertical Blank End */
 236        {IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } },
 237        /* IGA2 Vertical Sync Start */
 238        {IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } },
 239        /* IGA2 Vertical Sync End */
 240        {IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } }
 241};
 242
 243static struct rgbLUT palLUT_table[] = {
 244        /* {R,G,B} */
 245        /* Index 0x00~0x03 */
 246        {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
 247                                                                     0x2A,
 248                                                                     0x2A},
 249        /* Index 0x04~0x07 */
 250        {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
 251                                                                     0x2A,
 252                                                                     0x2A},
 253        /* Index 0x08~0x0B */
 254        {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
 255                                                                     0x3F,
 256                                                                     0x3F},
 257        /* Index 0x0C~0x0F */
 258        {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
 259                                                                     0x3F,
 260                                                                     0x3F},
 261        /* Index 0x10~0x13 */
 262        {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
 263                                                                     0x0B,
 264                                                                     0x0B},
 265        /* Index 0x14~0x17 */
 266        {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
 267                                                                     0x18,
 268                                                                     0x18},
 269        /* Index 0x18~0x1B */
 270        {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
 271                                                                     0x28,
 272                                                                     0x28},
 273        /* Index 0x1C~0x1F */
 274        {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
 275                                                                     0x3F,
 276                                                                     0x3F},
 277        /* Index 0x20~0x23 */
 278        {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
 279                                                                     0x00,
 280                                                                     0x3F},
 281        /* Index 0x24~0x27 */
 282        {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
 283                                                                     0x00,
 284                                                                     0x10},
 285        /* Index 0x28~0x2B */
 286        {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
 287                                                                     0x2F,
 288                                                                     0x00},
 289        /* Index 0x2C~0x2F */
 290        {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
 291                                                                     0x3F,
 292                                                                     0x00},
 293        /* Index 0x30~0x33 */
 294        {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
 295                                                                     0x3F,
 296                                                                     0x2F},
 297        /* Index 0x34~0x37 */
 298        {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
 299                                                                     0x10,
 300                                                                     0x3F},
 301        /* Index 0x38~0x3B */
 302        {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
 303                                                                     0x1F,
 304                                                                     0x3F},
 305        /* Index 0x3C~0x3F */
 306        {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
 307                                                                     0x1F,
 308                                                                     0x27},
 309        /* Index 0x40~0x43 */
 310        {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
 311                                                                     0x3F,
 312                                                                     0x1F},
 313        /* Index 0x44~0x47 */
 314        {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
 315                                                                     0x3F,
 316                                                                     0x1F},
 317        /* Index 0x48~0x4B */
 318        {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
 319                                                                     0x3F,
 320                                                                     0x37},
 321        /* Index 0x4C~0x4F */
 322        {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
 323                                                                     0x27,
 324                                                                     0x3F},
 325        /* Index 0x50~0x53 */
 326        {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
 327                                                                     0x2D,
 328                                                                     0x3F},
 329        /* Index 0x54~0x57 */
 330        {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
 331                                                                     0x2D,
 332                                                                     0x31},
 333        /* Index 0x58~0x5B */
 334        {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
 335                                                                     0x3A,
 336                                                                     0x2D},
 337        /* Index 0x5C~0x5F */
 338        {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
 339                                                                     0x3F,
 340                                                                     0x2D},
 341        /* Index 0x60~0x63 */
 342        {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
 343                                                                     0x3F,
 344                                                                     0x3A},
 345        /* Index 0x64~0x67 */
 346        {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
 347                                                                     0x31,
 348                                                                     0x3F},
 349        /* Index 0x68~0x6B */
 350        {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
 351                                                                     0x00,
 352                                                                     0x1C},
 353        /* Index 0x6C~0x6F */
 354        {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
 355                                                                     0x00,
 356                                                                     0x07},
 357        /* Index 0x70~0x73 */
 358        {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
 359                                                                     0x15,
 360                                                                     0x00},
 361        /* Index 0x74~0x77 */
 362        {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
 363                                                                     0x1C,
 364                                                                     0x00},
 365        /* Index 0x78~0x7B */
 366        {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
 367                                                                     0x1C,
 368                                                                     0x15},
 369        /* Index 0x7C~0x7F */
 370        {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
 371                                                                     0x07,
 372                                                                     0x1C},
 373        /* Index 0x80~0x83 */
 374        {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
 375                                                                     0x0E,
 376                                                                     0x1C},
 377        /* Index 0x84~0x87 */
 378        {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
 379                                                                     0x0E,
 380                                                                     0x11},
 381        /* Index 0x88~0x8B */
 382        {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
 383                                                                     0x18,
 384                                                                     0x0E},
 385        /* Index 0x8C~0x8F */
 386        {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
 387                                                                     0x1C,
 388                                                                     0x0E},
 389        /* Index 0x90~0x93 */
 390        {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
 391                                                                     0x1C,
 392                                                                     0x18},
 393        /* Index 0x94~0x97 */
 394        {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
 395                                                                     0x11,
 396                                                                     0x1C},
 397        /* Index 0x98~0x9B */
 398        {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
 399                                                                     0x14,
 400                                                                     0x1C},
 401        /* Index 0x9C~0x9F */
 402        {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
 403                                                                     0x14,
 404                                                                     0x16},
 405        /* Index 0xA0~0xA3 */
 406        {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
 407                                                                     0x1A,
 408                                                                     0x14},
 409        /* Index 0xA4~0xA7 */
 410        {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
 411                                                                     0x1C,
 412                                                                     0x14},
 413        /* Index 0xA8~0xAB */
 414        {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
 415                                                                     0x1C,
 416                                                                     0x1A},
 417        /* Index 0xAC~0xAF */
 418        {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
 419                                                                     0x16,
 420                                                                     0x1C},
 421        /* Index 0xB0~0xB3 */
 422        {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
 423                                                                     0x00,
 424                                                                     0x10},
 425        /* Index 0xB4~0xB7 */
 426        {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
 427                                                                     0x00,
 428                                                                     0x04},
 429        /* Index 0xB8~0xBB */
 430        {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
 431                                                                     0x0C,
 432                                                                     0x00},
 433        /* Index 0xBC~0xBF */
 434        {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
 435                                                                     0x10,
 436                                                                     0x00},
 437        /* Index 0xC0~0xC3 */
 438        {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
 439                                                                     0x10,
 440                                                                     0x0C},
 441        /* Index 0xC4~0xC7 */
 442        {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
 443                                                                     0x04,
 444                                                                     0x10},
 445        /* Index 0xC8~0xCB */
 446        {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
 447                                                                     0x08,
 448                                                                     0x10},
 449        /* Index 0xCC~0xCF */
 450        {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
 451                                                                     0x08,
 452                                                                     0x0A},
 453        /* Index 0xD0~0xD3 */
 454        {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
 455                                                                     0x0E,
 456                                                                     0x08},
 457        /* Index 0xD4~0xD7 */
 458        {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
 459                                                                     0x10,
 460                                                                     0x08},
 461        /* Index 0xD8~0xDB */
 462        {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
 463                                                                     0x10,
 464                                                                     0x0E},
 465        /* Index 0xDC~0xDF */
 466        {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
 467                                                                     0x0A,
 468                                                                     0x10},
 469        /* Index 0xE0~0xE3 */
 470        {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
 471                                                                     0x0B,
 472                                                                     0x10},
 473        /* Index 0xE4~0xE7 */
 474        {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
 475                                                                     0x0B,
 476                                                                     0x0C},
 477        /* Index 0xE8~0xEB */
 478        {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
 479                                                                     0x0F,
 480                                                                     0x0B},
 481        /* Index 0xEC~0xEF */
 482        {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
 483                                                                     0x10,
 484                                                                     0x0B},
 485        /* Index 0xF0~0xF3 */
 486        {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
 487                                                                     0x10,
 488                                                                     0x0F},
 489        /* Index 0xF4~0xF7 */
 490        {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
 491                                                                     0x0C,
 492                                                                     0x10},
 493        /* Index 0xF8~0xFB */
 494        {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
 495                                                                     0x00,
 496                                                                     0x00},
 497        /* Index 0xFC~0xFF */
 498        {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
 499                                                                     0x00,
 500                                                                     0x00}
 501};
 502
 503static void set_crt_output_path(int set_iga);
 504static void dvi_patch_skew_dvp0(void);
 505static void dvi_patch_skew_dvp1(void);
 506static void dvi_patch_skew_dvp_low(void);
 507static void set_dvi_output_path(int set_iga, int output_interface);
 508static void set_lcd_output_path(int set_iga, int output_interface);
 509static int search_mode_setting(int ModeInfoIndex);
 510static void load_fix_bit_crtc_reg(void);
 511static void init_gfx_chip_info(void);
 512static void init_tmds_chip_info(void);
 513static void init_lvds_chip_info(void);
 514static void device_screen_off(void);
 515static void device_screen_on(void);
 516static void set_display_channel(void);
 517static void device_off(void);
 518static void device_on(void);
 519static void enable_second_display_channel(void);
 520static void disable_second_display_channel(void);
 521static int get_fb_size_from_pci(void);
 522
 523void viafb_write_reg(u8 index, u16 io_port, u8 data)
 524{
 525        outb(index, io_port);
 526        outb(data, io_port + 1);
 527        /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, data); */
 528}
 529u8 viafb_read_reg(int io_port, u8 index)
 530{
 531        outb(index, io_port);
 532        return inb(io_port + 1);
 533}
 534
 535void viafb_lock_crt(void)
 536{
 537        viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
 538}
 539
 540void viafb_unlock_crt(void)
 541{
 542        viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
 543        viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
 544}
 545
 546void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask)
 547{
 548        u8 tmp;
 549
 550        outb(index, io_port);
 551        tmp = inb(io_port + 1);
 552        outb((data & mask) | (tmp & (~mask)), io_port + 1);
 553        /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, tmp); */
 554}
 555
 556void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
 557{
 558        outb(index, LUT_INDEX_WRITE);
 559        outb(r, LUT_DATA);
 560        outb(g, LUT_DATA);
 561        outb(b, LUT_DATA);
 562}
 563
 564/*Set IGA path for each device*/
 565void viafb_set_iga_path(void)
 566{
 567
 568        if (viafb_SAMM_ON == 1) {
 569                if (viafb_CRT_ON) {
 570                        if (viafb_primary_dev == CRT_Device)
 571                                viaparinfo->crt_setting_info->iga_path = IGA1;
 572                        else
 573                                viaparinfo->crt_setting_info->iga_path = IGA2;
 574                }
 575
 576                if (viafb_DVI_ON) {
 577                        if (viafb_primary_dev == DVI_Device)
 578                                viaparinfo->tmds_setting_info->iga_path = IGA1;
 579                        else
 580                                viaparinfo->tmds_setting_info->iga_path = IGA2;
 581                }
 582
 583                if (viafb_LCD_ON) {
 584                        if (viafb_primary_dev == LCD_Device) {
 585                                if (viafb_dual_fb &&
 586                                        (viaparinfo->chip_info->gfx_chip_name ==
 587                                        UNICHROME_CLE266)) {
 588                                        viaparinfo->
 589                                        lvds_setting_info->iga_path = IGA2;
 590                                        viaparinfo->
 591                                        crt_setting_info->iga_path = IGA1;
 592                                        viaparinfo->
 593                                        tmds_setting_info->iga_path = IGA1;
 594                                } else
 595                                        viaparinfo->
 596                                        lvds_setting_info->iga_path = IGA1;
 597                        } else {
 598                                viaparinfo->lvds_setting_info->iga_path = IGA2;
 599                        }
 600                }
 601                if (viafb_LCD2_ON) {
 602                        if (LCD2_Device == viafb_primary_dev)
 603                                viaparinfo->lvds_setting_info2->iga_path = IGA1;
 604                        else
 605                                viaparinfo->lvds_setting_info2->iga_path = IGA2;
 606                }
 607        } else {
 608                viafb_SAMM_ON = 0;
 609
 610                if (viafb_CRT_ON && viafb_LCD_ON) {
 611                        viaparinfo->crt_setting_info->iga_path = IGA1;
 612                        viaparinfo->lvds_setting_info->iga_path = IGA2;
 613                } else if (viafb_CRT_ON && viafb_DVI_ON) {
 614                        viaparinfo->crt_setting_info->iga_path = IGA1;
 615                        viaparinfo->tmds_setting_info->iga_path = IGA2;
 616                } else if (viafb_LCD_ON && viafb_DVI_ON) {
 617                        viaparinfo->tmds_setting_info->iga_path = IGA1;
 618                        viaparinfo->lvds_setting_info->iga_path = IGA2;
 619                } else if (viafb_LCD_ON && viafb_LCD2_ON) {
 620                        viaparinfo->lvds_setting_info->iga_path = IGA2;
 621                        viaparinfo->lvds_setting_info2->iga_path = IGA2;
 622                } else if (viafb_CRT_ON) {
 623                        viaparinfo->crt_setting_info->iga_path = IGA1;
 624                } else if (viafb_LCD_ON) {
 625                        viaparinfo->lvds_setting_info->iga_path = IGA2;
 626                } else if (viafb_DVI_ON) {
 627                        viaparinfo->tmds_setting_info->iga_path = IGA1;
 628                }
 629        }
 630}
 631
 632void viafb_set_start_addr(void)
 633{
 634        unsigned long offset = 0, tmp = 0, size = 0;
 635        unsigned long length;
 636
 637        DEBUG_MSG(KERN_INFO "viafb_set_start_addr!\n");
 638        viafb_unlock_crt();
 639        /* update starting address of IGA1 */
 640        viafb_write_reg(CR0C, VIACR, 0x00);        /*initial starting address */
 641        viafb_write_reg(CR0D, VIACR, 0x00);
 642        viafb_write_reg(CR34, VIACR, 0x00);
 643        viafb_write_reg_mask(CR48, VIACR, 0x00, 0x1F);
 644
 645        if (viafb_dual_fb) {
 646                viaparinfo->iga_path = IGA1;
 647                viaparinfo1->iga_path = IGA2;
 648        }
 649
 650        if (viafb_SAMM_ON == 1) {
 651                if (!viafb_dual_fb) {
 652                        if (viafb_second_size)
 653                                size = viafb_second_size * 1024 * 1024;
 654                        else
 655                                size = 8 * 1024 * 1024;
 656                } else {
 657
 658                        size = viaparinfo1->memsize;
 659                }
 660                offset = viafb_second_offset;
 661                DEBUG_MSG(KERN_INFO
 662                          "viafb_second_size=%lx, second start_adddress=%lx\n",
 663                          size, offset);
 664        }
 665        if (viafb_SAMM_ON == 1) {
 666                offset = offset >> 3;
 667
 668                tmp = viafb_read_reg(VIACR, 0x62) & 0x01;
 669                tmp |= (offset & 0x7F) << 1;
 670                viafb_write_reg(CR62, VIACR, tmp);
 671                viafb_write_reg(CR63, VIACR, ((offset & 0x7F80) >> 7));
 672                viafb_write_reg(CR64, VIACR, ((offset & 0x7F8000) >> 15));
 673                viafb_write_reg(CRA3, VIACR, ((offset & 0x3800000) >> 23));
 674        } else {
 675                /* update starting address */
 676                viafb_write_reg(CR62, VIACR, 0x00);
 677                viafb_write_reg(CR63, VIACR, 0x00);
 678                viafb_write_reg(CR64, VIACR, 0x00);
 679                viafb_write_reg(CRA3, VIACR, 0x00);
 680        }
 681
 682        if (viafb_SAMM_ON == 1) {
 683                if (viafb_accel) {
 684                        if (!viafb_dual_fb)
 685                                length = size - viaparinfo->fbmem_used;
 686                        else
 687                                length = size - viaparinfo1->fbmem_used;
 688                } else
 689                        length = size;
 690                offset = (unsigned long)(void *)viafb_FB_MM +
 691                        viafb_second_offset;
 692                memset((void *)offset, 0, length);
 693        }
 694
 695        viafb_lock_crt();
 696}
 697
 698void viafb_set_output_path(int device, int set_iga, int output_interface)
 699{
 700        switch (device) {
 701        case DEVICE_CRT:
 702                set_crt_output_path(set_iga);
 703                break;
 704        case DEVICE_DVI:
 705                set_dvi_output_path(set_iga, output_interface);
 706                break;
 707        case DEVICE_LCD:
 708                set_lcd_output_path(set_iga, output_interface);
 709                break;
 710        }
 711}
 712
 713static void set_crt_output_path(int set_iga)
 714{
 715        viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
 716
 717        switch (set_iga) {
 718        case IGA1:
 719                viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6);
 720                break;
 721        case IGA2:
 722        case IGA1_IGA2:
 723                viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
 724                viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6);
 725                if (set_iga == IGA1_IGA2)
 726                        viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
 727                break;
 728        }
 729}
 730
 731static void dvi_patch_skew_dvp0(void)
 732{
 733        /* Reset data driving first: */
 734        viafb_write_reg_mask(SR1B, VIASR, 0, BIT1);
 735        viafb_write_reg_mask(SR2A, VIASR, 0, BIT4);
 736
 737        switch (viaparinfo->chip_info->gfx_chip_name) {
 738        case UNICHROME_P4M890:
 739                {
 740                        if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
 741                                (viaparinfo->tmds_setting_info->v_active ==
 742                                1200))
 743                                viafb_write_reg_mask(CR96, VIACR, 0x03,
 744                                               BIT0 + BIT1 + BIT2);
 745                        else
 746                                viafb_write_reg_mask(CR96, VIACR, 0x07,
 747                                               BIT0 + BIT1 + BIT2);
 748                        break;
 749                }
 750
 751        case UNICHROME_P4M900:
 752                {
 753                        viafb_write_reg_mask(CR96, VIACR, 0x07,
 754                                       BIT0 + BIT1 + BIT2 + BIT3);
 755                        viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1);
 756                        viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4);
 757                        break;
 758                }
 759
 760        default:
 761                {
 762                        break;
 763                }
 764        }
 765}
 766
 767static void dvi_patch_skew_dvp1(void)
 768{
 769        switch (viaparinfo->chip_info->gfx_chip_name) {
 770        case UNICHROME_CX700:
 771                {
 772                        break;
 773                }
 774
 775        default:
 776                {
 777                        break;
 778                }
 779        }
 780}
 781
 782static void dvi_patch_skew_dvp_low(void)
 783{
 784        switch (viaparinfo->chip_info->gfx_chip_name) {
 785        case UNICHROME_K8M890:
 786                {
 787                        viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1);
 788                        break;
 789                }
 790
 791        case UNICHROME_P4M900:
 792                {
 793                        viafb_write_reg_mask(CR99, VIACR, 0x08,
 794                                       BIT0 + BIT1 + BIT2 + BIT3);
 795                        break;
 796                }
 797
 798        case UNICHROME_P4M890:
 799                {
 800                        viafb_write_reg_mask(CR99, VIACR, 0x0F,
 801                                       BIT0 + BIT1 + BIT2 + BIT3);
 802                        break;
 803                }
 804
 805        default:
 806                {
 807                        break;
 808                }
 809        }
 810}
 811
 812static void set_dvi_output_path(int set_iga, int output_interface)
 813{
 814        switch (output_interface) {
 815        case INTERFACE_DVP0:
 816                viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0);
 817
 818                if (set_iga == IGA1) {
 819                        viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
 820                        viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 +
 821                                BIT5 + BIT7);
 822                } else {
 823                        viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
 824                        viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 +
 825                                BIT5 + BIT7);
 826                }
 827
 828                viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6);
 829
 830                dvi_patch_skew_dvp0();
 831                break;
 832
 833        case INTERFACE_DVP1:
 834                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
 835                        if (set_iga == IGA1)
 836                                viafb_write_reg_mask(CR93, VIACR, 0x21,
 837                                               BIT0 + BIT5 + BIT7);
 838                        else
 839                                viafb_write_reg_mask(CR93, VIACR, 0xA1,
 840                                               BIT0 + BIT5 + BIT7);
 841                } else {
 842                        if (set_iga == IGA1)
 843                                viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
 844                        else
 845                                viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
 846                }
 847
 848                viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5);
 849                dvi_patch_skew_dvp1();
 850                break;
 851        case INTERFACE_DFP_HIGH:
 852                if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) {
 853                        if (set_iga == IGA1) {
 854                                viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
 855                                viafb_write_reg_mask(CR97, VIACR, 0x03,
 856                                               BIT0 + BIT1 + BIT4);
 857                        } else {
 858                                viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
 859                                viafb_write_reg_mask(CR97, VIACR, 0x13,
 860                                               BIT0 + BIT1 + BIT4);
 861                        }
 862                }
 863                viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3);
 864                break;
 865
 866        case INTERFACE_DFP_LOW:
 867                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
 868                        break;
 869
 870                if (set_iga == IGA1) {
 871                        viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
 872                        viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
 873                } else {
 874                        viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
 875                        viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
 876                }
 877
 878                viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
 879                dvi_patch_skew_dvp_low();
 880                break;
 881
 882        case INTERFACE_TMDS:
 883                if (set_iga == IGA1)
 884                        viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
 885                else
 886                        viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
 887                break;
 888        }
 889
 890        if (set_iga == IGA2) {
 891                enable_second_display_channel();
 892                /* Disable LCD Scaling */
 893                viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0);
 894        }
 895}
 896
 897static void set_lcd_output_path(int set_iga, int output_interface)
 898{
 899        DEBUG_MSG(KERN_INFO
 900                  "set_lcd_output_path, iga:%d,out_interface:%d\n",
 901                  set_iga, output_interface);
 902        switch (set_iga) {
 903        case IGA1:
 904                viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
 905                viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
 906
 907                disable_second_display_channel();
 908                break;
 909
 910        case IGA2:
 911                viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
 912                viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
 913
 914                enable_second_display_channel();
 915                break;
 916
 917        case IGA1_IGA2:
 918                viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
 919                viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
 920
 921                disable_second_display_channel();
 922                break;
 923        }
 924
 925        switch (output_interface) {
 926        case INTERFACE_DVP0:
 927                if (set_iga == IGA1) {
 928                        viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
 929                } else {
 930                        viafb_write_reg(CR91, VIACR, 0x00);
 931                        viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
 932                }
 933                break;
 934
 935        case INTERFACE_DVP1:
 936                if (set_iga == IGA1)
 937                        viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
 938                else {
 939                        viafb_write_reg(CR91, VIACR, 0x00);
 940                        viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
 941                }
 942                break;
 943
 944        case INTERFACE_DFP_HIGH:
 945                if (set_iga == IGA1)
 946                        viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
 947                else {
 948                        viafb_write_reg(CR91, VIACR, 0x00);
 949                        viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
 950                        viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
 951                }
 952                break;
 953
 954        case INTERFACE_DFP_LOW:
 955                if (set_iga == IGA1)
 956                        viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
 957                else {
 958                        viafb_write_reg(CR91, VIACR, 0x00);
 959                        viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
 960                        viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
 961                }
 962
 963                break;
 964
 965        case INTERFACE_DFP:
 966                if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
 967                    || (UNICHROME_P4M890 ==
 968                    viaparinfo->chip_info->gfx_chip_name))
 969                        viafb_write_reg_mask(CR97, VIACR, 0x84,
 970                                       BIT7 + BIT2 + BIT1 + BIT0);
 971                if (set_iga == IGA1) {
 972                        viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
 973                        viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
 974                } else {
 975                        viafb_write_reg(CR91, VIACR, 0x00);
 976                        viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
 977                        viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
 978                }
 979                break;
 980
 981        case INTERFACE_LVDS0:
 982        case INTERFACE_LVDS0LVDS1:
 983                if (set_iga == IGA1)
 984                        viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
 985                else
 986                        viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
 987
 988                break;
 989
 990        case INTERFACE_LVDS1:
 991                if (set_iga == IGA1)
 992                        viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
 993                else
 994                        viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
 995                break;
 996        }
 997}
 998
 999/* Search Mode Index */
1000static int search_mode_setting(int ModeInfoIndex)
1001{
1002        int i = 0;
1003
1004        while ((i < NUM_TOTAL_MODETABLE) &&
1005                        (ModeInfoIndex != CLE266Modes[i].ModeIndex))
1006                i++;
1007        if (i >= NUM_TOTAL_MODETABLE)
1008                i = 0;
1009        return i;
1010
1011}
1012
1013struct VideoModeTable *viafb_get_modetbl_pointer(int Index)
1014{
1015        struct VideoModeTable *TmpTbl = NULL;
1016        TmpTbl = &CLE266Modes[search_mode_setting(Index)];
1017        return TmpTbl;
1018}
1019
1020struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index)
1021{
1022        struct VideoModeTable *TmpTbl = NULL;
1023        int i = 0;
1024        while ((i < NUM_TOTAL_CEA_MODES) &&
1025                        (Index != CEA_HDMI_Modes[i].ModeIndex))
1026                i++;
1027        if ((i < NUM_TOTAL_CEA_MODES))
1028                TmpTbl = &CEA_HDMI_Modes[i];
1029         else {
1030                /*Still use general timing if don't find CEA timing */
1031                i = 0;
1032                while ((i < NUM_TOTAL_MODETABLE) &&
1033                                (Index != CLE266Modes[i].ModeIndex))
1034                       i++;
1035                if (i >= NUM_TOTAL_MODETABLE)
1036                        i = 0;
1037                TmpTbl = &CLE266Modes[i];
1038        }
1039        return TmpTbl;
1040}
1041
1042static void load_fix_bit_crtc_reg(void)
1043{
1044        /* always set to 1 */
1045        viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
1046        /* line compare should set all bits = 1 (extend modes) */
1047        viafb_write_reg(CR18, VIACR, 0xff);
1048        /* line compare should set all bits = 1 (extend modes) */
1049        viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4);
1050        /* line compare should set all bits = 1 (extend modes) */
1051        viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6);
1052        /* line compare should set all bits = 1 (extend modes) */
1053        viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
1054        /* line compare should set all bits = 1 (extend modes) */
1055        viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
1056        /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
1057        /* extend mode always set to e3h */
1058        viafb_write_reg(CR17, VIACR, 0xe3);
1059        /* extend mode always set to 0h */
1060        viafb_write_reg(CR08, VIACR, 0x00);
1061        /* extend mode always set to 0h */
1062        viafb_write_reg(CR14, VIACR, 0x00);
1063
1064        /* If K8M800, enable Prefetch Mode. */
1065        if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
1066                || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
1067                viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
1068        if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
1069            && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
1070                viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
1071
1072}
1073
1074void viafb_load_reg(int timing_value, int viafb_load_reg_num,
1075        struct io_register *reg,
1076              int io_type)
1077{
1078        int reg_mask;
1079        int bit_num = 0;
1080        int data;
1081        int i, j;
1082        int shift_next_reg;
1083        int start_index, end_index, cr_index;
1084        u16 get_bit;
1085
1086        for (i = 0; i < viafb_load_reg_num; i++) {
1087                reg_mask = 0;
1088                data = 0;
1089                start_index = reg[i].start_bit;
1090                end_index = reg[i].end_bit;
1091                cr_index = reg[i].io_addr;
1092
1093                shift_next_reg = bit_num;
1094                for (j = start_index; j <= end_index; j++) {
1095                        /*if (bit_num==8) timing_value = timing_value >>8; */
1096                        reg_mask = reg_mask | (BIT0 << j);
1097                        get_bit = (timing_value & (BIT0 << bit_num));
1098                        data =
1099                            data | ((get_bit >> shift_next_reg) << start_index);
1100                        bit_num++;
1101                }
1102                if (io_type == VIACR)
1103                        viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
1104                else
1105                        viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
1106        }
1107
1108}
1109
1110/* Write Registers */
1111void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
1112{
1113        int i;
1114        unsigned char RegTemp;
1115
1116        /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
1117
1118        for (i = 0; i < ItemNum; i++) {
1119                outb(RegTable[i].index, RegTable[i].port);
1120                RegTemp = inb(RegTable[i].port + 1);
1121                RegTemp = (RegTemp & (~RegTable[i].mask)) | RegTable[i].value;
1122                outb(RegTemp, RegTable[i].port + 1);
1123        }
1124}
1125
1126void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga)
1127{
1128        int reg_value;
1129        int viafb_load_reg_num;
1130        struct io_register *reg;
1131
1132        switch (set_iga) {
1133        case IGA1_IGA2:
1134        case IGA1:
1135                reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte);
1136                viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num;
1137                reg = offset_reg.iga1_offset_reg.reg;
1138                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1139                if (set_iga == IGA1)
1140                        break;
1141        case IGA2:
1142                reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte);
1143                viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
1144                reg = offset_reg.iga2_offset_reg.reg;
1145                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1146                break;
1147        }
1148}
1149
1150void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
1151{
1152        int reg_value;
1153        int viafb_load_reg_num;
1154        struct io_register *reg = NULL;
1155
1156        switch (set_iga) {
1157        case IGA1_IGA2:
1158        case IGA1:
1159                reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1160                viafb_load_reg_num = fetch_count_reg.
1161                        iga1_fetch_count_reg.reg_num;
1162                reg = fetch_count_reg.iga1_fetch_count_reg.reg;
1163                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1164                if (set_iga == IGA1)
1165                        break;
1166        case IGA2:
1167                reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1168                viafb_load_reg_num = fetch_count_reg.
1169                        iga2_fetch_count_reg.reg_num;
1170                reg = fetch_count_reg.iga2_fetch_count_reg.reg;
1171                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1172                break;
1173        }
1174
1175}
1176
1177void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1178{
1179        int reg_value;
1180        int viafb_load_reg_num;
1181        struct io_register *reg = NULL;
1182        int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
1183            0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
1184        int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
1185            0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
1186
1187        if (set_iga == IGA1) {
1188                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1189                        iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
1190                        iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
1191                        iga1_fifo_high_threshold =
1192                            K800_IGA1_FIFO_HIGH_THRESHOLD;
1193                        /* If resolution > 1280x1024, expire length = 64, else
1194                           expire length = 128 */
1195                        if ((hor_active > 1280) && (ver_active > 1024))
1196                                iga1_display_queue_expire_num = 16;
1197                        else
1198                                iga1_display_queue_expire_num =
1199                                    K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1200
1201                }
1202
1203                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1204                        iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
1205                        iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
1206                        iga1_fifo_high_threshold =
1207                            P880_IGA1_FIFO_HIGH_THRESHOLD;
1208                        iga1_display_queue_expire_num =
1209                            P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1210
1211                        /* If resolution > 1280x1024, expire length = 64, else
1212                           expire length = 128 */
1213                        if ((hor_active > 1280) && (ver_active > 1024))
1214                                iga1_display_queue_expire_num = 16;
1215                        else
1216                                iga1_display_queue_expire_num =
1217                                    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1218                }
1219
1220                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1221                        iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
1222                        iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
1223                        iga1_fifo_high_threshold =
1224                            CN700_IGA1_FIFO_HIGH_THRESHOLD;
1225
1226                        /* If resolution > 1280x1024, expire length = 64,
1227                           else expire length = 128 */
1228                        if ((hor_active > 1280) && (ver_active > 1024))
1229                                iga1_display_queue_expire_num = 16;
1230                        else
1231                                iga1_display_queue_expire_num =
1232                                    CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1233                }
1234
1235                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1236                        iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
1237                        iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
1238                        iga1_fifo_high_threshold =
1239                            CX700_IGA1_FIFO_HIGH_THRESHOLD;
1240                        iga1_display_queue_expire_num =
1241                            CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1242                }
1243
1244                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1245                        iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
1246                        iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
1247                        iga1_fifo_high_threshold =
1248                            K8M890_IGA1_FIFO_HIGH_THRESHOLD;
1249                        iga1_display_queue_expire_num =
1250                            K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1251                }
1252
1253                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1254                        iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
1255                        iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
1256                        iga1_fifo_high_threshold =
1257                            P4M890_IGA1_FIFO_HIGH_THRESHOLD;
1258                        iga1_display_queue_expire_num =
1259                            P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1260                }
1261
1262                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1263                        iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
1264                        iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
1265                        iga1_fifo_high_threshold =
1266                            P4M900_IGA1_FIFO_HIGH_THRESHOLD;
1267                        iga1_display_queue_expire_num =
1268                            P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1269                }
1270
1271                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1272                        iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
1273                        iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
1274                        iga1_fifo_high_threshold =
1275                            VX800_IGA1_FIFO_HIGH_THRESHOLD;
1276                        iga1_display_queue_expire_num =
1277                            VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1278                }
1279
1280                /* Set Display FIFO Depath Select */
1281                reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
1282                viafb_load_reg_num =
1283                    display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
1284                reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
1285                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1286
1287                /* Set Display FIFO Threshold Select */
1288                reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
1289                viafb_load_reg_num =
1290                    fifo_threshold_select_reg.
1291                    iga1_fifo_threshold_select_reg.reg_num;
1292                reg =
1293                    fifo_threshold_select_reg.
1294                    iga1_fifo_threshold_select_reg.reg;
1295                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1296
1297                /* Set FIFO High Threshold Select */
1298                reg_value =
1299                    IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
1300                viafb_load_reg_num =
1301                    fifo_high_threshold_select_reg.
1302                    iga1_fifo_high_threshold_select_reg.reg_num;
1303                reg =
1304                    fifo_high_threshold_select_reg.
1305                    iga1_fifo_high_threshold_select_reg.reg;
1306                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1307
1308                /* Set Display Queue Expire Num */
1309                reg_value =
1310                    IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1311                    (iga1_display_queue_expire_num);
1312                viafb_load_reg_num =
1313                    display_queue_expire_num_reg.
1314                    iga1_display_queue_expire_num_reg.reg_num;
1315                reg =
1316                    display_queue_expire_num_reg.
1317                    iga1_display_queue_expire_num_reg.reg;
1318                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1319
1320        } else {
1321                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1322                        iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
1323                        iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
1324                        iga2_fifo_high_threshold =
1325                            K800_IGA2_FIFO_HIGH_THRESHOLD;
1326
1327                        /* If resolution > 1280x1024, expire length = 64,
1328                           else  expire length = 128 */
1329                        if ((hor_active > 1280) && (ver_active > 1024))
1330                                iga2_display_queue_expire_num = 16;
1331                        else
1332                                iga2_display_queue_expire_num =
1333                                    K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1334                }
1335
1336                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1337                        iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
1338                        iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
1339                        iga2_fifo_high_threshold =
1340                            P880_IGA2_FIFO_HIGH_THRESHOLD;
1341
1342                        /* If resolution > 1280x1024, expire length = 64,
1343                           else  expire length = 128 */
1344                        if ((hor_active > 1280) && (ver_active > 1024))
1345                                iga2_display_queue_expire_num = 16;
1346                        else
1347                                iga2_display_queue_expire_num =
1348                                    P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1349                }
1350
1351                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1352                        iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
1353                        iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
1354                        iga2_fifo_high_threshold =
1355                            CN700_IGA2_FIFO_HIGH_THRESHOLD;
1356
1357                        /* If resolution > 1280x1024, expire length = 64,
1358                           else expire length = 128 */
1359                        if ((hor_active > 1280) && (ver_active > 1024))
1360                                iga2_display_queue_expire_num = 16;
1361                        else
1362                                iga2_display_queue_expire_num =
1363                                    CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1364                }
1365
1366                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1367                        iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
1368                        iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
1369                        iga2_fifo_high_threshold =
1370                            CX700_IGA2_FIFO_HIGH_THRESHOLD;
1371                        iga2_display_queue_expire_num =
1372                            CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1373                }
1374
1375                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1376                        iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
1377                        iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
1378                        iga2_fifo_high_threshold =
1379                            K8M890_IGA2_FIFO_HIGH_THRESHOLD;
1380                        iga2_display_queue_expire_num =
1381                            K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1382                }
1383
1384                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1385                        iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
1386                        iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
1387                        iga2_fifo_high_threshold =
1388                            P4M890_IGA2_FIFO_HIGH_THRESHOLD;
1389                        iga2_display_queue_expire_num =
1390                            P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1391                }
1392
1393                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1394                        iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
1395                        iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
1396                        iga2_fifo_high_threshold =
1397                            P4M900_IGA2_FIFO_HIGH_THRESHOLD;
1398                        iga2_display_queue_expire_num =
1399                            P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1400                }
1401
1402                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1403                        iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
1404                        iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
1405                        iga2_fifo_high_threshold =
1406                            VX800_IGA2_FIFO_HIGH_THRESHOLD;
1407                        iga2_display_queue_expire_num =
1408                            VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1409                }
1410
1411                if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1412                        /* Set Display FIFO Depath Select */
1413                        reg_value =
1414                            IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
1415                            - 1;
1416                        /* Patch LCD in IGA2 case */
1417                        viafb_load_reg_num =
1418                            display_fifo_depth_reg.
1419                            iga2_fifo_depth_select_reg.reg_num;
1420                        reg =
1421                            display_fifo_depth_reg.
1422                            iga2_fifo_depth_select_reg.reg;
1423                        viafb_load_reg(reg_value,
1424                                viafb_load_reg_num, reg, VIACR);
1425                } else {
1426
1427                        /* Set Display FIFO Depath Select */
1428                        reg_value =
1429                            IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
1430                        viafb_load_reg_num =
1431                            display_fifo_depth_reg.
1432                            iga2_fifo_depth_select_reg.reg_num;
1433                        reg =
1434                            display_fifo_depth_reg.
1435                            iga2_fifo_depth_select_reg.reg;
1436                        viafb_load_reg(reg_value,
1437                                viafb_load_reg_num, reg, VIACR);
1438                }
1439
1440                /* Set Display FIFO Threshold Select */
1441                reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
1442                viafb_load_reg_num =
1443                    fifo_threshold_select_reg.
1444                    iga2_fifo_threshold_select_reg.reg_num;
1445                reg =
1446                    fifo_threshold_select_reg.
1447                    iga2_fifo_threshold_select_reg.reg;
1448                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1449
1450                /* Set FIFO High Threshold Select */
1451                reg_value =
1452                    IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
1453                viafb_load_reg_num =
1454                    fifo_high_threshold_select_reg.
1455                    iga2_fifo_high_threshold_select_reg.reg_num;
1456                reg =
1457                    fifo_high_threshold_select_reg.
1458                    iga2_fifo_high_threshold_select_reg.reg;
1459                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1460
1461                /* Set Display Queue Expire Num */
1462                reg_value =
1463                    IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1464                    (iga2_display_queue_expire_num);
1465                viafb_load_reg_num =
1466                    display_queue_expire_num_reg.
1467                    iga2_display_queue_expire_num_reg.reg_num;
1468                reg =
1469                    display_queue_expire_num_reg.
1470                    iga2_display_queue_expire_num_reg.reg;
1471                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1472
1473        }
1474
1475}
1476
1477u32 viafb_get_clk_value(int clk)
1478{
1479        int i;
1480
1481        for (i = 0; i < NUM_TOTAL_PLL_TABLE; i++) {
1482                if (clk == pll_value[i].clk) {
1483                        switch (viaparinfo->chip_info->gfx_chip_name) {
1484                        case UNICHROME_CLE266:
1485                        case UNICHROME_K400:
1486                                return pll_value[i].cle266_pll;
1487
1488                        case UNICHROME_K800:
1489                        case UNICHROME_PM800:
1490                        case UNICHROME_CN700:
1491                                return pll_value[i].k800_pll;
1492
1493                        case UNICHROME_CX700:
1494                        case UNICHROME_K8M890:
1495                        case UNICHROME_P4M890:
1496                        case UNICHROME_P4M900:
1497                        case UNICHROME_VX800:
1498                                return pll_value[i].cx700_pll;
1499                        }
1500                }
1501        }
1502
1503        DEBUG_MSG(KERN_INFO "Can't find match PLL value\n\n");
1504        return 0;
1505}
1506
1507/* Set VCLK*/
1508void viafb_set_vclock(u32 CLK, int set_iga)
1509{
1510        unsigned char RegTemp;
1511
1512        /* H.W. Reset : ON */
1513        viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1514
1515        if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
1516                /* Change D,N FOR VCLK */
1517                switch (viaparinfo->chip_info->gfx_chip_name) {
1518                case UNICHROME_CLE266:
1519                case UNICHROME_K400:
1520                        viafb_write_reg(SR46, VIASR, CLK / 0x100);
1521                        viafb_write_reg(SR47, VIASR, CLK % 0x100);
1522                        break;
1523
1524                case UNICHROME_K800:
1525                case UNICHROME_PM800:
1526                case UNICHROME_CN700:
1527                case UNICHROME_CX700:
1528                case UNICHROME_K8M890:
1529                case UNICHROME_P4M890:
1530                case UNICHROME_P4M900:
1531                case UNICHROME_VX800:
1532                        viafb_write_reg(SR44, VIASR, CLK / 0x10000);
1533                        DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000);
1534                        viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100);
1535                        DEBUG_MSG(KERN_INFO "\nSR45=%x",
1536                                  (CLK & 0xFFFF) / 0x100);
1537                        viafb_write_reg(SR46, VIASR, CLK % 0x100);
1538                        DEBUG_MSG(KERN_INFO "\nSR46=%x", CLK % 0x100);
1539                        break;
1540                }
1541        }
1542
1543        if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
1544                /* Change D,N FOR LCK */
1545                switch (viaparinfo->chip_info->gfx_chip_name) {
1546                case UNICHROME_CLE266:
1547                case UNICHROME_K400:
1548                        viafb_write_reg(SR44, VIASR, CLK / 0x100);
1549                        viafb_write_reg(SR45, VIASR, CLK % 0x100);
1550                        break;
1551
1552                case UNICHROME_K800:
1553                case UNICHROME_PM800:
1554                case UNICHROME_CN700:
1555                case UNICHROME_CX700:
1556                case UNICHROME_K8M890:
1557                case UNICHROME_P4M890:
1558                case UNICHROME_P4M900:
1559                case UNICHROME_VX800:
1560                        viafb_write_reg(SR4A, VIASR, CLK / 0x10000);
1561                        viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100);
1562                        viafb_write_reg(SR4C, VIASR, CLK % 0x100);
1563                        break;
1564                }
1565        }
1566
1567        /* H.W. Reset : OFF */
1568        viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1569
1570        /* Reset PLL */
1571        if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
1572                viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
1573                viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
1574        }
1575
1576        if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
1577                viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0);
1578                viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0);
1579        }
1580
1581        /* Fire! */
1582        RegTemp = inb(VIARMisc);
1583        outb(RegTemp | (BIT2 + BIT3), VIAWMisc);
1584}
1585
1586void viafb_load_crtc_timing(struct display_timing device_timing,
1587        int set_iga)
1588{
1589        int i;
1590        int viafb_load_reg_num = 0;
1591        int reg_value = 0;
1592        struct io_register *reg = NULL;
1593
1594        viafb_unlock_crt();
1595
1596        for (i = 0; i < 12; i++) {
1597                if (set_iga == IGA1) {
1598                        switch (i) {
1599                        case H_TOTAL_INDEX:
1600                                reg_value =
1601                                    IGA1_HOR_TOTAL_FORMULA(device_timing.
1602                                                           hor_total);
1603                                viafb_load_reg_num =
1604                                        iga1_crtc_reg.hor_total.reg_num;
1605                                reg = iga1_crtc_reg.hor_total.reg;
1606                                break;
1607                        case H_ADDR_INDEX:
1608                                reg_value =
1609                                    IGA1_HOR_ADDR_FORMULA(device_timing.
1610                                                          hor_addr);
1611                                viafb_load_reg_num =
1612                                        iga1_crtc_reg.hor_addr.reg_num;
1613                                reg = iga1_crtc_reg.hor_addr.reg;
1614                                break;
1615                        case H_BLANK_START_INDEX:
1616                                reg_value =
1617                                    IGA1_HOR_BLANK_START_FORMULA
1618                                    (device_timing.hor_blank_start);
1619                                viafb_load_reg_num =
1620                                    iga1_crtc_reg.hor_blank_start.reg_num;
1621                                reg = iga1_crtc_reg.hor_blank_start.reg;
1622                                break;
1623                        case H_BLANK_END_INDEX:
1624                                reg_value =
1625                                    IGA1_HOR_BLANK_END_FORMULA
1626                                    (device_timing.hor_blank_start,
1627                                     device_timing.hor_blank_end);
1628                                viafb_load_reg_num =
1629                                    iga1_crtc_reg.hor_blank_end.reg_num;
1630                                reg = iga1_crtc_reg.hor_blank_end.reg;
1631                                break;
1632                        case H_SYNC_START_INDEX:
1633                                reg_value =
1634                                    IGA1_HOR_SYNC_START_FORMULA
1635                                    (device_timing.hor_sync_start);
1636                                viafb_load_reg_num =
1637                                    iga1_crtc_reg.hor_sync_start.reg_num;
1638                                reg = iga1_crtc_reg.hor_sync_start.reg;
1639                                break;
1640                        case H_SYNC_END_INDEX:
1641                                reg_value =
1642                                    IGA1_HOR_SYNC_END_FORMULA
1643                                    (device_timing.hor_sync_start,
1644                                     device_timing.hor_sync_end);
1645                                viafb_load_reg_num =
1646                                    iga1_crtc_reg.hor_sync_end.reg_num;
1647                                reg = iga1_crtc_reg.hor_sync_end.reg;
1648                                break;
1649                        case V_TOTAL_INDEX:
1650                                reg_value =
1651                                    IGA1_VER_TOTAL_FORMULA(device_timing.
1652                                                           ver_total);
1653                                viafb_load_reg_num =
1654                                        iga1_crtc_reg.ver_total.reg_num;
1655                                reg = iga1_crtc_reg.ver_total.reg;
1656                                break;
1657                        case V_ADDR_INDEX:
1658                                reg_value =
1659                                    IGA1_VER_ADDR_FORMULA(device_timing.
1660                                                          ver_addr);
1661                                viafb_load_reg_num =
1662                                        iga1_crtc_reg.ver_addr.reg_num;
1663                                reg = iga1_crtc_reg.ver_addr.reg;
1664                                break;
1665                        case V_BLANK_START_INDEX:
1666                                reg_value =
1667                                    IGA1_VER_BLANK_START_FORMULA
1668                                    (device_timing.ver_blank_start);
1669                                viafb_load_reg_num =
1670                                    iga1_crtc_reg.ver_blank_start.reg_num;
1671                                reg = iga1_crtc_reg.ver_blank_start.reg;
1672                                break;
1673                        case V_BLANK_END_INDEX:
1674                                reg_value =
1675                                    IGA1_VER_BLANK_END_FORMULA
1676                                    (device_timing.ver_blank_start,
1677                                     device_timing.ver_blank_end);
1678                                viafb_load_reg_num =
1679                                    iga1_crtc_reg.ver_blank_end.reg_num;
1680                                reg = iga1_crtc_reg.ver_blank_end.reg;
1681                                break;
1682                        case V_SYNC_START_INDEX:
1683                                reg_value =
1684                                    IGA1_VER_SYNC_START_FORMULA
1685                                    (device_timing.ver_sync_start);
1686                                viafb_load_reg_num =
1687                                    iga1_crtc_reg.ver_sync_start.reg_num;
1688                                reg = iga1_crtc_reg.ver_sync_start.reg;
1689                                break;
1690                        case V_SYNC_END_INDEX:
1691                                reg_value =
1692                                    IGA1_VER_SYNC_END_FORMULA
1693                                    (device_timing.ver_sync_start,
1694                                     device_timing.ver_sync_end);
1695                                viafb_load_reg_num =
1696                                    iga1_crtc_reg.ver_sync_end.reg_num;
1697                                reg = iga1_crtc_reg.ver_sync_end.reg;
1698                                break;
1699
1700                        }
1701                }
1702
1703                if (set_iga == IGA2) {
1704                        switch (i) {
1705                        case H_TOTAL_INDEX:
1706                                reg_value =
1707                                    IGA2_HOR_TOTAL_FORMULA(device_timing.
1708                                                           hor_total);
1709                                viafb_load_reg_num =
1710                                        iga2_crtc_reg.hor_total.reg_num;
1711                                reg = iga2_crtc_reg.hor_total.reg;
1712                                break;
1713                        case H_ADDR_INDEX:
1714                                reg_value =
1715                                    IGA2_HOR_ADDR_FORMULA(device_timing.
1716                                                          hor_addr);
1717                                viafb_load_reg_num =
1718                                        iga2_crtc_reg.hor_addr.reg_num;
1719                                reg = iga2_crtc_reg.hor_addr.reg;
1720                                break;
1721                        case H_BLANK_START_INDEX:
1722                                reg_value =
1723                                    IGA2_HOR_BLANK_START_FORMULA
1724                                    (device_timing.hor_blank_start);
1725                                viafb_load_reg_num =
1726                                    iga2_crtc_reg.hor_blank_start.reg_num;
1727                                reg = iga2_crtc_reg.hor_blank_start.reg;
1728                                break;
1729                        case H_BLANK_END_INDEX:
1730                                reg_value =
1731                                    IGA2_HOR_BLANK_END_FORMULA
1732                                    (device_timing.hor_blank_start,
1733                                     device_timing.hor_blank_end);
1734                                viafb_load_reg_num =
1735                                    iga2_crtc_reg.hor_blank_end.reg_num;
1736                                reg = iga2_crtc_reg.hor_blank_end.reg;
1737                                break;
1738                        case H_SYNC_START_INDEX:
1739                                reg_value =
1740                                    IGA2_HOR_SYNC_START_FORMULA
1741                                    (device_timing.hor_sync_start);
1742                                if (UNICHROME_CN700 <=
1743                                        viaparinfo->chip_info->gfx_chip_name)
1744                                        viafb_load_reg_num =
1745                                            iga2_crtc_reg.hor_sync_start.
1746                                            reg_num;
1747                                else
1748                                        viafb_load_reg_num = 3;
1749                                reg = iga2_crtc_reg.hor_sync_start.reg;
1750                                break;
1751                        case H_SYNC_END_INDEX:
1752                                reg_value =
1753                                    IGA2_HOR_SYNC_END_FORMULA
1754                                    (device_timing.hor_sync_start,
1755                                     device_timing.hor_sync_end);
1756                                viafb_load_reg_num =
1757                                    iga2_crtc_reg.hor_sync_end.reg_num;
1758                                reg = iga2_crtc_reg.hor_sync_end.reg;
1759                                break;
1760                        case V_TOTAL_INDEX:
1761                                reg_value =
1762                                    IGA2_VER_TOTAL_FORMULA(device_timing.
1763                                                           ver_total);
1764                                viafb_load_reg_num =
1765                                        iga2_crtc_reg.ver_total.reg_num;
1766                                reg = iga2_crtc_reg.ver_total.reg;
1767                                break;
1768                        case V_ADDR_INDEX:
1769                                reg_value =
1770                                    IGA2_VER_ADDR_FORMULA(device_timing.
1771                                                          ver_addr);
1772                                viafb_load_reg_num =
1773                                        iga2_crtc_reg.ver_addr.reg_num;
1774                                reg = iga2_crtc_reg.ver_addr.reg;
1775                                break;
1776                        case V_BLANK_START_INDEX:
1777                                reg_value =
1778                                    IGA2_VER_BLANK_START_FORMULA
1779                                    (device_timing.ver_blank_start);
1780                                viafb_load_reg_num =
1781                                    iga2_crtc_reg.ver_blank_start.reg_num;
1782                                reg = iga2_crtc_reg.ver_blank_start.reg;
1783                                break;
1784                        case V_BLANK_END_INDEX:
1785                                reg_value =
1786                                    IGA2_VER_BLANK_END_FORMULA
1787                                    (device_timing.ver_blank_start,
1788                                     device_timing.ver_blank_end);
1789                                viafb_load_reg_num =
1790                                    iga2_crtc_reg.ver_blank_end.reg_num;
1791                                reg = iga2_crtc_reg.ver_blank_end.reg;
1792                                break;
1793                        case V_SYNC_START_INDEX:
1794                                reg_value =
1795                                    IGA2_VER_SYNC_START_FORMULA
1796                                    (device_timing.ver_sync_start);
1797                                viafb_load_reg_num =
1798                                    iga2_crtc_reg.ver_sync_start.reg_num;
1799                                reg = iga2_crtc_reg.ver_sync_start.reg;
1800                                break;
1801                        case V_SYNC_END_INDEX:
1802                                reg_value =
1803                                    IGA2_VER_SYNC_END_FORMULA
1804                                    (device_timing.ver_sync_start,
1805                                     device_timing.ver_sync_end);
1806                                viafb_load_reg_num =
1807                                    iga2_crtc_reg.ver_sync_end.reg_num;
1808                                reg = iga2_crtc_reg.ver_sync_end.reg;
1809                                break;
1810
1811                        }
1812                }
1813                viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1814        }
1815
1816        viafb_lock_crt();
1817}
1818
1819void viafb_set_color_depth(int bpp_byte, int set_iga)
1820{
1821        if (set_iga == IGA1) {
1822                switch (bpp_byte) {
1823                case MODE_8BPP:
1824                        viafb_write_reg_mask(SR15, VIASR, 0x22, 0x7E);
1825                        break;
1826                case MODE_16BPP:
1827                        viafb_write_reg_mask(SR15, VIASR, 0xB6, 0xFE);
1828                        break;
1829                case MODE_32BPP:
1830                        viafb_write_reg_mask(SR15, VIASR, 0xAE, 0xFE);
1831                        break;
1832                }
1833        } else {
1834                switch (bpp_byte) {
1835                case MODE_8BPP:
1836                        viafb_write_reg_mask(CR67, VIACR, 0x00, BIT6 + BIT7);
1837                        break;
1838                case MODE_16BPP:
1839                        viafb_write_reg_mask(CR67, VIACR, 0x40, BIT6 + BIT7);
1840                        break;
1841                case MODE_32BPP:
1842                        viafb_write_reg_mask(CR67, VIACR, 0xC0, BIT6 + BIT7);
1843                        break;
1844                }
1845        }
1846}
1847
1848void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1849        int mode_index, int bpp_byte, int set_iga)
1850{
1851        struct VideoModeTable *video_mode;
1852        struct display_timing crt_reg;
1853        int i;
1854        int index = 0;
1855        int h_addr, v_addr;
1856        u32 pll_D_N;
1857
1858        video_mode = &CLE266Modes[search_mode_setting(mode_index)];
1859
1860        for (i = 0; i < video_mode->mode_array; i++) {
1861                index = i;
1862
1863                if (crt_table[i].refresh_rate == viaparinfo->
1864                        crt_setting_info->refresh_rate)
1865                        break;
1866        }
1867
1868        crt_reg = crt_table[index].crtc;
1869
1870        /* Mode 640x480 has border, but LCD/DFP didn't have border. */
1871        /* So we would delete border. */
1872        if ((viafb_LCD_ON | viafb_DVI_ON) && (mode_index == VIA_RES_640X480)
1873            && (viaparinfo->crt_setting_info->refresh_rate == 60)) {
1874                /* The border is 8 pixels. */
1875                crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
1876
1877                /* Blanking time should add left and right borders. */
1878                crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16;
1879        }
1880
1881        h_addr = crt_reg.hor_addr;
1882        v_addr = crt_reg.ver_addr;
1883
1884        /* update polarity for CRT timing */
1885        if (crt_table[index].h_sync_polarity == NEGATIVE) {
1886                if (crt_table[index].v_sync_polarity == NEGATIVE)
1887                        outb((inb(VIARMisc) & (~(BIT6 + BIT7))) |
1888                             (BIT6 + BIT7), VIAWMisc);
1889                else
1890                        outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT6),
1891                             VIAWMisc);
1892        } else {
1893                if (crt_table[index].v_sync_polarity == NEGATIVE)
1894                        outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT7),
1895                             VIAWMisc);
1896                else
1897                        outb((inb(VIARMisc) & (~(BIT6 + BIT7))), VIAWMisc);
1898        }
1899
1900        if (set_iga == IGA1) {
1901                viafb_unlock_crt();
1902                viafb_write_reg(CR09, VIACR, 0x00);        /*initial CR09=0 */
1903                viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);
1904                viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1905        }
1906
1907        switch (set_iga) {
1908        case IGA1:
1909                viafb_load_crtc_timing(crt_reg, IGA1);
1910                break;
1911        case IGA2:
1912                viafb_load_crtc_timing(crt_reg, IGA2);
1913                break;
1914        }
1915
1916        load_fix_bit_crtc_reg();
1917        viafb_lock_crt();
1918        viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1919        viafb_load_offset_reg(h_addr, bpp_byte, set_iga);
1920        viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
1921
1922        /* load FIFO */
1923        if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
1924            && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
1925                viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
1926
1927        /* load SR Register About Memory and Color part */
1928        viafb_set_color_depth(bpp_byte, set_iga);
1929
1930        pll_D_N = viafb_get_clk_value(crt_table[index].clk);
1931        DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
1932        viafb_set_vclock(pll_D_N, set_iga);
1933
1934}
1935
1936void viafb_init_chip_info(void)
1937{
1938        init_gfx_chip_info();
1939        init_tmds_chip_info();
1940        init_lvds_chip_info();
1941
1942        viaparinfo->crt_setting_info->iga_path = IGA1;
1943        viaparinfo->crt_setting_info->refresh_rate = viafb_refresh;
1944
1945        /*Set IGA path for each device */
1946        viafb_set_iga_path();
1947
1948        viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
1949        viaparinfo->lvds_setting_info->get_lcd_size_method =
1950                GET_LCD_SIZE_BY_USER_SETTING;
1951        viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
1952        viaparinfo->lvds_setting_info2->display_method =
1953                viaparinfo->lvds_setting_info->display_method;
1954        viaparinfo->lvds_setting_info2->lcd_mode =
1955                viaparinfo->lvds_setting_info->lcd_mode;
1956}
1957
1958void viafb_update_device_setting(int hres, int vres,
1959        int bpp, int vmode_refresh, int flag)
1960{
1961        if (flag == 0) {
1962                viaparinfo->crt_setting_info->h_active = hres;
1963                viaparinfo->crt_setting_info->v_active = vres;
1964                viaparinfo->crt_setting_info->bpp = bpp;
1965                viaparinfo->crt_setting_info->refresh_rate =
1966                        vmode_refresh;
1967
1968                viaparinfo->tmds_setting_info->h_active = hres;
1969                viaparinfo->tmds_setting_info->v_active = vres;
1970                viaparinfo->tmds_setting_info->bpp = bpp;
1971                viaparinfo->tmds_setting_info->refresh_rate =
1972                        vmode_refresh;
1973
1974                viaparinfo->lvds_setting_info->h_active = hres;
1975                viaparinfo->lvds_setting_info->v_active = vres;
1976                viaparinfo->lvds_setting_info->bpp = bpp;
1977                viaparinfo->lvds_setting_info->refresh_rate =
1978                        vmode_refresh;
1979                viaparinfo->lvds_setting_info2->h_active = hres;
1980                viaparinfo->lvds_setting_info2->v_active = vres;
1981                viaparinfo->lvds_setting_info2->bpp = bpp;
1982                viaparinfo->lvds_setting_info2->refresh_rate =
1983                        vmode_refresh;
1984        } else {
1985
1986                if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
1987                        viaparinfo->tmds_setting_info->h_active = hres;
1988                        viaparinfo->tmds_setting_info->v_active = vres;
1989                        viaparinfo->tmds_setting_info->bpp = bpp;
1990                        viaparinfo->tmds_setting_info->refresh_rate =
1991                                vmode_refresh;
1992                }
1993
1994                if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
1995                        viaparinfo->lvds_setting_info->h_active = hres;
1996                        viaparinfo->lvds_setting_info->v_active = vres;
1997                        viaparinfo->lvds_setting_info->bpp = bpp;
1998                        viaparinfo->lvds_setting_info->refresh_rate =
1999                                vmode_refresh;
2000                }
2001                if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
2002                        viaparinfo->lvds_setting_info2->h_active = hres;
2003                        viaparinfo->lvds_setting_info2->v_active = vres;
2004                        viaparinfo->lvds_setting_info2->bpp = bpp;
2005                        viaparinfo->lvds_setting_info2->refresh_rate =
2006                                vmode_refresh;
2007                }
2008        }
2009}
2010
2011static void init_gfx_chip_info(void)
2012{
2013        struct pci_dev *pdev = NULL;
2014        u32 i;
2015        u8 tmp;
2016
2017        /* Indentify GFX Chip Name */
2018        for (i = 0; pciidlist[i].vendor != 0; i++) {
2019                pdev = pci_get_device(pciidlist[i].vendor,
2020                        pciidlist[i].device, 0);
2021                if (pdev)
2022                        break;
2023        }
2024
2025        if (!pciidlist[i].vendor)
2026                return ;
2027
2028        viaparinfo->chip_info->gfx_chip_name = pciidlist[i].chip_index;
2029
2030        /* Check revision of CLE266 Chip */
2031        if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
2032                /* CR4F only define in CLE266.CX chip */
2033                tmp = viafb_read_reg(VIACR, CR4F);
2034                viafb_write_reg(CR4F, VIACR, 0x55);
2035                if (viafb_read_reg(VIACR, CR4F) != 0x55)
2036                        viaparinfo->chip_info->gfx_chip_revision =
2037                        CLE266_REVISION_AX;
2038                else
2039                        viaparinfo->chip_info->gfx_chip_revision =
2040                        CLE266_REVISION_CX;
2041                /* restore orignal CR4F value */
2042                viafb_write_reg(CR4F, VIACR, tmp);
2043        }
2044
2045        if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
2046                tmp = viafb_read_reg(VIASR, SR43);
2047                DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
2048                if (tmp & 0x02) {
2049                        viaparinfo->chip_info->gfx_chip_revision =
2050                                CX700_REVISION_700M2;
2051                } else if (tmp & 0x40) {
2052                        viaparinfo->chip_info->gfx_chip_revision =
2053                                CX700_REVISION_700M;
2054                } else {
2055                        viaparinfo->chip_info->gfx_chip_revision =
2056                                CX700_REVISION_700;
2057                }
2058        }
2059
2060        pci_dev_put(pdev);
2061}
2062
2063static void init_tmds_chip_info(void)
2064{
2065        viafb_tmds_trasmitter_identify();
2066
2067        if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
2068                output_interface) {
2069                switch (viaparinfo->chip_info->gfx_chip_name) {
2070                case UNICHROME_CX700:
2071                        {
2072                                /* we should check support by hardware layout.*/
2073                                if ((viafb_display_hardware_layout ==
2074                                     HW_LAYOUT_DVI_ONLY)
2075                                    || (viafb_display_hardware_layout ==
2076                                        HW_LAYOUT_LCD_DVI)) {
2077                                        viaparinfo->chip_info->tmds_chip_info.
2078                                            output_interface = INTERFACE_TMDS;
2079                                } else {
2080                                        viaparinfo->chip_info->tmds_chip_info.
2081                                                output_interface =
2082                                                INTERFACE_NONE;
2083                                }
2084                                break;
2085                        }
2086                case UNICHROME_K8M890:
2087                case UNICHROME_P4M900:
2088                case UNICHROME_P4M890:
2089                        /* TMDS on PCIE, we set DFPLOW as default. */
2090                        viaparinfo->chip_info->tmds_chip_info.output_interface =
2091                            INTERFACE_DFP_LOW;
2092                        break;
2093                default:
2094                        {
2095                                /* set DVP1 default for DVI */
2096                                viaparinfo->chip_info->tmds_chip_info
2097                                .output_interface = INTERFACE_DVP1;
2098                        }
2099                }
2100        }
2101
2102        DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
2103                  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
2104        viaparinfo->tmds_setting_info->get_dvi_size_method =
2105                GET_DVI_SIZE_BY_VGA_BIOS;
2106        viafb_init_dvi_size();
2107}
2108
2109static void init_lvds_chip_info(void)
2110{
2111        if (viafb_lcd_panel_id > LCD_PANEL_ID_MAXIMUM)
2112                viaparinfo->lvds_setting_info->get_lcd_size_method =
2113                    GET_LCD_SIZE_BY_VGA_BIOS;
2114        else
2115                viaparinfo->lvds_setting_info->get_lcd_size_method =
2116                    GET_LCD_SIZE_BY_USER_SETTING;
2117
2118        viafb_lvds_trasmitter_identify();
2119        viafb_init_lcd_size();
2120        viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
2121                                   viaparinfo->lvds_setting_info);
2122        if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
2123                viafb_init_lvds_output_interface(&viaparinfo->chip_info->
2124                        lvds_chip_info2, viaparinfo->lvds_setting_info2);
2125        }
2126        /*If CX700,two singel LCD, we need to reassign
2127           LCD interface to different LVDS port */
2128        if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
2129            && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
2130                if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
2131                        lvds_chip_name) && (INTEGRATED_LVDS ==
2132                        viaparinfo->chip_info->
2133                        lvds_chip_info2.lvds_chip_name)) {
2134                        viaparinfo->chip_info->lvds_chip_info.output_interface =
2135                                INTERFACE_LVDS0;
2136                        viaparinfo->chip_info->lvds_chip_info2.
2137                                output_interface =
2138                            INTERFACE_LVDS1;
2139                }
2140        }
2141
2142        DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
2143                  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
2144        DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
2145                  viaparinfo->chip_info->lvds_chip_info.output_interface);
2146        DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
2147                  viaparinfo->chip_info->lvds_chip_info.output_interface);
2148}
2149
2150void viafb_init_dac(int set_iga)
2151{
2152        int i;
2153        u8 tmp;
2154
2155        if (set_iga == IGA1) {
2156                /* access Primary Display's LUT */
2157                viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
2158                /* turn off LCK */
2159                viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
2160                for (i = 0; i < 256; i++) {
2161                        write_dac_reg(i, palLUT_table[i].red,
2162                                      palLUT_table[i].green,
2163                                      palLUT_table[i].blue);
2164                }
2165                /* turn on LCK */
2166                viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
2167        } else {
2168                tmp = viafb_read_reg(VIACR, CR6A);
2169                /* access Secondary Display's LUT */
2170                viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
2171                viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
2172                for (i = 0; i < 256; i++) {
2173                        write_dac_reg(i, palLUT_table[i].red,
2174                                      palLUT_table[i].green,
2175                                      palLUT_table[i].blue);
2176                }
2177                /* set IGA1 DAC for default */
2178                viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
2179                viafb_write_reg(CR6A, VIACR, tmp);
2180        }
2181}
2182
2183static void device_screen_off(void)
2184{
2185        /* turn off CRT screen (IGA1) */
2186        viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
2187}
2188
2189static void device_screen_on(void)
2190{
2191        /* turn on CRT screen (IGA1) */
2192        viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
2193}
2194
2195static void set_display_channel(void)
2196{
2197        /*If viafb_LCD2_ON, on cx700, internal lvds's information
2198        is keeped on lvds_setting_info2 */
2199        if (viafb_LCD2_ON &&
2200                viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
2201                /* For dual channel LCD: */
2202                /* Set to Dual LVDS channel. */
2203                viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
2204        } else if (viafb_LCD_ON && viafb_DVI_ON) {
2205                /* For LCD+DFP: */
2206                /* Set to LVDS1 + TMDS channel. */
2207                viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
2208        } else if (viafb_DVI_ON) {
2209                /* Set to single TMDS channel. */
2210                viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
2211        } else if (viafb_LCD_ON) {
2212                if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
2213                        /* For dual channel LCD: */
2214                        /* Set to Dual LVDS channel. */
2215                        viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
2216                } else {
2217                        /* Set to LVDS0 + LVDS1 channel. */
2218                        viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
2219                }
2220        }
2221}
2222
2223int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
2224        int vmode_index1, int hor_res1, int ver_res1, int video_bpp1)
2225{
2226        int i, j;
2227        int port;
2228        u8 value, index, mask;
2229        struct VideoModeTable *vmode_tbl;
2230        struct crt_mode_table *crt_timing;
2231        struct VideoModeTable *vmode_tbl1 = NULL;
2232        struct crt_mode_table *crt_timing1 = NULL;
2233
2234        DEBUG_MSG(KERN_INFO "Set Mode!!\n");
2235        DEBUG_MSG(KERN_INFO
2236                  "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n",
2237                  vmode_index, hor_res, ver_res, video_bpp);
2238
2239        device_screen_off();
2240        vmode_tbl = &CLE266Modes[search_mode_setting(vmode_index)];
2241        crt_timing = vmode_tbl->crtc;
2242
2243        if (viafb_SAMM_ON == 1) {
2244                vmode_tbl1 = &CLE266Modes[search_mode_setting(vmode_index1)];
2245                crt_timing1 = vmode_tbl1->crtc;
2246        }
2247
2248        inb(VIAStatus);
2249        outb(0x00, VIAAR);
2250
2251        /* Write Common Setting for Video Mode */
2252        switch (viaparinfo->chip_info->gfx_chip_name) {
2253        case UNICHROME_CLE266:
2254                viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
2255                break;
2256
2257        case UNICHROME_K400:
2258                viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
2259                break;
2260
2261        case UNICHROME_K800:
2262        case UNICHROME_PM800:
2263                viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
2264                break;
2265
2266        case UNICHROME_CN700:
2267        case UNICHROME_K8M890:
2268        case UNICHROME_P4M890:
2269        case UNICHROME_P4M900:
2270                viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
2271                break;
2272
2273        case UNICHROME_CX700:
2274                viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
2275
2276        case UNICHROME_VX800:
2277                viafb_write_regx(VX800_ModeXregs, NUM_TOTAL_VX800_ModeXregs);
2278
2279                break;
2280        }
2281
2282        device_off();
2283
2284        /* Fill VPIT Parameters */
2285        /* Write Misc Register */
2286        outb(VPIT.Misc, VIAWMisc);
2287
2288        /* Write Sequencer */
2289        for (i = 1; i <= StdSR; i++) {
2290                outb(i, VIASR);
2291                outb(VPIT.SR[i - 1], VIASR + 1);
2292        }
2293
2294        viafb_set_start_addr();
2295        viafb_set_iga_path();
2296
2297        /* Write CRTC */
2298        viafb_fill_crtc_timing(crt_timing, vmode_index, video_bpp / 8, IGA1);
2299
2300        /* Write Graphic Controller */
2301        for (i = 0; i < StdGR; i++) {
2302                outb(i, VIAGR);
2303                outb(VPIT.GR[i], VIAGR + 1);
2304        }
2305
2306        /* Write Attribute Controller */
2307        for (i = 0; i < StdAR; i++) {
2308                inb(VIAStatus);
2309                outb(i, VIAAR);
2310                outb(VPIT.AR[i], VIAAR);
2311        }
2312
2313        inb(VIAStatus);
2314        outb(0x20, VIAAR);
2315
2316        /* Update Patch Register */
2317
2318        if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
2319            || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)) {
2320                for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
2321                        if (res_patch_table[i].mode_index == vmode_index) {
2322                                for (j = 0;
2323                                     j < res_patch_table[i].table_length; j++) {
2324                                        index =
2325                                            res_patch_table[i].
2326                                            io_reg_table[j].index;
2327                                        port =
2328                                            res_patch_table[i].
2329                                            io_reg_table[j].port;
2330                                        value =
2331                                            res_patch_table[i].
2332                                            io_reg_table[j].value;
2333                                        mask =
2334                                            res_patch_table[i].
2335                                            io_reg_table[j].mask;
2336                                        viafb_write_reg_mask(index, port, value,
2337                                                       mask);
2338                                }
2339                        }
2340                }
2341        }
2342
2343        if (viafb_SAMM_ON == 1) {
2344                if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
2345                    || (viaparinfo->chip_info->gfx_chip_name ==
2346                    UNICHROME_K400)) {
2347                        for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
2348                                if (res_patch_table[i].mode_index ==
2349                                    vmode_index1) {
2350                                        for (j = 0;
2351                                             j <
2352                                             res_patch_table[i].
2353                                             table_length; j++) {
2354                                                index =
2355                                                    res_patch_table[i].
2356                                                    io_reg_table[j].index;
2357                                                port =
2358                                                    res_patch_table[i].
2359                                                    io_reg_table[j].port;
2360                                                value =
2361                                                    res_patch_table[i].
2362                                                    io_reg_table[j].value;
2363                                                mask =
2364                                                    res_patch_table[i].
2365                                                    io_reg_table[j].mask;
2366                                                viafb_write_reg_mask(index,
2367                                                        port, value, mask);
2368                                        }
2369                                }
2370                        }
2371                }
2372        }
2373
2374        /* Update Refresh Rate Setting */
2375
2376        /* Clear On Screen */
2377
2378        /* CRT set mode */
2379        if (viafb_CRT_ON) {
2380                if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path ==
2381                        IGA2)) {
2382                        viafb_fill_crtc_timing(crt_timing1, vmode_index1,
2383                                video_bpp1 / 8,
2384                                viaparinfo->crt_setting_info->iga_path);
2385                } else {
2386                        viafb_fill_crtc_timing(crt_timing, vmode_index,
2387                                video_bpp / 8,
2388                                viaparinfo->crt_setting_info->iga_path);
2389                }
2390
2391                set_crt_output_path(viaparinfo->crt_setting_info->iga_path);
2392
2393                /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
2394                to 8 alignment (1368),there is several pixels (2 pixels)
2395                on right side of screen. */
2396                if (hor_res % 8) {
2397                        viafb_unlock_crt();
2398                        viafb_write_reg(CR02, VIACR,
2399                                viafb_read_reg(VIACR, CR02) - 1);
2400                        viafb_lock_crt();
2401                }
2402        }
2403
2404        if (viafb_DVI_ON) {
2405                if (viafb_SAMM_ON &&
2406                        (viaparinfo->tmds_setting_info->iga_path == IGA2)) {
2407                        viafb_dvi_set_mode(viafb_get_mode_index
2408                                     (viaparinfo->tmds_setting_info->h_active,
2409                                      viaparinfo->tmds_setting_info->
2410                                      v_active, 1),
2411                                     video_bpp1, viaparinfo->
2412                                     tmds_setting_info->iga_path);
2413                } else {
2414                        viafb_dvi_set_mode(viafb_get_mode_index
2415                                     (viaparinfo->tmds_setting_info->h_active,
2416                                      viaparinfo->
2417                                      tmds_setting_info->v_active, 0),
2418                                     video_bpp, viaparinfo->
2419                                     tmds_setting_info->iga_path);
2420                }
2421        }
2422
2423        if (viafb_LCD_ON) {
2424                if (viafb_SAMM_ON &&
2425                        (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
2426                        viaparinfo->lvds_setting_info->bpp = video_bpp1;
2427                        viafb_lcd_set_mode(crt_timing1, viaparinfo->
2428                                lvds_setting_info,
2429                                     &viaparinfo->chip_info->lvds_chip_info);
2430                } else {
2431                        /* IGA1 doesn't have LCD scaling, so set it center. */
2432                        if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
2433                                viaparinfo->lvds_setting_info->display_method =
2434                                    LCD_CENTERING;
2435                        }
2436                        viaparinfo->lvds_setting_info->bpp = video_bpp;
2437                        viafb_lcd_set_mode(crt_timing, viaparinfo->
2438                                lvds_setting_info,
2439                                     &viaparinfo->chip_info->lvds_chip_info);
2440                }
2441        }
2442        if (viafb_LCD2_ON) {
2443                if (viafb_SAMM_ON &&
2444                        (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
2445                        viaparinfo->lvds_setting_info2->bpp = video_bpp1;
2446                        viafb_lcd_set_mode(crt_timing1, viaparinfo->
2447                                lvds_setting_info2,
2448                                     &viaparinfo->chip_info->lvds_chip_info2);
2449                } else {
2450                        /* IGA1 doesn't have LCD scaling, so set it center. */
2451                        if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
2452                                viaparinfo->lvds_setting_info2->display_method =
2453                                    LCD_CENTERING;
2454                        }
2455                        viaparinfo->lvds_setting_info2->bpp = video_bpp;
2456                        viafb_lcd_set_mode(crt_timing, viaparinfo->
2457                                lvds_setting_info2,
2458                                     &viaparinfo->chip_info->lvds_chip_info2);
2459                }
2460        }
2461
2462        if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
2463            && (viafb_LCD_ON || viafb_DVI_ON))
2464                set_display_channel();
2465
2466        /* If set mode normally, save resolution information for hot-plug . */
2467        if (!viafb_hotplug) {
2468                viafb_hotplug_Xres = hor_res;
2469                viafb_hotplug_Yres = ver_res;
2470                viafb_hotplug_bpp = video_bpp;
2471                viafb_hotplug_refresh = viafb_refresh;
2472
2473                if (viafb_DVI_ON)
2474                        viafb_DeviceStatus = DVI_Device;
2475                else
2476                        viafb_DeviceStatus = CRT_Device;
2477        }
2478        device_on();
2479
2480        if (viafb_SAMM_ON == 1)
2481                viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
2482
2483        device_screen_on();
2484        return 1;
2485}
2486
2487int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
2488{
2489        int i;
2490
2491        for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) {
2492                if ((hres == res_map_refresh_tbl[i].hres)
2493                    && (vres == res_map_refresh_tbl[i].vres)
2494                    && (vmode_refresh == res_map_refresh_tbl[i].vmode_refresh))
2495                        return res_map_refresh_tbl[i].pixclock;
2496        }
2497        return RES_640X480_60HZ_PIXCLOCK;
2498
2499}
2500
2501int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2502{
2503#define REFRESH_TOLERANCE 3
2504        int i, nearest = -1, diff = REFRESH_TOLERANCE;
2505        for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) {
2506                if ((hres == res_map_refresh_tbl[i].hres)
2507                    && (vres == res_map_refresh_tbl[i].vres)
2508                    && (diff > (abs(long_refresh -
2509                    res_map_refresh_tbl[i].vmode_refresh)))) {
2510                        diff = abs(long_refresh - res_map_refresh_tbl[i].
2511                                vmode_refresh);
2512                        nearest = i;
2513                }
2514        }
2515#undef REFRESH_TOLERANCE
2516        if (nearest > 0)
2517                return res_map_refresh_tbl[nearest].vmode_refresh;
2518        return 60;
2519}
2520
2521static void device_off(void)
2522{
2523        viafb_crt_disable();
2524        viafb_dvi_disable();
2525        viafb_lcd_disable();
2526}
2527
2528static void device_on(void)
2529{
2530        if (viafb_CRT_ON == 1)
2531                viafb_crt_enable();
2532        if (viafb_DVI_ON == 1)
2533                viafb_dvi_enable();
2534        if (viafb_LCD_ON == 1)
2535                viafb_lcd_enable();
2536}
2537
2538void viafb_crt_disable(void)
2539{
2540        viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4);
2541}
2542
2543void viafb_crt_enable(void)
2544{
2545        viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4);
2546}
2547
2548void viafb_get_mmio_info(unsigned long *mmio_base,
2549        unsigned long *mmio_len)
2550{
2551        struct pci_dev *pdev = NULL;
2552        u32 vendor, device;
2553        u32 i;
2554
2555        for (i = 0; pciidlist[i].vendor != 0; i++)
2556                if (viaparinfo->chip_info->gfx_chip_name ==
2557                        pciidlist[i].chip_index)
2558                        break;
2559
2560        if (!pciidlist[i].vendor)
2561                return ;
2562
2563        vendor = pciidlist[i].vendor;
2564        device = pciidlist[i].device;
2565
2566        pdev = pci_get_device(vendor, device, NULL);
2567
2568        if (!pdev) {
2569                *mmio_base = 0;
2570                *mmio_len = 0;
2571                return ;
2572        }
2573
2574        *mmio_base = pci_resource_start(pdev, 1);
2575        *mmio_len = pci_resource_len(pdev, 1);
2576
2577        pci_dev_put(pdev);
2578}
2579
2580static void enable_second_display_channel(void)
2581{
2582        /* to enable second display channel. */
2583        viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2584        viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
2585        viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2586}
2587
2588static void disable_second_display_channel(void)
2589{
2590        /* to disable second display channel. */
2591        viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2592        viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
2593        viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2594}
2595
2596void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len)
2597{
2598        struct pci_dev *pdev = NULL;
2599        u32 vendor, device;
2600        u32 i;
2601
2602        for (i = 0; pciidlist[i].vendor != 0; i++)
2603                if (viaparinfo->chip_info->gfx_chip_name ==
2604                        pciidlist[i].chip_index)
2605                        break;
2606
2607        if (!pciidlist[i].vendor)
2608                return ;
2609
2610        vendor = pciidlist[i].vendor;
2611        device = pciidlist[i].device;
2612
2613        pdev = pci_get_device(vendor, device, NULL);
2614
2615        if (!pdev) {
2616                *fb_base = viafb_read_reg(VIASR, SR30) << 24;
2617                *fb_len = viafb_get_memsize();
2618                DEBUG_MSG(KERN_INFO "Get FB info from SR30!\n");
2619                DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
2620                DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
2621                return ;
2622        }
2623
2624        *fb_base = (unsigned int)pci_resource_start(pdev, 0);
2625        *fb_len = get_fb_size_from_pci();
2626        DEBUG_MSG(KERN_INFO "Get FB info from PCI system!\n");
2627        DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
2628        DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
2629
2630        pci_dev_put(pdev);
2631}
2632
2633static int get_fb_size_from_pci(void)
2634{
2635        unsigned long configid, deviceid, FBSize = 0;
2636        int VideoMemSize;
2637        int DeviceFound = false;
2638
2639        for (configid = 0x80000000; configid < 0x80010800; configid += 0x100) {
2640                outl(configid, (unsigned long)0xCF8);
2641                deviceid = (inl((unsigned long)0xCFC) >> 16) & 0xffff;
2642
2643                switch (deviceid) {
2644                case CLE266:
2645                case KM400:
2646                        outl(configid + 0xE0, (unsigned long)0xCF8);
2647                        FBSize = inl((unsigned long)0xCFC);
2648                        DeviceFound = true;        /* Found device id */
2649                        break;
2650
2651                case CN400_FUNCTION3:
2652                case CN700_FUNCTION3:
2653                case CX700_FUNCTION3:
2654                case KM800_FUNCTION3:
2655                case KM890_FUNCTION3:
2656                case P4M890_FUNCTION3:
2657                case P4M900_FUNCTION3:
2658                case VX800_FUNCTION3:
2659                        /*case CN750_FUNCTION3: */
2660                        outl(configid + 0xA0, (unsigned long)0xCF8);
2661                        FBSize = inl((unsigned long)0xCFC);
2662                        DeviceFound = true;        /* Found device id */
2663                        break;
2664
2665                default:
2666                        break;
2667                }
2668
2669                if (DeviceFound)
2670                        break;
2671        }
2672
2673        DEBUG_MSG(KERN_INFO "Device ID = %lx\n", deviceid);
2674
2675        FBSize = FBSize & 0x00007000;
2676        DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
2677
2678        if (viaparinfo->chip_info->gfx_chip_name < UNICHROME_CX700) {
2679                switch (FBSize) {
2680                case 0x00004000:
2681                        VideoMemSize = (16 << 20);        /*16M */
2682                        break;
2683
2684                case 0x00005000:
2685                        VideoMemSize = (32 << 20);        /*32M */
2686                        break;
2687
2688                case 0x00006000:
2689                        VideoMemSize = (64 << 20);        /*64M */
2690                        break;
2691
2692                default:
2693                        VideoMemSize = (32 << 20);        /*32M */
2694                        break;
2695                }
2696        } else {
2697                switch (FBSize) {
2698                case 0x00001000:
2699                        VideoMemSize = (8 << 20);        /*8M */
2700                        break;
2701
2702                case 0x00002000:
2703                        VideoMemSize = (16 << 20);        /*16M */
2704                        break;
2705
2706                case 0x00003000:
2707                        VideoMemSize = (32 << 20);        /*32M */
2708                        break;
2709
2710                case 0x00004000:
2711                        VideoMemSize = (64 << 20);        /*64M */
2712                        break;
2713
2714                case 0x00005000:
2715                        VideoMemSize = (128 << 20);        /*128M */
2716                        break;
2717
2718                case 0x00006000:
2719                        VideoMemSize = (256 << 20);        /*256M */
2720                        break;
2721
2722                default:
2723                        VideoMemSize = (32 << 20);        /*32M */
2724                        break;
2725                }
2726        }
2727
2728        return VideoMemSize;
2729}
2730
2731void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2732                                        *p_gfx_dpa_setting)
2733{
2734        switch (output_interface) {
2735        case INTERFACE_DVP0:
2736                {
2737                        /* DVP0 Clock Polarity and Adjust: */
2738                        viafb_write_reg_mask(CR96, VIACR,
2739                                       p_gfx_dpa_setting->DVP0, 0x0F);
2740
2741                        /* DVP0 Clock and Data Pads Driving: */
2742                        viafb_write_reg_mask(SR1E, VIASR,
2743                                       p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
2744                        viafb_write_reg_mask(SR2A, VIASR,
2745                                       p_gfx_dpa_setting->DVP0ClockDri_S1,
2746                                       BIT4);
2747                        viafb_write_reg_mask(SR1B, VIASR,
2748                                       p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
2749                        viafb_write_reg_mask(SR2A, VIASR,
2750                                       p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
2751                        break;
2752                }
2753
2754        case INTERFACE_DVP1:
2755                {
2756                        /* DVP1 Clock Polarity and Adjust: */
2757                        viafb_write_reg_mask(CR9B, VIACR,
2758                                       p_gfx_dpa_setting->DVP1, 0x0F);
2759
2760                        /* DVP1 Clock and Data Pads Driving: */
2761                        viafb_write_reg_mask(SR65, VIASR,
2762                                       p_gfx_dpa_setting->DVP1Driving, 0x0F);
2763                        break;
2764                }
2765
2766        case INTERFACE_DFP_HIGH:
2767                {
2768                        viafb_write_reg_mask(CR97, VIACR,
2769                                       p_gfx_dpa_setting->DFPHigh, 0x0F);
2770                        break;
2771                }
2772
2773        case INTERFACE_DFP_LOW:
2774                {
2775                        viafb_write_reg_mask(CR99, VIACR,
2776                                       p_gfx_dpa_setting->DFPLow, 0x0F);
2777                        break;
2778                }
2779
2780        case INTERFACE_DFP:
2781                {
2782                        viafb_write_reg_mask(CR97, VIACR,
2783                                       p_gfx_dpa_setting->DFPHigh, 0x0F);
2784                        viafb_write_reg_mask(CR99, VIACR,
2785                                       p_gfx_dpa_setting->DFPLow, 0x0F);
2786                        break;
2787                }
2788        }
2789}
2790
2791void viafb_memory_pitch_patch(struct fb_info *info)
2792{
2793        if (info->var.xres != info->var.xres_virtual) {
2794                viafb_load_offset_reg(info->var.xres_virtual,
2795                                info->var.bits_per_pixel >> 3, IGA1);
2796
2797                if (viafb_SAMM_ON) {
2798                        viafb_load_offset_reg(viafb_second_virtual_xres,
2799                                viafb_bpp1 >> 3,
2800                                        IGA2);
2801                } else {
2802                        viafb_load_offset_reg(info->var.xres_virtual,
2803                                        info->var.bits_per_pixel >> 3, IGA2);
2804                }
2805
2806        }
2807}
2808
2809/*According var's xres, yres fill var's other timing information*/
2810void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
2811                          int mode_index)
2812{
2813        struct VideoModeTable *vmode_tbl = NULL;
2814        struct crt_mode_table *crt_timing = NULL;
2815        struct display_timing crt_reg;
2816        int i = 0, index = 0;
2817        vmode_tbl = &CLE266Modes[search_mode_setting(mode_index)];
2818        crt_timing = vmode_tbl->crtc;
2819        for (i = 0; i < vmode_tbl->mode_array; i++) {
2820                index = i;
2821                if (crt_timing[i].refresh_rate == refresh)
2822                        break;
2823        }
2824
2825        crt_reg = crt_timing[index].crtc;
2826        switch (var->bits_per_pixel) {
2827        case 8:
2828                var->red.offset = 0;
2829                var->green.offset = 0;
2830                var->blue.offset = 0;
2831                var->red.length = 6;
2832                var->green.length = 6;
2833                var->blue.length = 6;
2834                break;
2835        case 16:
2836                var->red.offset = 11;
2837                var->green.offset = 5;
2838                var->blue.offset = 0;
2839                var->red.length = 5;
2840                var->green.length = 6;
2841                var->blue.length = 5;
2842                break;
2843        case 32:
2844                var->red.offset = 16;
2845                var->green.offset = 8;
2846                var->blue.offset = 0;
2847                var->red.length = 8;
2848                var->green.length = 8;
2849                var->blue.length = 8;
2850                break;
2851        default:
2852                /* never happed, put here to keep consistent */
2853                break;
2854        }
2855
2856        var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
2857        var->left_margin =
2858            crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
2859        var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
2860        var->hsync_len = crt_reg.hor_sync_end;
2861        var->upper_margin =
2862            crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
2863        var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
2864        var->vsync_len = crt_reg.ver_sync_end;
2865}