root/drivers/video/fbdev/via/lcd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_lvds_chip
  2. viafb_init_lcd_size
  3. lvds_identify_integratedlvds
  4. viafb_lvds_trasmitter_identify
  5. fp_id_to_vindex
  6. lvds_register_read
  7. load_lcd_scaling
  8. via_pitch_alignment_patch_lcd
  9. lcd_patch_skew_dvp0
  10. lcd_patch_skew_dvp1
  11. lcd_patch_skew
  12. viafb_lcd_set_mode
  13. integrated_lvds_disable
  14. integrated_lvds_enable
  15. viafb_lcd_disable
  16. set_lcd_output_path
  17. viafb_lcd_enable
  18. lcd_powersequence_off
  19. lcd_powersequence_on
  20. fill_lcd_format
  21. check_diport_of_integrated_lvds
  22. viafb_init_lvds_output_interface
  23. viafb_lcd_get_mobile_state

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
   4  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
   5 
   6  */
   7 #include <linux/via-core.h>
   8 #include <linux/via_i2c.h>
   9 #include "global.h"
  10 
  11 #define viafb_compact_res(x, y) (((x)<<16)|(y))
  12 
  13 /* CLE266 Software Power Sequence */
  14 /* {Mask}, {Data}, {Delay} */
  15 static const int PowerSequenceOn[3][3] = {
  16         {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01}
  17 };
  18 static const int PowerSequenceOff[3][3] = {
  19         {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01}
  20 };
  21 
  22 static struct _lcd_scaling_factor lcd_scaling_factor = {
  23         /* LCD Horizontal Scaling Factor Register */
  24         {LCD_HOR_SCALING_FACTOR_REG_NUM,
  25          {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } },
  26         /* LCD Vertical Scaling Factor Register */
  27         {LCD_VER_SCALING_FACTOR_REG_NUM,
  28          {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } }
  29 };
  30 static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
  31         /* LCD Horizontal Scaling Factor Register */
  32         {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } },
  33         /* LCD Vertical Scaling Factor Register */
  34         {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }
  35 };
  36 
  37 static bool lvds_identify_integratedlvds(void);
  38 static void fp_id_to_vindex(int panel_id);
  39 static int lvds_register_read(int index);
  40 static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
  41                       int panel_vres);
  42 static void lcd_patch_skew_dvp0(struct lvds_setting_information
  43                          *plvds_setting_info,
  44                          struct lvds_chip_information *plvds_chip_info);
  45 static void lcd_patch_skew_dvp1(struct lvds_setting_information
  46                          *plvds_setting_info,
  47                          struct lvds_chip_information *plvds_chip_info);
  48 static void lcd_patch_skew(struct lvds_setting_information
  49         *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
  50 
  51 static void integrated_lvds_disable(struct lvds_setting_information
  52                              *plvds_setting_info,
  53                              struct lvds_chip_information *plvds_chip_info);
  54 static void integrated_lvds_enable(struct lvds_setting_information
  55                             *plvds_setting_info,
  56                             struct lvds_chip_information *plvds_chip_info);
  57 static void lcd_powersequence_off(void);
  58 static void lcd_powersequence_on(void);
  59 static void fill_lcd_format(void);
  60 static void check_diport_of_integrated_lvds(
  61         struct lvds_chip_information *plvds_chip_info,
  62                                      struct lvds_setting_information
  63                                      *plvds_setting_info);
  64 
  65 static inline bool check_lvds_chip(int device_id_subaddr, int device_id)
  66 {
  67         return lvds_register_read(device_id_subaddr) == device_id;
  68 }
  69 
  70 void viafb_init_lcd_size(void)
  71 {
  72         DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
  73 
  74         fp_id_to_vindex(viafb_lcd_panel_id);
  75         viaparinfo->lvds_setting_info2->lcd_panel_hres =
  76                 viaparinfo->lvds_setting_info->lcd_panel_hres;
  77         viaparinfo->lvds_setting_info2->lcd_panel_vres =
  78                 viaparinfo->lvds_setting_info->lcd_panel_vres;
  79         viaparinfo->lvds_setting_info2->device_lcd_dualedge =
  80             viaparinfo->lvds_setting_info->device_lcd_dualedge;
  81         viaparinfo->lvds_setting_info2->LCDDithering =
  82                 viaparinfo->lvds_setting_info->LCDDithering;
  83 }
  84 
  85 static bool lvds_identify_integratedlvds(void)
  86 {
  87         if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) {
  88                 /* Two dual channel LCD (Internal LVDS + External LVDS): */
  89                 /* If we have an external LVDS, such as VT1636, we should
  90                    have its chip ID already. */
  91                 if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
  92                         viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
  93                             INTEGRATED_LVDS;
  94                         DEBUG_MSG(KERN_INFO "Support two dual channel LVDS! "
  95                                   "(Internal LVDS + External LVDS)\n");
  96                 } else {
  97                         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
  98                             INTEGRATED_LVDS;
  99                         DEBUG_MSG(KERN_INFO "Not found external LVDS, "
 100                                   "so can't support two dual channel LVDS!\n");
 101                 }
 102         } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
 103                 /* Two single channel LCD (Internal LVDS + Internal LVDS): */
 104                 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
 105                 INTEGRATED_LVDS;
 106                 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
 107                         INTEGRATED_LVDS;
 108                 DEBUG_MSG(KERN_INFO "Support two single channel LVDS! "
 109                           "(Internal LVDS + Internal LVDS)\n");
 110         } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
 111                 /* If we have found external LVDS, just use it,
 112                    otherwise, we will use internal LVDS as default. */
 113                 if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
 114                         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
 115                             INTEGRATED_LVDS;
 116                         DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n");
 117                 }
 118         } else {
 119                 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
 120                         NON_LVDS_TRANSMITTER;
 121                 DEBUG_MSG(KERN_INFO "Do not support LVDS!\n");
 122                 return false;
 123         }
 124 
 125         return true;
 126 }
 127 
 128 bool viafb_lvds_trasmitter_identify(void)
 129 {
 130         if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
 131                 viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
 132                 DEBUG_MSG(KERN_INFO
 133                           "Found VIA VT1636 LVDS on port i2c 0x31\n");
 134         } else {
 135                 if (viafb_lvds_identify_vt1636(VIA_PORT_2C)) {
 136                         viaparinfo->chip_info->lvds_chip_info.i2c_port =
 137                                 VIA_PORT_2C;
 138                         DEBUG_MSG(KERN_INFO
 139                                   "Found VIA VT1636 LVDS on port gpio 0x2c\n");
 140                 }
 141         }
 142 
 143         if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
 144                 lvds_identify_integratedlvds();
 145 
 146         if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
 147                 return true;
 148         /* Check for VT1631: */
 149         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS;
 150         viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
 151                 VT1631_LVDS_I2C_ADDR;
 152 
 153         if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID)) {
 154                 DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");
 155                 DEBUG_MSG(KERN_INFO "\n %2d",
 156                           viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
 157                 DEBUG_MSG(KERN_INFO "\n %2d",
 158                           viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
 159                 return true;
 160         }
 161 
 162         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
 163                 NON_LVDS_TRANSMITTER;
 164         viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
 165                 VT1631_LVDS_I2C_ADDR;
 166         return false;
 167 }
 168 
 169 static void fp_id_to_vindex(int panel_id)
 170 {
 171         DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
 172 
 173         if (panel_id > LCD_PANEL_ID_MAXIMUM)
 174                 viafb_lcd_panel_id = panel_id =
 175                 viafb_read_reg(VIACR, CR3F) & 0x0F;
 176 
 177         switch (panel_id) {
 178         case 0x0:
 179                 viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
 180                 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
 181                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 182                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 183                 break;
 184         case 0x1:
 185                 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
 186                 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
 187                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 188                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 189                 break;
 190         case 0x2:
 191                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
 192                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 193                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 194                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 195                 break;
 196         case 0x3:
 197                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
 198                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 199                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 200                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 201                 break;
 202         case 0x4:
 203                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
 204                 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
 205                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 206                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 207                 break;
 208         case 0x5:
 209                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
 210                 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
 211                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 212                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 213                 break;
 214         case 0x6:
 215                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
 216                 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
 217                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 218                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 219                 break;
 220         case 0x8:
 221                 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
 222                 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
 223                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 224                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 225                 break;
 226         case 0x9:
 227                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
 228                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 229                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 230                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 231                 break;
 232         case 0xA:
 233                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
 234                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 235                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 236                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 237                 break;
 238         case 0xB:
 239                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
 240                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 241                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 242                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 243                 break;
 244         case 0xC:
 245                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
 246                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 247                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 248                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 249                 break;
 250         case 0xD:
 251                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
 252                 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
 253                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 254                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 255                 break;
 256         case 0xE:
 257                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
 258                 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
 259                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 260                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 261                 break;
 262         case 0xF:
 263                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
 264                 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
 265                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 266                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 267                 break;
 268         case 0x10:
 269                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
 270                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 271                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 272                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 273                 break;
 274         case 0x11:
 275                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
 276                 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
 277                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 278                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 279                 break;
 280         case 0x12:
 281                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
 282                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 283                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 284                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 285                 break;
 286         case 0x13:
 287                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
 288                 viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
 289                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 290                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 291                 break;
 292         case 0x14:
 293                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
 294                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 295                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 296                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 297                 break;
 298         case 0x15:
 299                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
 300                 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
 301                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
 302                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 303                 break;
 304         case 0x16:
 305                 viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
 306                 viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
 307                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 308                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 309                 break;
 310         case 0x17:
 311                 /* OLPC XO-1.5 panel */
 312                 viaparinfo->lvds_setting_info->lcd_panel_hres = 1200;
 313                 viaparinfo->lvds_setting_info->lcd_panel_vres = 900;
 314                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 315                 viaparinfo->lvds_setting_info->LCDDithering = 0;
 316                 break;
 317         default:
 318                 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
 319                 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
 320                 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 321                 viaparinfo->lvds_setting_info->LCDDithering = 1;
 322         }
 323 }
 324 
 325 static int lvds_register_read(int index)
 326 {
 327         u8 data;
 328 
 329         viafb_i2c_readbyte(VIA_PORT_2C,
 330                         (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
 331                         (u8) index, &data);
 332         return data;
 333 }
 334 
 335 static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
 336                       int panel_vres)
 337 {
 338         int reg_value = 0;
 339         int viafb_load_reg_num;
 340         struct io_register *reg = NULL;
 341 
 342         DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n");
 343 
 344         /* LCD Scaling Enable */
 345         viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
 346 
 347         /* Check if expansion for horizontal */
 348         if (set_hres < panel_hres) {
 349                 /* Load Horizontal Scaling Factor */
 350                 switch (viaparinfo->chip_info->gfx_chip_name) {
 351                 case UNICHROME_CLE266:
 352                 case UNICHROME_K400:
 353                         reg_value =
 354                             CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
 355                         viafb_load_reg_num =
 356                             lcd_scaling_factor_CLE.lcd_hor_scaling_factor.
 357                             reg_num;
 358                         reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg;
 359                         viafb_load_reg(reg_value,
 360                                 viafb_load_reg_num, reg, VIACR);
 361                         break;
 362                 case UNICHROME_K800:
 363                 case UNICHROME_PM800:
 364                 case UNICHROME_CN700:
 365                 case UNICHROME_CX700:
 366                 case UNICHROME_K8M890:
 367                 case UNICHROME_P4M890:
 368                 case UNICHROME_P4M900:
 369                 case UNICHROME_CN750:
 370                 case UNICHROME_VX800:
 371                 case UNICHROME_VX855:
 372                 case UNICHROME_VX900:
 373                         reg_value =
 374                             K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
 375                         /* Horizontal scaling enabled */
 376                         viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6);
 377                         viafb_load_reg_num =
 378                             lcd_scaling_factor.lcd_hor_scaling_factor.reg_num;
 379                         reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg;
 380                         viafb_load_reg(reg_value,
 381                                 viafb_load_reg_num, reg, VIACR);
 382                         break;
 383                 }
 384 
 385                 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value);
 386         } else {
 387                 /* Horizontal scaling disabled */
 388                 viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7);
 389         }
 390 
 391         /* Check if expansion for vertical */
 392         if (set_vres < panel_vres) {
 393                 /* Load Vertical Scaling Factor */
 394                 switch (viaparinfo->chip_info->gfx_chip_name) {
 395                 case UNICHROME_CLE266:
 396                 case UNICHROME_K400:
 397                         reg_value =
 398                             CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
 399                         viafb_load_reg_num =
 400                             lcd_scaling_factor_CLE.lcd_ver_scaling_factor.
 401                             reg_num;
 402                         reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg;
 403                         viafb_load_reg(reg_value,
 404                                 viafb_load_reg_num, reg, VIACR);
 405                         break;
 406                 case UNICHROME_K800:
 407                 case UNICHROME_PM800:
 408                 case UNICHROME_CN700:
 409                 case UNICHROME_CX700:
 410                 case UNICHROME_K8M890:
 411                 case UNICHROME_P4M890:
 412                 case UNICHROME_P4M900:
 413                 case UNICHROME_CN750:
 414                 case UNICHROME_VX800:
 415                 case UNICHROME_VX855:
 416                 case UNICHROME_VX900:
 417                         reg_value =
 418                             K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
 419                         /* Vertical scaling enabled */
 420                         viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3);
 421                         viafb_load_reg_num =
 422                             lcd_scaling_factor.lcd_ver_scaling_factor.reg_num;
 423                         reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg;
 424                         viafb_load_reg(reg_value,
 425                                 viafb_load_reg_num, reg, VIACR);
 426                         break;
 427                 }
 428 
 429                 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value);
 430         } else {
 431                 /* Vertical scaling disabled */
 432                 viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3);
 433         }
 434 }
 435 
 436 static void via_pitch_alignment_patch_lcd(int iga_path, int hres, int bpp)
 437 {
 438         unsigned char cr13, cr35, cr65, cr66, cr67;
 439         unsigned long dwScreenPitch = 0;
 440         unsigned long dwPitch;
 441 
 442         dwPitch = hres * (bpp >> 3);
 443         if (dwPitch & 0x1F) {
 444                 dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
 445                 if (iga_path == IGA2) {
 446                         if (bpp > 8) {
 447                                 cr66 = (unsigned char)(dwScreenPitch & 0xFF);
 448                                 viafb_write_reg(CR66, VIACR, cr66);
 449                                 cr67 = viafb_read_reg(VIACR, CR67) & 0xFC;
 450                                 cr67 |=
 451                                     (unsigned
 452                                      char)((dwScreenPitch & 0x300) >> 8);
 453                                 viafb_write_reg(CR67, VIACR, cr67);
 454                         }
 455 
 456                         /* Fetch Count */
 457                         cr67 = viafb_read_reg(VIACR, CR67) & 0xF3;
 458                         cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7);
 459                         viafb_write_reg(CR67, VIACR, cr67);
 460                         cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF);
 461                         cr65 += 2;
 462                         viafb_write_reg(CR65, VIACR, cr65);
 463                 } else {
 464                         if (bpp > 8) {
 465                                 cr13 = (unsigned char)(dwScreenPitch & 0xFF);
 466                                 viafb_write_reg(CR13, VIACR, cr13);
 467                                 cr35 = viafb_read_reg(VIACR, CR35) & 0x1F;
 468                                 cr35 |=
 469                                     (unsigned
 470                                      char)((dwScreenPitch & 0x700) >> 3);
 471                                 viafb_write_reg(CR35, VIACR, cr35);
 472                         }
 473                 }
 474         }
 475 }
 476 static void lcd_patch_skew_dvp0(struct lvds_setting_information
 477                          *plvds_setting_info,
 478                          struct lvds_chip_information *plvds_chip_info)
 479 {
 480         if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
 481                 switch (viaparinfo->chip_info->gfx_chip_name) {
 482                 case UNICHROME_P4M900:
 483                         viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info,
 484                                                     plvds_chip_info);
 485                         break;
 486                 case UNICHROME_P4M890:
 487                         viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info,
 488                                                     plvds_chip_info);
 489                         break;
 490                 }
 491         }
 492 }
 493 static void lcd_patch_skew_dvp1(struct lvds_setting_information
 494                          *plvds_setting_info,
 495                          struct lvds_chip_information *plvds_chip_info)
 496 {
 497         if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
 498                 switch (viaparinfo->chip_info->gfx_chip_name) {
 499                 case UNICHROME_CX700:
 500                         viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info,
 501                                                     plvds_chip_info);
 502                         break;
 503                 }
 504         }
 505 }
 506 static void lcd_patch_skew(struct lvds_setting_information
 507         *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
 508 {
 509         DEBUG_MSG(KERN_INFO "lcd_patch_skew\n");
 510         switch (plvds_chip_info->output_interface) {
 511         case INTERFACE_DVP0:
 512                 lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info);
 513                 break;
 514         case INTERFACE_DVP1:
 515                 lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info);
 516                 break;
 517         case INTERFACE_DFP_LOW:
 518                 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
 519                         viafb_write_reg_mask(CR99, VIACR, 0x08,
 520                                        BIT0 + BIT1 + BIT2 + BIT3);
 521                 }
 522                 break;
 523         }
 524 }
 525 
 526 /* LCD Set Mode */
 527 void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
 528         u16 cyres, struct lvds_setting_information *plvds_setting_info,
 529         struct lvds_chip_information *plvds_chip_info)
 530 {
 531         int set_iga = plvds_setting_info->iga_path;
 532         int mode_bpp = var->bits_per_pixel;
 533         int set_hres = cxres ? cxres : var->xres;
 534         int set_vres = cyres ? cyres : var->yres;
 535         int panel_hres = plvds_setting_info->lcd_panel_hres;
 536         int panel_vres = plvds_setting_info->lcd_panel_vres;
 537         u32 clock;
 538         struct via_display_timing timing;
 539         struct fb_var_screeninfo panel_var;
 540         const struct fb_videomode *mode_crt_table, *panel_crt_table;
 541 
 542         DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
 543         /* Get mode table */
 544         mode_crt_table = viafb_get_best_mode(set_hres, set_vres, 60);
 545         /* Get panel table Pointer */
 546         panel_crt_table = viafb_get_best_mode(panel_hres, panel_vres, 60);
 547         viafb_fill_var_timing_info(&panel_var, panel_crt_table);
 548         DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
 549         if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
 550                 viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
 551         clock = PICOS2KHZ(panel_crt_table->pixclock) * 1000;
 552         plvds_setting_info->vclk = clock;
 553 
 554         if (set_iga == IGA2 && (set_hres < panel_hres || set_vres < panel_vres)
 555                 && plvds_setting_info->display_method == LCD_EXPANDSION) {
 556                 timing = var_to_timing(&panel_var, panel_hres, panel_vres);
 557                 load_lcd_scaling(set_hres, set_vres, panel_hres, panel_vres);
 558         } else {
 559                 timing = var_to_timing(&panel_var, set_hres, set_vres);
 560                 if (set_iga == IGA2)
 561                         /* disable scaling */
 562                         via_write_reg_mask(VIACR, 0x79, 0x00,
 563                                 BIT0 + BIT1 + BIT2);
 564         }
 565 
 566         if (set_iga == IGA1)
 567                 via_set_primary_timing(&timing);
 568         else if (set_iga == IGA2)
 569                 via_set_secondary_timing(&timing);
 570 
 571         /* Fetch count for IGA2 only */
 572         viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
 573 
 574         if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
 575                 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
 576                 viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
 577 
 578         fill_lcd_format();
 579         viafb_set_vclock(clock, set_iga);
 580         lcd_patch_skew(plvds_setting_info, plvds_chip_info);
 581 
 582         /* If K8M800, enable LCD Prefetch Mode. */
 583         if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
 584             || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
 585                 viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
 586 
 587         /* Patch for non 32bit alignment mode */
 588         via_pitch_alignment_patch_lcd(plvds_setting_info->iga_path, set_hres,
 589                 var->bits_per_pixel);
 590 }
 591 
 592 static void integrated_lvds_disable(struct lvds_setting_information
 593                              *plvds_setting_info,
 594                              struct lvds_chip_information *plvds_chip_info)
 595 {
 596         bool turn_off_first_powersequence = false;
 597         bool turn_off_second_powersequence = false;
 598         if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
 599                 turn_off_first_powersequence = true;
 600         if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
 601                 turn_off_first_powersequence = true;
 602         if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
 603                 turn_off_second_powersequence = true;
 604         if (turn_off_second_powersequence) {
 605                 /* Use second power sequence control: */
 606 
 607                 /* Turn off power sequence. */
 608                 viafb_write_reg_mask(CRD4, VIACR, 0, BIT1);
 609 
 610                 /* Turn off back light. */
 611                 viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7);
 612         }
 613         if (turn_off_first_powersequence) {
 614                 /* Use first power sequence control: */
 615 
 616                 /* Turn off power sequence. */
 617                 viafb_write_reg_mask(CR6A, VIACR, 0, BIT3);
 618 
 619                 /* Turn off back light. */
 620                 viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
 621         }
 622 
 623         /* Power off LVDS channel. */
 624         switch (plvds_chip_info->output_interface) {
 625         case INTERFACE_LVDS0:
 626                 {
 627                         viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7);
 628                         break;
 629                 }
 630 
 631         case INTERFACE_LVDS1:
 632                 {
 633                         viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6);
 634                         break;
 635                 }
 636 
 637         case INTERFACE_LVDS0LVDS1:
 638                 {
 639                         viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7);
 640                         break;
 641                 }
 642         }
 643 }
 644 
 645 static void integrated_lvds_enable(struct lvds_setting_information
 646                             *plvds_setting_info,
 647                             struct lvds_chip_information *plvds_chip_info)
 648 {
 649         DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n",
 650                   plvds_chip_info->output_interface);
 651         if (plvds_setting_info->lcd_mode == LCD_SPWG)
 652                 viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1);
 653         else
 654                 viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1);
 655 
 656         switch (plvds_chip_info->output_interface) {
 657         case INTERFACE_LVDS0LVDS1:
 658         case INTERFACE_LVDS0:
 659                 /* Use first power sequence control: */
 660                 /* Use hardware control power sequence. */
 661                 viafb_write_reg_mask(CR91, VIACR, 0, BIT0);
 662                 /* Turn on back light. */
 663                 viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7);
 664                 /* Turn on hardware power sequence. */
 665                 viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
 666                 break;
 667         case INTERFACE_LVDS1:
 668                 /* Use second power sequence control: */
 669                 /* Use hardware control power sequence. */
 670                 viafb_write_reg_mask(CRD3, VIACR, 0, BIT0);
 671                 /* Turn on back light. */
 672                 viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7);
 673                 /* Turn on hardware power sequence. */
 674                 viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1);
 675                 break;
 676         }
 677 
 678         /* Power on LVDS channel. */
 679         switch (plvds_chip_info->output_interface) {
 680         case INTERFACE_LVDS0:
 681                 {
 682                         viafb_write_reg_mask(CRD2, VIACR, 0, BIT7);
 683                         break;
 684                 }
 685 
 686         case INTERFACE_LVDS1:
 687                 {
 688                         viafb_write_reg_mask(CRD2, VIACR, 0, BIT6);
 689                         break;
 690                 }
 691 
 692         case INTERFACE_LVDS0LVDS1:
 693                 {
 694                         viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7);
 695                         break;
 696                 }
 697         }
 698 }
 699 
 700 void viafb_lcd_disable(void)
 701 {
 702 
 703         if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
 704                 lcd_powersequence_off();
 705                 /* DI1 pad off */
 706                 viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
 707         } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
 708                 if (viafb_LCD2_ON
 709                     && (INTEGRATED_LVDS ==
 710                         viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
 711                         integrated_lvds_disable(viaparinfo->lvds_setting_info,
 712                                 &viaparinfo->chip_info->lvds_chip_info2);
 713                 if (INTEGRATED_LVDS ==
 714                         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
 715                         integrated_lvds_disable(viaparinfo->lvds_setting_info,
 716                                 &viaparinfo->chip_info->lvds_chip_info);
 717                 if (VT1636_LVDS == viaparinfo->chip_info->
 718                         lvds_chip_info.lvds_chip_name)
 719                         viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
 720                                 &viaparinfo->chip_info->lvds_chip_info);
 721         } else if (VT1636_LVDS ==
 722         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
 723                 viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
 724                                     &viaparinfo->chip_info->lvds_chip_info);
 725         } else {
 726                 /* Backlight off           */
 727                 viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
 728                 /* 24 bit DI data paht off */
 729                 viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
 730         }
 731 
 732         /* Disable expansion bit   */
 733         viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
 734         /* Simultaneout disabled   */
 735         viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
 736 }
 737 
 738 static void set_lcd_output_path(int set_iga, int output_interface)
 739 {
 740         switch (output_interface) {
 741         case INTERFACE_DFP:
 742                 if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
 743                     || (UNICHROME_P4M890 ==
 744                     viaparinfo->chip_info->gfx_chip_name))
 745                         viafb_write_reg_mask(CR97, VIACR, 0x84,
 746                                        BIT7 + BIT2 + BIT1 + BIT0);
 747                 /* fall through */
 748         case INTERFACE_DVP0:
 749         case INTERFACE_DVP1:
 750         case INTERFACE_DFP_HIGH:
 751         case INTERFACE_DFP_LOW:
 752                 if (set_iga == IGA2)
 753                         viafb_write_reg(CR91, VIACR, 0x00);
 754                 break;
 755         }
 756 }
 757 
 758 void viafb_lcd_enable(void)
 759 {
 760         viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
 761         viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
 762         set_lcd_output_path(viaparinfo->lvds_setting_info->iga_path,
 763                 viaparinfo->chip_info->lvds_chip_info.output_interface);
 764         if (viafb_LCD2_ON)
 765                 set_lcd_output_path(viaparinfo->lvds_setting_info2->iga_path,
 766                         viaparinfo->chip_info->
 767                         lvds_chip_info2.output_interface);
 768 
 769         if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
 770                 /* DI1 pad on */
 771                 viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
 772                 lcd_powersequence_on();
 773         } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
 774                 if (viafb_LCD2_ON && (INTEGRATED_LVDS ==
 775                         viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
 776                         integrated_lvds_enable(viaparinfo->lvds_setting_info2, \
 777                                 &viaparinfo->chip_info->lvds_chip_info2);
 778                 if (INTEGRATED_LVDS ==
 779                         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
 780                         integrated_lvds_enable(viaparinfo->lvds_setting_info,
 781                                 &viaparinfo->chip_info->lvds_chip_info);
 782                 if (VT1636_LVDS == viaparinfo->chip_info->
 783                         lvds_chip_info.lvds_chip_name)
 784                         viafb_enable_lvds_vt1636(viaparinfo->
 785                         lvds_setting_info, &viaparinfo->chip_info->
 786                         lvds_chip_info);
 787         } else if (VT1636_LVDS ==
 788         viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
 789                 viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
 790                                    &viaparinfo->chip_info->lvds_chip_info);
 791         } else {
 792                 /* Backlight on            */
 793                 viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
 794                 /* 24 bit DI data paht on  */
 795                 viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
 796                 /* LCD enabled             */
 797                 viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
 798         }
 799 }
 800 
 801 static void lcd_powersequence_off(void)
 802 {
 803         int i, mask, data;
 804 
 805         /* Software control power sequence */
 806         viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
 807 
 808         for (i = 0; i < 3; i++) {
 809                 mask = PowerSequenceOff[0][i];
 810                 data = PowerSequenceOff[1][i] & mask;
 811                 viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
 812                 udelay(PowerSequenceOff[2][i]);
 813         }
 814 
 815         /* Disable LCD */
 816         viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08);
 817 }
 818 
 819 static void lcd_powersequence_on(void)
 820 {
 821         int i, mask, data;
 822 
 823         /* Software control power sequence */
 824         viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
 825 
 826         /* Enable LCD */
 827         viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08);
 828 
 829         for (i = 0; i < 3; i++) {
 830                 mask = PowerSequenceOn[0][i];
 831                 data = PowerSequenceOn[1][i] & mask;
 832                 viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
 833                 udelay(PowerSequenceOn[2][i]);
 834         }
 835 
 836         udelay(1);
 837 }
 838 
 839 static void fill_lcd_format(void)
 840 {
 841         u8 bdithering = 0, bdual = 0;
 842 
 843         if (viaparinfo->lvds_setting_info->device_lcd_dualedge)
 844                 bdual = BIT4;
 845         if (viaparinfo->lvds_setting_info->LCDDithering)
 846                 bdithering = BIT0;
 847         /* Dual & Dithering */
 848         viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0);
 849 }
 850 
 851 static void check_diport_of_integrated_lvds(
 852         struct lvds_chip_information *plvds_chip_info,
 853                                      struct lvds_setting_information
 854                                      *plvds_setting_info)
 855 {
 856         /* Determine LCD DI Port by hardware layout. */
 857         switch (viafb_display_hardware_layout) {
 858         case HW_LAYOUT_LCD_ONLY:
 859                 {
 860                         if (plvds_setting_info->device_lcd_dualedge) {
 861                                 plvds_chip_info->output_interface =
 862                                     INTERFACE_LVDS0LVDS1;
 863                         } else {
 864                                 plvds_chip_info->output_interface =
 865                                     INTERFACE_LVDS0;
 866                         }
 867 
 868                         break;
 869                 }
 870 
 871         case HW_LAYOUT_DVI_ONLY:
 872                 {
 873                         plvds_chip_info->output_interface = INTERFACE_NONE;
 874                         break;
 875                 }
 876 
 877         case HW_LAYOUT_LCD1_LCD2:
 878         case HW_LAYOUT_LCD_EXTERNAL_LCD2:
 879                 {
 880                         plvds_chip_info->output_interface =
 881                             INTERFACE_LVDS0LVDS1;
 882                         break;
 883                 }
 884 
 885         case HW_LAYOUT_LCD_DVI:
 886                 {
 887                         plvds_chip_info->output_interface = INTERFACE_LVDS1;
 888                         break;
 889                 }
 890 
 891         default:
 892                 {
 893                         plvds_chip_info->output_interface = INTERFACE_LVDS1;
 894                         break;
 895                 }
 896         }
 897 
 898         DEBUG_MSG(KERN_INFO
 899                   "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
 900                   viafb_display_hardware_layout,
 901                   plvds_chip_info->output_interface);
 902 }
 903 
 904 void viafb_init_lvds_output_interface(struct lvds_chip_information
 905                                 *plvds_chip_info,
 906                                 struct lvds_setting_information
 907                                 *plvds_setting_info)
 908 {
 909         if (INTERFACE_NONE != plvds_chip_info->output_interface) {
 910                 /*Do nothing, lcd port is specified by module parameter */
 911                 return;
 912         }
 913 
 914         switch (plvds_chip_info->lvds_chip_name) {
 915 
 916         case VT1636_LVDS:
 917                 switch (viaparinfo->chip_info->gfx_chip_name) {
 918                 case UNICHROME_CX700:
 919                         plvds_chip_info->output_interface = INTERFACE_DVP1;
 920                         break;
 921                 case UNICHROME_CN700:
 922                         plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
 923                         break;
 924                 default:
 925                         plvds_chip_info->output_interface = INTERFACE_DVP0;
 926                         break;
 927                 }
 928                 break;
 929 
 930         case INTEGRATED_LVDS:
 931                 check_diport_of_integrated_lvds(plvds_chip_info,
 932                                                 plvds_setting_info);
 933                 break;
 934 
 935         default:
 936                 switch (viaparinfo->chip_info->gfx_chip_name) {
 937                 case UNICHROME_K8M890:
 938                 case UNICHROME_P4M900:
 939                 case UNICHROME_P4M890:
 940                         plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
 941                         break;
 942                 default:
 943                         plvds_chip_info->output_interface = INTERFACE_DFP;
 944                         break;
 945                 }
 946                 break;
 947         }
 948 }
 949 
 950 bool viafb_lcd_get_mobile_state(bool *mobile)
 951 {
 952         unsigned char __iomem *romptr, *tableptr, *biosptr;
 953         u8 core_base;
 954         /* Rom address */
 955         const u32 romaddr = 0x000C0000;
 956         u16 start_pattern;
 957 
 958         biosptr = ioremap(romaddr, 0x10000);
 959         start_pattern = readw(biosptr);
 960 
 961         /* Compare pattern */
 962         if (start_pattern == 0xAA55) {
 963                 /* Get the start of Table */
 964                 /* 0x1B means BIOS offset position */
 965                 romptr = biosptr + 0x1B;
 966                 tableptr = biosptr + readw(romptr);
 967 
 968                 /* Get the start of biosver structure */
 969                 /* 18 means BIOS version position. */
 970                 romptr = tableptr + 18;
 971                 romptr = biosptr + readw(romptr);
 972 
 973                 /* The offset should be 44, but the
 974                    actual image is less three char. */
 975                 /* pRom += 44; */
 976                 romptr += 41;
 977 
 978                 core_base = readb(romptr);
 979 
 980                 if (core_base & 0x8)
 981                         *mobile = false;
 982                 else
 983                         *mobile = true;
 984                 /* release memory */
 985                 iounmap(biosptr);
 986 
 987                 return true;
 988         } else {
 989                 iounmap(biosptr);
 990                 return false;
 991         }
 992 }

/* [<][>][^][v][top][bottom][index][help] */