Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.28 1821 lines 56 kB view raw
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#include "lcdtbl.h" 24 25static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = { 26 /* IGA2 Shadow Horizontal Total */ 27 {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } }, 28 /* IGA2 Shadow Horizontal Blank End */ 29 {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } }, 30 /* IGA2 Shadow Vertical Total */ 31 {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } }, 32 /* IGA2 Shadow Vertical Addressable Video */ 33 {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } }, 34 /* IGA2 Shadow Vertical Blank Start */ 35 {IGA2_SHADOW_VER_BLANK_START_REG_NUM, 36 {{CR72, 0, 7}, {CR74, 4, 6} } }, 37 /* IGA2 Shadow Vertical Blank End */ 38 {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } }, 39 /* IGA2 Shadow Vertical Sync Start */ 40 {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } }, 41 /* IGA2 Shadow Vertical Sync End */ 42 {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } } 43}; 44 45static struct _lcd_scaling_factor lcd_scaling_factor = { 46 /* LCD Horizontal Scaling Factor Register */ 47 {LCD_HOR_SCALING_FACTOR_REG_NUM, 48 {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } }, 49 /* LCD Vertical Scaling Factor Register */ 50 {LCD_VER_SCALING_FACTOR_REG_NUM, 51 {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } } 52}; 53static struct _lcd_scaling_factor lcd_scaling_factor_CLE = { 54 /* LCD Horizontal Scaling Factor Register */ 55 {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } }, 56 /* LCD Vertical Scaling Factor Register */ 57 {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } } 58}; 59 60static int check_lvds_chip(int device_id_subaddr, int device_id); 61static bool lvds_identify_integratedlvds(void); 62static int fp_id_to_vindex(int panel_id); 63static int lvds_register_read(int index); 64static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, 65 int panel_vres); 66static void load_lcd_k400_patch_tbl(int set_hres, int set_vres, 67 int panel_id); 68static void load_lcd_p880_patch_tbl(int set_hres, int set_vres, 69 int panel_id); 70static void load_lcd_patch_regs(int set_hres, int set_vres, 71 int panel_id, int set_iga); 72static void via_pitch_alignment_patch_lcd( 73 struct lvds_setting_information *plvds_setting_info, 74 struct lvds_chip_information 75 *plvds_chip_info); 76static void lcd_patch_skew_dvp0(struct lvds_setting_information 77 *plvds_setting_info, 78 struct lvds_chip_information *plvds_chip_info); 79static void lcd_patch_skew_dvp1(struct lvds_setting_information 80 *plvds_setting_info, 81 struct lvds_chip_information *plvds_chip_info); 82static void lcd_patch_skew(struct lvds_setting_information 83 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); 84 85static void integrated_lvds_disable(struct lvds_setting_information 86 *plvds_setting_info, 87 struct lvds_chip_information *plvds_chip_info); 88static void integrated_lvds_enable(struct lvds_setting_information 89 *plvds_setting_info, 90 struct lvds_chip_information *plvds_chip_info); 91static void lcd_powersequence_off(void); 92static void lcd_powersequence_on(void); 93static void fill_lcd_format(void); 94static void check_diport_of_integrated_lvds( 95 struct lvds_chip_information *plvds_chip_info, 96 struct lvds_setting_information 97 *plvds_setting_info); 98static struct display_timing lcd_centering_timging(struct display_timing 99 mode_crt_reg, 100 struct display_timing panel_crt_reg); 101static void load_crtc_shadow_timing(struct display_timing mode_timing, 102 struct display_timing panel_timing); 103static void viafb_load_scaling_factor_for_p4m900(int set_hres, 104 int set_vres, int panel_hres, int panel_vres); 105 106static int check_lvds_chip(int device_id_subaddr, int device_id) 107{ 108 if (lvds_register_read(device_id_subaddr) == device_id) 109 return OK; 110 else 111 return FAIL; 112} 113 114void viafb_init_lcd_size(void) 115{ 116 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); 117 DEBUG_MSG(KERN_INFO 118 "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n", 119 viaparinfo->lvds_setting_info->get_lcd_size_method); 120 121 switch (viaparinfo->lvds_setting_info->get_lcd_size_method) { 122 case GET_LCD_SIZE_BY_SYSTEM_BIOS: 123 break; 124 case GET_LCD_SZIE_BY_HW_STRAPPING: 125 break; 126 case GET_LCD_SIZE_BY_VGA_BIOS: 127 DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n"); 128 viaparinfo->lvds_setting_info->lcd_panel_size = 129 fp_id_to_vindex(viafb_lcd_panel_id); 130 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", 131 viaparinfo->lvds_setting_info->lcd_panel_id); 132 DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", 133 viaparinfo->lvds_setting_info->lcd_panel_size); 134 break; 135 case GET_LCD_SIZE_BY_USER_SETTING: 136 DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n"); 137 viaparinfo->lvds_setting_info->lcd_panel_size = 138 fp_id_to_vindex(viafb_lcd_panel_id); 139 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", 140 viaparinfo->lvds_setting_info->lcd_panel_id); 141 DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", 142 viaparinfo->lvds_setting_info->lcd_panel_size); 143 break; 144 default: 145 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n"); 146 viaparinfo->lvds_setting_info->lcd_panel_id = 147 LCD_PANEL_ID1_800X600; 148 viaparinfo->lvds_setting_info->lcd_panel_size = 149 fp_id_to_vindex(LCD_PANEL_ID1_800X600); 150 } 151 viaparinfo->lvds_setting_info2->lcd_panel_id = 152 viaparinfo->lvds_setting_info->lcd_panel_id; 153 viaparinfo->lvds_setting_info2->lcd_panel_size = 154 viaparinfo->lvds_setting_info->lcd_panel_size; 155 viaparinfo->lvds_setting_info2->lcd_panel_hres = 156 viaparinfo->lvds_setting_info->lcd_panel_hres; 157 viaparinfo->lvds_setting_info2->lcd_panel_vres = 158 viaparinfo->lvds_setting_info->lcd_panel_vres; 159 viaparinfo->lvds_setting_info2->device_lcd_dualedge = 160 viaparinfo->lvds_setting_info->device_lcd_dualedge; 161 viaparinfo->lvds_setting_info2->LCDDithering = 162 viaparinfo->lvds_setting_info->LCDDithering; 163} 164 165static bool lvds_identify_integratedlvds(void) 166{ 167 if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) { 168 /* Two dual channel LCD (Internal LVDS + External LVDS): */ 169 /* If we have an external LVDS, such as VT1636, we should 170 have its chip ID already. */ 171 if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 172 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = 173 INTEGRATED_LVDS; 174 DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\ 175 (Internal LVDS + External LVDS)\n"); 176 } else { 177 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 178 INTEGRATED_LVDS; 179 DEBUG_MSG(KERN_INFO "Not found external LVDS,\ 180 so can't support two dual channel LVDS!\n"); 181 } 182 } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) { 183 /* Two single channel LCD (Internal LVDS + Internal LVDS): */ 184 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 185 INTEGRATED_LVDS; 186 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = 187 INTEGRATED_LVDS; 188 DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\ 189 (Internal LVDS + Internal LVDS)\n"); 190 } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) { 191 /* If we have found external LVDS, just use it, 192 otherwise, we will use internal LVDS as default. */ 193 if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 194 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 195 INTEGRATED_LVDS; 196 DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n"); 197 } 198 } else { 199 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 200 NON_LVDS_TRANSMITTER; 201 DEBUG_MSG(KERN_INFO "Do not support LVDS!\n"); 202 return false; 203 } 204 205 return true; 206} 207 208int viafb_lvds_trasmitter_identify(void) 209{ 210 viaparinfo->i2c_stuff.i2c_port = I2CPORTINDEX; 211 if (viafb_lvds_identify_vt1636()) { 212 viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX; 213 DEBUG_MSG(KERN_INFO 214 "Found VIA VT1636 LVDS on port i2c 0x31 \n"); 215 } else { 216 viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX; 217 if (viafb_lvds_identify_vt1636()) { 218 viaparinfo->chip_info->lvds_chip_info.i2c_port = 219 GPIOPORTINDEX; 220 DEBUG_MSG(KERN_INFO 221 "Found VIA VT1636 LVDS on port gpio 0x2c \n"); 222 } 223 } 224 225 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) 226 lvds_identify_integratedlvds(); 227 228 if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) 229 return true; 230 /* Check for VT1631: */ 231 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS; 232 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 233 VT1631_LVDS_I2C_ADDR; 234 235 if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) { 236 DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n"); 237 DEBUG_MSG(KERN_INFO "\n %2d", 238 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); 239 DEBUG_MSG(KERN_INFO "\n %2d", 240 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); 241 return OK; 242 } 243 244 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 245 NON_LVDS_TRANSMITTER; 246 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 247 VT1631_LVDS_I2C_ADDR; 248 return FAIL; 249} 250 251static int fp_id_to_vindex(int panel_id) 252{ 253 DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); 254 255 if (panel_id > LCD_PANEL_ID_MAXIMUM) 256 viafb_lcd_panel_id = panel_id = 257 viafb_read_reg(VIACR, CR3F) & 0x0F; 258 259 switch (panel_id) { 260 case 0x0: 261 viaparinfo->lvds_setting_info->lcd_panel_hres = 640; 262 viaparinfo->lvds_setting_info->lcd_panel_vres = 480; 263 viaparinfo->lvds_setting_info->lcd_panel_id = 264 LCD_PANEL_ID0_640X480; 265 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 266 viaparinfo->lvds_setting_info->LCDDithering = 1; 267 return VIA_RES_640X480; 268 break; 269 case 0x1: 270 viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 271 viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 272 viaparinfo->lvds_setting_info->lcd_panel_id = 273 LCD_PANEL_ID1_800X600; 274 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 275 viaparinfo->lvds_setting_info->LCDDithering = 1; 276 return VIA_RES_800X600; 277 break; 278 case 0x2: 279 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 280 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 281 viaparinfo->lvds_setting_info->lcd_panel_id = 282 LCD_PANEL_ID2_1024X768; 283 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 284 viaparinfo->lvds_setting_info->LCDDithering = 1; 285 return VIA_RES_1024X768; 286 break; 287 case 0x3: 288 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 289 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 290 viaparinfo->lvds_setting_info->lcd_panel_id = 291 LCD_PANEL_ID3_1280X768; 292 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 293 viaparinfo->lvds_setting_info->LCDDithering = 1; 294 return VIA_RES_1280X768; 295 break; 296 case 0x4: 297 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 298 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; 299 viaparinfo->lvds_setting_info->lcd_panel_id = 300 LCD_PANEL_ID4_1280X1024; 301 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 302 viaparinfo->lvds_setting_info->LCDDithering = 1; 303 return VIA_RES_1280X1024; 304 break; 305 case 0x5: 306 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; 307 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; 308 viaparinfo->lvds_setting_info->lcd_panel_id = 309 LCD_PANEL_ID5_1400X1050; 310 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 311 viaparinfo->lvds_setting_info->LCDDithering = 1; 312 return VIA_RES_1400X1050; 313 break; 314 case 0x6: 315 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; 316 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; 317 viaparinfo->lvds_setting_info->lcd_panel_id = 318 LCD_PANEL_ID6_1600X1200; 319 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 320 viaparinfo->lvds_setting_info->LCDDithering = 1; 321 return VIA_RES_1600X1200; 322 break; 323 case 0x8: 324 viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 325 viaparinfo->lvds_setting_info->lcd_panel_vres = 480; 326 viaparinfo->lvds_setting_info->lcd_panel_id = 327 LCD_PANEL_IDA_800X480; 328 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 329 viaparinfo->lvds_setting_info->LCDDithering = 1; 330 return VIA_RES_800X480; 331 break; 332 case 0x9: 333 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 334 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 335 viaparinfo->lvds_setting_info->lcd_panel_id = 336 LCD_PANEL_ID2_1024X768; 337 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 338 viaparinfo->lvds_setting_info->LCDDithering = 1; 339 return VIA_RES_1024X768; 340 break; 341 case 0xA: 342 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 343 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 344 viaparinfo->lvds_setting_info->lcd_panel_id = 345 LCD_PANEL_ID2_1024X768; 346 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 347 viaparinfo->lvds_setting_info->LCDDithering = 0; 348 return VIA_RES_1024X768; 349 break; 350 case 0xB: 351 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 352 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 353 viaparinfo->lvds_setting_info->lcd_panel_id = 354 LCD_PANEL_ID2_1024X768; 355 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 356 viaparinfo->lvds_setting_info->LCDDithering = 0; 357 return VIA_RES_1024X768; 358 break; 359 case 0xC: 360 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 361 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 362 viaparinfo->lvds_setting_info->lcd_panel_id = 363 LCD_PANEL_ID3_1280X768; 364 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 365 viaparinfo->lvds_setting_info->LCDDithering = 0; 366 return VIA_RES_1280X768; 367 break; 368 case 0xD: 369 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 370 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; 371 viaparinfo->lvds_setting_info->lcd_panel_id = 372 LCD_PANEL_ID4_1280X1024; 373 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 374 viaparinfo->lvds_setting_info->LCDDithering = 0; 375 return VIA_RES_1280X1024; 376 break; 377 case 0xE: 378 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; 379 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; 380 viaparinfo->lvds_setting_info->lcd_panel_id = 381 LCD_PANEL_ID5_1400X1050; 382 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 383 viaparinfo->lvds_setting_info->LCDDithering = 0; 384 return VIA_RES_1400X1050; 385 break; 386 case 0xF: 387 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; 388 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; 389 viaparinfo->lvds_setting_info->lcd_panel_id = 390 LCD_PANEL_ID6_1600X1200; 391 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 392 viaparinfo->lvds_setting_info->LCDDithering = 0; 393 return VIA_RES_1600X1200; 394 break; 395 case 0x10: 396 viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; 397 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 398 viaparinfo->lvds_setting_info->lcd_panel_id = 399 LCD_PANEL_ID7_1366X768; 400 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 401 viaparinfo->lvds_setting_info->LCDDithering = 0; 402 return VIA_RES_1368X768; 403 break; 404 case 0x11: 405 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 406 viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 407 viaparinfo->lvds_setting_info->lcd_panel_id = 408 LCD_PANEL_ID8_1024X600; 409 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 410 viaparinfo->lvds_setting_info->LCDDithering = 1; 411 return VIA_RES_1024X600; 412 break; 413 case 0x12: 414 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 415 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 416 viaparinfo->lvds_setting_info->lcd_panel_id = 417 LCD_PANEL_ID3_1280X768; 418 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 419 viaparinfo->lvds_setting_info->LCDDithering = 1; 420 return VIA_RES_1280X768; 421 break; 422 case 0x13: 423 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 424 viaparinfo->lvds_setting_info->lcd_panel_vres = 800; 425 viaparinfo->lvds_setting_info->lcd_panel_id = 426 LCD_PANEL_ID9_1280X800; 427 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 428 viaparinfo->lvds_setting_info->LCDDithering = 1; 429 return VIA_RES_1280X800; 430 break; 431 case 0x14: 432 viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; 433 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 434 viaparinfo->lvds_setting_info->lcd_panel_id = 435 LCD_PANEL_IDB_1360X768; 436 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 437 viaparinfo->lvds_setting_info->LCDDithering = 0; 438 return VIA_RES_1360X768; 439 break; 440 case 0x15: 441 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 442 viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 443 viaparinfo->lvds_setting_info->lcd_panel_id = 444 LCD_PANEL_ID3_1280X768; 445 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 446 viaparinfo->lvds_setting_info->LCDDithering = 0; 447 return VIA_RES_1280X768; 448 break; 449 case 0x16: 450 viaparinfo->lvds_setting_info->lcd_panel_hres = 480; 451 viaparinfo->lvds_setting_info->lcd_panel_vres = 640; 452 viaparinfo->lvds_setting_info->lcd_panel_id = 453 LCD_PANEL_IDC_480X640; 454 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 455 viaparinfo->lvds_setting_info->LCDDithering = 1; 456 return VIA_RES_480X640; 457 break; 458 default: 459 viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 460 viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 461 viaparinfo->lvds_setting_info->lcd_panel_id = 462 LCD_PANEL_ID1_800X600; 463 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 464 viaparinfo->lvds_setting_info->LCDDithering = 1; 465 return VIA_RES_800X600; 466 } 467} 468 469static int lvds_register_read(int index) 470{ 471 u8 data; 472 473 viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX; 474 viafb_i2c_readbyte((u8) viaparinfo->chip_info-> 475 lvds_chip_info.lvds_chip_slave_addr, 476 (u8) index, &data); 477 return data; 478} 479 480static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, 481 int panel_vres) 482{ 483 int reg_value = 0; 484 int viafb_load_reg_num; 485 struct io_register *reg = NULL; 486 487 DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n"); 488 489 /* LCD Scaling Enable */ 490 viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2); 491 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) { 492 viafb_load_scaling_factor_for_p4m900(set_hres, set_vres, 493 panel_hres, panel_vres); 494 return; 495 } 496 497 /* Check if expansion for horizontal */ 498 if (set_hres != panel_hres) { 499 /* Load Horizontal Scaling Factor */ 500 switch (viaparinfo->chip_info->gfx_chip_name) { 501 case UNICHROME_CLE266: 502 case UNICHROME_K400: 503 reg_value = 504 CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); 505 viafb_load_reg_num = 506 lcd_scaling_factor_CLE.lcd_hor_scaling_factor. 507 reg_num; 508 reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg; 509 viafb_load_reg(reg_value, 510 viafb_load_reg_num, reg, VIACR); 511 break; 512 case UNICHROME_K800: 513 case UNICHROME_PM800: 514 case UNICHROME_CN700: 515 case UNICHROME_CX700: 516 case UNICHROME_K8M890: 517 case UNICHROME_P4M890: 518 reg_value = 519 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); 520 /* Horizontal scaling enabled */ 521 viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6); 522 viafb_load_reg_num = 523 lcd_scaling_factor.lcd_hor_scaling_factor.reg_num; 524 reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg; 525 viafb_load_reg(reg_value, 526 viafb_load_reg_num, reg, VIACR); 527 break; 528 } 529 530 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value); 531 } else { 532 /* Horizontal scaling disabled */ 533 viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7); 534 } 535 536 /* Check if expansion for vertical */ 537 if (set_vres != panel_vres) { 538 /* Load Vertical Scaling Factor */ 539 switch (viaparinfo->chip_info->gfx_chip_name) { 540 case UNICHROME_CLE266: 541 case UNICHROME_K400: 542 reg_value = 543 CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres); 544 viafb_load_reg_num = 545 lcd_scaling_factor_CLE.lcd_ver_scaling_factor. 546 reg_num; 547 reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg; 548 viafb_load_reg(reg_value, 549 viafb_load_reg_num, reg, VIACR); 550 break; 551 case UNICHROME_K800: 552 case UNICHROME_PM800: 553 case UNICHROME_CN700: 554 case UNICHROME_CX700: 555 case UNICHROME_K8M890: 556 case UNICHROME_P4M890: 557 reg_value = 558 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); 559 /* Vertical scaling enabled */ 560 viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3); 561 viafb_load_reg_num = 562 lcd_scaling_factor.lcd_ver_scaling_factor.reg_num; 563 reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg; 564 viafb_load_reg(reg_value, 565 viafb_load_reg_num, reg, VIACR); 566 break; 567 } 568 569 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value); 570 } else { 571 /* Vertical scaling disabled */ 572 viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3); 573 } 574} 575 576static void load_lcd_k400_patch_tbl(int set_hres, int set_vres, 577 int panel_id) 578{ 579 int vmode_index; 580 int reg_num = 0; 581 struct io_reg *lcd_patch_reg = NULL; 582 583 if (viaparinfo->lvds_setting_info->iga_path == IGA2) 584 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); 585 else 586 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); 587 switch (panel_id) { 588 /* LCD 800x600 */ 589 case LCD_PANEL_ID1_800X600: 590 switch (vmode_index) { 591 case VIA_RES_640X400: 592 case VIA_RES_640X480: 593 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6; 594 lcd_patch_reg = K400_LCD_RES_6X4_8X6; 595 break; 596 case VIA_RES_720X480: 597 case VIA_RES_720X576: 598 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6; 599 lcd_patch_reg = K400_LCD_RES_7X4_8X6; 600 break; 601 } 602 break; 603 604 /* LCD 1024x768 */ 605 case LCD_PANEL_ID2_1024X768: 606 switch (vmode_index) { 607 case VIA_RES_640X400: 608 case VIA_RES_640X480: 609 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7; 610 lcd_patch_reg = K400_LCD_RES_6X4_10X7; 611 break; 612 case VIA_RES_720X480: 613 case VIA_RES_720X576: 614 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7; 615 lcd_patch_reg = K400_LCD_RES_7X4_10X7; 616 break; 617 case VIA_RES_800X600: 618 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7; 619 lcd_patch_reg = K400_LCD_RES_8X6_10X7; 620 break; 621 } 622 break; 623 624 /* LCD 1280x1024 */ 625 case LCD_PANEL_ID4_1280X1024: 626 switch (vmode_index) { 627 case VIA_RES_640X400: 628 case VIA_RES_640X480: 629 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10; 630 lcd_patch_reg = K400_LCD_RES_6X4_12X10; 631 break; 632 case VIA_RES_720X480: 633 case VIA_RES_720X576: 634 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10; 635 lcd_patch_reg = K400_LCD_RES_7X4_12X10; 636 break; 637 case VIA_RES_800X600: 638 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10; 639 lcd_patch_reg = K400_LCD_RES_8X6_12X10; 640 break; 641 case VIA_RES_1024X768: 642 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10; 643 lcd_patch_reg = K400_LCD_RES_10X7_12X10; 644 break; 645 646 } 647 break; 648 649 /* LCD 1400x1050 */ 650 case LCD_PANEL_ID5_1400X1050: 651 switch (vmode_index) { 652 case VIA_RES_640X480: 653 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10; 654 lcd_patch_reg = K400_LCD_RES_6X4_14X10; 655 break; 656 case VIA_RES_800X600: 657 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10; 658 lcd_patch_reg = K400_LCD_RES_8X6_14X10; 659 break; 660 case VIA_RES_1024X768: 661 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10; 662 lcd_patch_reg = K400_LCD_RES_10X7_14X10; 663 break; 664 case VIA_RES_1280X768: 665 case VIA_RES_1280X800: 666 case VIA_RES_1280X960: 667 case VIA_RES_1280X1024: 668 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10; 669 lcd_patch_reg = K400_LCD_RES_12X10_14X10; 670 break; 671 } 672 break; 673 674 /* LCD 1600x1200 */ 675 case LCD_PANEL_ID6_1600X1200: 676 switch (vmode_index) { 677 case VIA_RES_640X400: 678 case VIA_RES_640X480: 679 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12; 680 lcd_patch_reg = K400_LCD_RES_6X4_16X12; 681 break; 682 case VIA_RES_720X480: 683 case VIA_RES_720X576: 684 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12; 685 lcd_patch_reg = K400_LCD_RES_7X4_16X12; 686 break; 687 case VIA_RES_800X600: 688 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12; 689 lcd_patch_reg = K400_LCD_RES_8X6_16X12; 690 break; 691 case VIA_RES_1024X768: 692 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12; 693 lcd_patch_reg = K400_LCD_RES_10X7_16X12; 694 break; 695 case VIA_RES_1280X768: 696 case VIA_RES_1280X800: 697 case VIA_RES_1280X960: 698 case VIA_RES_1280X1024: 699 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12; 700 lcd_patch_reg = K400_LCD_RES_12X10_16X12; 701 break; 702 } 703 break; 704 705 /* LCD 1366x768 */ 706 case LCD_PANEL_ID7_1366X768: 707 switch (vmode_index) { 708 case VIA_RES_640X480: 709 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7; 710 lcd_patch_reg = K400_LCD_RES_6X4_1366X7; 711 break; 712 case VIA_RES_720X480: 713 case VIA_RES_720X576: 714 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7; 715 lcd_patch_reg = K400_LCD_RES_7X4_1366X7; 716 break; 717 case VIA_RES_800X600: 718 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7; 719 lcd_patch_reg = K400_LCD_RES_8X6_1366X7; 720 break; 721 case VIA_RES_1024X768: 722 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7; 723 lcd_patch_reg = K400_LCD_RES_10X7_1366X7; 724 break; 725 case VIA_RES_1280X768: 726 case VIA_RES_1280X800: 727 case VIA_RES_1280X960: 728 case VIA_RES_1280X1024: 729 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7; 730 lcd_patch_reg = K400_LCD_RES_12X10_1366X7; 731 break; 732 } 733 break; 734 735 /* LCD 1360x768 */ 736 case LCD_PANEL_IDB_1360X768: 737 break; 738 } 739 if (reg_num != 0) { 740 /* H.W. Reset : ON */ 741 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); 742 743 viafb_write_regx(lcd_patch_reg, reg_num); 744 745 /* H.W. Reset : OFF */ 746 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); 747 748 /* Reset PLL */ 749 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); 750 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); 751 752 /* Fire! */ 753 outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc); 754 } 755} 756 757static void load_lcd_p880_patch_tbl(int set_hres, int set_vres, 758 int panel_id) 759{ 760 int vmode_index; 761 int reg_num = 0; 762 struct io_reg *lcd_patch_reg = NULL; 763 764 if (viaparinfo->lvds_setting_info->iga_path == IGA2) 765 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); 766 else 767 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); 768 769 switch (panel_id) { 770 case LCD_PANEL_ID5_1400X1050: 771 switch (vmode_index) { 772 case VIA_RES_640X480: 773 reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10; 774 lcd_patch_reg = P880_LCD_RES_6X4_14X10; 775 break; 776 case VIA_RES_800X600: 777 reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10; 778 lcd_patch_reg = P880_LCD_RES_8X6_14X10; 779 break; 780 } 781 break; 782 case LCD_PANEL_ID6_1600X1200: 783 switch (vmode_index) { 784 case VIA_RES_640X400: 785 case VIA_RES_640X480: 786 reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12; 787 lcd_patch_reg = P880_LCD_RES_6X4_16X12; 788 break; 789 case VIA_RES_720X480: 790 case VIA_RES_720X576: 791 reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12; 792 lcd_patch_reg = P880_LCD_RES_7X4_16X12; 793 break; 794 case VIA_RES_800X600: 795 reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12; 796 lcd_patch_reg = P880_LCD_RES_8X6_16X12; 797 break; 798 case VIA_RES_1024X768: 799 reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12; 800 lcd_patch_reg = P880_LCD_RES_10X7_16X12; 801 break; 802 case VIA_RES_1280X768: 803 case VIA_RES_1280X960: 804 case VIA_RES_1280X1024: 805 reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12; 806 lcd_patch_reg = P880_LCD_RES_12X10_16X12; 807 break; 808 } 809 break; 810 811 } 812 if (reg_num != 0) { 813 /* H.W. Reset : ON */ 814 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); 815 816 viafb_write_regx(lcd_patch_reg, reg_num); 817 818 /* H.W. Reset : OFF */ 819 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); 820 821 /* Reset PLL */ 822 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); 823 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); 824 825 /* Fire! */ 826 outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc); 827 } 828} 829 830static void load_lcd_patch_regs(int set_hres, int set_vres, 831 int panel_id, int set_iga) 832{ 833 int vmode_index; 834 835 if (viaparinfo->lvds_setting_info->iga_path == IGA2) 836 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1); 837 else 838 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0); 839 840 viafb_unlock_crt(); 841 842 /* Patch for simultaneous & Expansion */ 843 if ((set_iga == IGA1_IGA2) && 844 (viaparinfo->lvds_setting_info->display_method == 845 LCD_EXPANDSION)) { 846 switch (viaparinfo->chip_info->gfx_chip_name) { 847 case UNICHROME_CLE266: 848 case UNICHROME_K400: 849 load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id); 850 break; 851 case UNICHROME_K800: 852 break; 853 case UNICHROME_PM800: 854 case UNICHROME_CN700: 855 case UNICHROME_CX700: 856 load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id); 857 } 858 } 859 860 viafb_lock_crt(); 861} 862 863static void via_pitch_alignment_patch_lcd( 864 struct lvds_setting_information *plvds_setting_info, 865 struct lvds_chip_information 866 *plvds_chip_info) 867{ 868 unsigned char cr13, cr35, cr65, cr66, cr67; 869 unsigned long dwScreenPitch = 0; 870 unsigned long dwPitch; 871 872 dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3); 873 if (dwPitch & 0x1F) { 874 dwScreenPitch = ((dwPitch + 31) & ~31) >> 3; 875 if (plvds_setting_info->iga_path == IGA2) { 876 if (plvds_setting_info->bpp > 8) { 877 cr66 = (unsigned char)(dwScreenPitch & 0xFF); 878 viafb_write_reg(CR66, VIACR, cr66); 879 cr67 = viafb_read_reg(VIACR, CR67) & 0xFC; 880 cr67 |= 881 (unsigned 882 char)((dwScreenPitch & 0x300) >> 8); 883 viafb_write_reg(CR67, VIACR, cr67); 884 } 885 886 /* Fetch Count */ 887 cr67 = viafb_read_reg(VIACR, CR67) & 0xF3; 888 cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7); 889 viafb_write_reg(CR67, VIACR, cr67); 890 cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF); 891 cr65 += 2; 892 viafb_write_reg(CR65, VIACR, cr65); 893 } else { 894 if (plvds_setting_info->bpp > 8) { 895 cr13 = (unsigned char)(dwScreenPitch & 0xFF); 896 viafb_write_reg(CR13, VIACR, cr13); 897 cr35 = viafb_read_reg(VIACR, CR35) & 0x1F; 898 cr35 |= 899 (unsigned 900 char)((dwScreenPitch & 0x700) >> 3); 901 viafb_write_reg(CR35, VIACR, cr35); 902 } 903 } 904 } 905} 906static void lcd_patch_skew_dvp0(struct lvds_setting_information 907 *plvds_setting_info, 908 struct lvds_chip_information *plvds_chip_info) 909{ 910 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) { 911 switch (viaparinfo->chip_info->gfx_chip_name) { 912 case UNICHROME_P4M900: 913 viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info, 914 plvds_chip_info); 915 break; 916 case UNICHROME_P4M890: 917 viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info, 918 plvds_chip_info); 919 break; 920 } 921 } 922} 923static void lcd_patch_skew_dvp1(struct lvds_setting_information 924 *plvds_setting_info, 925 struct lvds_chip_information *plvds_chip_info) 926{ 927 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) { 928 switch (viaparinfo->chip_info->gfx_chip_name) { 929 case UNICHROME_CX700: 930 viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info, 931 plvds_chip_info); 932 break; 933 } 934 } 935} 936static void lcd_patch_skew(struct lvds_setting_information 937 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) 938{ 939 DEBUG_MSG(KERN_INFO "lcd_patch_skew\n"); 940 switch (plvds_chip_info->output_interface) { 941 case INTERFACE_DVP0: 942 lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info); 943 break; 944 case INTERFACE_DVP1: 945 lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info); 946 break; 947 case INTERFACE_DFP_LOW: 948 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) { 949 viafb_write_reg_mask(CR99, VIACR, 0x08, 950 BIT0 + BIT1 + BIT2 + BIT3); 951 } 952 break; 953 } 954} 955 956/* LCD Set Mode */ 957void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, 958 struct lvds_setting_information *plvds_setting_info, 959 struct lvds_chip_information *plvds_chip_info) 960{ 961 int video_index = plvds_setting_info->lcd_panel_size; 962 int set_iga = plvds_setting_info->iga_path; 963 int mode_bpp = plvds_setting_info->bpp; 964 int viafb_load_reg_num = 0; 965 int reg_value = 0; 966 int set_hres, set_vres; 967 int panel_hres, panel_vres; 968 u32 pll_D_N; 969 int offset; 970 struct io_register *reg = NULL; 971 struct display_timing mode_crt_reg, panel_crt_reg; 972 struct crt_mode_table *panel_crt_table = NULL; 973 struct VideoModeTable *vmode_tbl = NULL; 974 975 DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n"); 976 /* Get mode table */ 977 mode_crt_reg = mode_crt_table->crtc; 978 /* Get panel table Pointer */ 979 vmode_tbl = viafb_get_modetbl_pointer(video_index); 980 panel_crt_table = vmode_tbl->crtc; 981 panel_crt_reg = panel_crt_table->crtc; 982 DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n"); 983 set_hres = plvds_setting_info->h_active; 984 set_vres = plvds_setting_info->v_active; 985 panel_hres = plvds_setting_info->lcd_panel_hres; 986 panel_vres = plvds_setting_info->lcd_panel_vres; 987 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) 988 viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info); 989 plvds_setting_info->vclk = panel_crt_table->clk; 990 if (set_iga == IGA1) { 991 /* IGA1 doesn't have LCD scaling, so set it as centering. */ 992 viafb_load_crtc_timing(lcd_centering_timging 993 (mode_crt_reg, panel_crt_reg), IGA1); 994 } else { 995 /* Expansion */ 996 if ((plvds_setting_info->display_method == 997 LCD_EXPANDSION) & ((set_hres != panel_hres) 998 || (set_vres != panel_vres))) { 999 /* expansion timing IGA2 loaded panel set timing*/ 1000 viafb_load_crtc_timing(panel_crt_reg, IGA2); 1001 DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n"); 1002 load_lcd_scaling(set_hres, set_vres, panel_hres, 1003 panel_vres); 1004 DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n"); 1005 } else { /* Centering */ 1006 /* centering timing IGA2 always loaded panel 1007 and mode releative timing */ 1008 viafb_load_crtc_timing(lcd_centering_timging 1009 (mode_crt_reg, panel_crt_reg), IGA2); 1010 viafb_write_reg_mask(CR79, VIACR, 0x00, 1011 BIT0 + BIT1 + BIT2); 1012 /* LCD scaling disabled */ 1013 } 1014 } 1015 1016 if (set_iga == IGA1_IGA2) { 1017 load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg); 1018 /* Fill shadow registers */ 1019 1020 switch (plvds_setting_info->lcd_panel_id) { 1021 case LCD_PANEL_ID0_640X480: 1022 offset = 80; 1023 break; 1024 case LCD_PANEL_ID1_800X600: 1025 case LCD_PANEL_IDA_800X480: 1026 offset = 110; 1027 break; 1028 case LCD_PANEL_ID2_1024X768: 1029 offset = 150; 1030 break; 1031 case LCD_PANEL_ID3_1280X768: 1032 case LCD_PANEL_ID4_1280X1024: 1033 case LCD_PANEL_ID5_1400X1050: 1034 case LCD_PANEL_ID9_1280X800: 1035 offset = 190; 1036 break; 1037 case LCD_PANEL_ID6_1600X1200: 1038 offset = 250; 1039 break; 1040 case LCD_PANEL_ID7_1366X768: 1041 case LCD_PANEL_IDB_1360X768: 1042 offset = 212; 1043 break; 1044 default: 1045 offset = 140; 1046 break; 1047 } 1048 1049 /* Offset for simultaneous */ 1050 reg_value = offset; 1051 viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num; 1052 reg = offset_reg.iga2_offset_reg.reg; 1053 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); 1054 DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n"); 1055 viafb_load_fetch_count_reg(set_hres, 4, IGA2); 1056 /* Fetch count for simultaneous */ 1057 } else { /* SAMM */ 1058 /* Offset for IGA2 only */ 1059 viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga); 1060 /* Fetch count for IGA2 only */ 1061 viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); 1062 1063 if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) 1064 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) 1065 viafb_load_FIFO_reg(set_iga, set_hres, set_vres); 1066 1067 viafb_set_color_depth(mode_bpp / 8, set_iga); 1068 } 1069 1070 fill_lcd_format(); 1071 1072 pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk); 1073 DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); 1074 viafb_set_vclock(pll_D_N, set_iga); 1075 1076 viafb_set_output_path(DEVICE_LCD, set_iga, 1077 plvds_chip_info->output_interface); 1078 lcd_patch_skew(plvds_setting_info, plvds_chip_info); 1079 1080 /* If K8M800, enable LCD Prefetch Mode. */ 1081 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) 1082 || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)) 1083 viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0); 1084 1085 load_lcd_patch_regs(set_hres, set_vres, 1086 plvds_setting_info->lcd_panel_id, set_iga); 1087 1088 DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n"); 1089 1090 /* Patch for non 32bit alignment mode */ 1091 via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info); 1092} 1093 1094static void integrated_lvds_disable(struct lvds_setting_information 1095 *plvds_setting_info, 1096 struct lvds_chip_information *plvds_chip_info) 1097{ 1098 bool turn_off_first_powersequence = false; 1099 bool turn_off_second_powersequence = false; 1100 if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface) 1101 turn_off_first_powersequence = true; 1102 if (INTERFACE_LVDS0 == plvds_chip_info->output_interface) 1103 turn_off_first_powersequence = true; 1104 if (INTERFACE_LVDS1 == plvds_chip_info->output_interface) 1105 turn_off_second_powersequence = true; 1106 if (turn_off_second_powersequence) { 1107 /* Use second power sequence control: */ 1108 1109 /* Turn off power sequence. */ 1110 viafb_write_reg_mask(CRD4, VIACR, 0, BIT1); 1111 1112 /* Turn off back light. */ 1113 viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7); 1114 } 1115 if (turn_off_first_powersequence) { 1116 /* Use first power sequence control: */ 1117 1118 /* Turn off power sequence. */ 1119 viafb_write_reg_mask(CR6A, VIACR, 0, BIT3); 1120 1121 /* Turn off back light. */ 1122 viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7); 1123 } 1124 1125 /* Turn DFP High/Low Pad off. */ 1126 viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3); 1127 1128 /* Power off LVDS channel. */ 1129 switch (plvds_chip_info->output_interface) { 1130 case INTERFACE_LVDS0: 1131 { 1132 viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7); 1133 break; 1134 } 1135 1136 case INTERFACE_LVDS1: 1137 { 1138 viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6); 1139 break; 1140 } 1141 1142 case INTERFACE_LVDS0LVDS1: 1143 { 1144 viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7); 1145 break; 1146 } 1147 } 1148} 1149 1150static void integrated_lvds_enable(struct lvds_setting_information 1151 *plvds_setting_info, 1152 struct lvds_chip_information *plvds_chip_info) 1153{ 1154 bool turn_on_first_powersequence = false; 1155 bool turn_on_second_powersequence = false; 1156 1157 DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n", 1158 plvds_chip_info->output_interface); 1159 if (plvds_setting_info->lcd_mode == LCD_SPWG) 1160 viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1); 1161 else 1162 viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1); 1163 if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface) 1164 turn_on_first_powersequence = true; 1165 if (INTERFACE_LVDS0 == plvds_chip_info->output_interface) 1166 turn_on_first_powersequence = true; 1167 if (INTERFACE_LVDS1 == plvds_chip_info->output_interface) 1168 turn_on_second_powersequence = true; 1169 1170 if (turn_on_second_powersequence) { 1171 /* Use second power sequence control: */ 1172 1173 /* Use hardware control power sequence. */ 1174 viafb_write_reg_mask(CRD3, VIACR, 0, BIT0); 1175 1176 /* Turn on back light. */ 1177 viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7); 1178 1179 /* Turn on hardware power sequence. */ 1180 viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1); 1181 } 1182 if (turn_on_first_powersequence) { 1183 /* Use first power sequence control: */ 1184 1185 /* Use hardware control power sequence. */ 1186 viafb_write_reg_mask(CR91, VIACR, 0, BIT0); 1187 1188 /* Turn on back light. */ 1189 viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7); 1190 1191 /* Turn on hardware power sequence. */ 1192 viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); 1193 } 1194 1195 /* Turn DFP High/Low pad on. */ 1196 viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3); 1197 1198 /* Power on LVDS channel. */ 1199 switch (plvds_chip_info->output_interface) { 1200 case INTERFACE_LVDS0: 1201 { 1202 viafb_write_reg_mask(CRD2, VIACR, 0, BIT7); 1203 break; 1204 } 1205 1206 case INTERFACE_LVDS1: 1207 { 1208 viafb_write_reg_mask(CRD2, VIACR, 0, BIT6); 1209 break; 1210 } 1211 1212 case INTERFACE_LVDS0LVDS1: 1213 { 1214 viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7); 1215 break; 1216 } 1217 } 1218} 1219 1220void viafb_lcd_disable(void) 1221{ 1222 1223 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 1224 lcd_powersequence_off(); 1225 /* DI1 pad off */ 1226 viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30); 1227 } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { 1228 if (viafb_LCD2_ON 1229 && (INTEGRATED_LVDS == 1230 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name)) 1231 integrated_lvds_disable(viaparinfo->lvds_setting_info, 1232 &viaparinfo->chip_info->lvds_chip_info2); 1233 if (INTEGRATED_LVDS == 1234 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) 1235 integrated_lvds_disable(viaparinfo->lvds_setting_info, 1236 &viaparinfo->chip_info->lvds_chip_info); 1237 if (VT1636_LVDS == viaparinfo->chip_info-> 1238 lvds_chip_info.lvds_chip_name) 1239 viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, 1240 &viaparinfo->chip_info->lvds_chip_info); 1241 } else if (VT1636_LVDS == 1242 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 1243 viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, 1244 &viaparinfo->chip_info->lvds_chip_info); 1245 } else { 1246 /* DFP-HL pad off */ 1247 viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F); 1248 /* Backlight off */ 1249 viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20); 1250 /* 24 bit DI data paht off */ 1251 viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80); 1252 /* Simultaneout disabled */ 1253 viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); 1254 } 1255 1256 /* Disable expansion bit */ 1257 viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01); 1258 /* CRT path set to IGA1 */ 1259 viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40); 1260 /* Simultaneout disabled */ 1261 viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); 1262 /* IGA2 path disabled */ 1263 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80); 1264 1265} 1266 1267void viafb_lcd_enable(void) 1268{ 1269 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 1270 /* DI1 pad on */ 1271 viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); 1272 lcd_powersequence_on(); 1273 } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { 1274 if (viafb_LCD2_ON && (INTEGRATED_LVDS == 1275 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name)) 1276 integrated_lvds_enable(viaparinfo->lvds_setting_info2, \ 1277 &viaparinfo->chip_info->lvds_chip_info2); 1278 if (INTEGRATED_LVDS == 1279 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) 1280 integrated_lvds_enable(viaparinfo->lvds_setting_info, 1281 &viaparinfo->chip_info->lvds_chip_info); 1282 if (VT1636_LVDS == viaparinfo->chip_info-> 1283 lvds_chip_info.lvds_chip_name) 1284 viafb_enable_lvds_vt1636(viaparinfo-> 1285 lvds_setting_info, &viaparinfo->chip_info-> 1286 lvds_chip_info); 1287 } else if (VT1636_LVDS == 1288 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 1289 viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info, 1290 &viaparinfo->chip_info->lvds_chip_info); 1291 } else { 1292 /* DFP-HL pad on */ 1293 viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F); 1294 /* Backlight on */ 1295 viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20); 1296 /* 24 bit DI data paht on */ 1297 viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80); 1298 1299 /* Set data source selection bit by iga path */ 1300 if (viaparinfo->lvds_setting_info->iga_path == IGA1) { 1301 /* DFP-H set to IGA1 */ 1302 viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10); 1303 /* DFP-L set to IGA1 */ 1304 viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10); 1305 } else { 1306 /* DFP-H set to IGA2 */ 1307 viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10); 1308 /* DFP-L set to IGA2 */ 1309 viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10); 1310 } 1311 /* LCD enabled */ 1312 viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48); 1313 } 1314 1315 if ((viaparinfo->lvds_setting_info->iga_path == IGA1) 1316 || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) { 1317 /* CRT path set to IGA2 */ 1318 viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40); 1319 /* IGA2 path disabled */ 1320 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80); 1321 /* IGA2 path enabled */ 1322 } else { /* IGA2 */ 1323 viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80); 1324 } 1325 1326} 1327 1328static void lcd_powersequence_off(void) 1329{ 1330 int i, mask, data; 1331 1332 /* Software control power sequence */ 1333 viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11); 1334 1335 for (i = 0; i < 3; i++) { 1336 mask = PowerSequenceOff[0][i]; 1337 data = PowerSequenceOff[1][i] & mask; 1338 viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask); 1339 udelay(PowerSequenceOff[2][i]); 1340 } 1341 1342 /* Disable LCD */ 1343 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08); 1344} 1345 1346static void lcd_powersequence_on(void) 1347{ 1348 int i, mask, data; 1349 1350 /* Software control power sequence */ 1351 viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11); 1352 1353 /* Enable LCD */ 1354 viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08); 1355 1356 for (i = 0; i < 3; i++) { 1357 mask = PowerSequenceOn[0][i]; 1358 data = PowerSequenceOn[1][i] & mask; 1359 viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask); 1360 udelay(PowerSequenceOn[2][i]); 1361 } 1362 1363 udelay(1); 1364} 1365 1366static void fill_lcd_format(void) 1367{ 1368 u8 bdithering = 0, bdual = 0; 1369 1370 if (viaparinfo->lvds_setting_info->device_lcd_dualedge) 1371 bdual = BIT4; 1372 if (viaparinfo->lvds_setting_info->LCDDithering) 1373 bdithering = BIT0; 1374 /* Dual & Dithering */ 1375 viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0); 1376} 1377 1378static void check_diport_of_integrated_lvds( 1379 struct lvds_chip_information *plvds_chip_info, 1380 struct lvds_setting_information 1381 *plvds_setting_info) 1382{ 1383 /* Determine LCD DI Port by hardware layout. */ 1384 switch (viafb_display_hardware_layout) { 1385 case HW_LAYOUT_LCD_ONLY: 1386 { 1387 if (plvds_setting_info->device_lcd_dualedge) { 1388 plvds_chip_info->output_interface = 1389 INTERFACE_LVDS0LVDS1; 1390 } else { 1391 plvds_chip_info->output_interface = 1392 INTERFACE_LVDS0; 1393 } 1394 1395 break; 1396 } 1397 1398 case HW_LAYOUT_DVI_ONLY: 1399 { 1400 plvds_chip_info->output_interface = INTERFACE_NONE; 1401 break; 1402 } 1403 1404 case HW_LAYOUT_LCD1_LCD2: 1405 case HW_LAYOUT_LCD_EXTERNAL_LCD2: 1406 { 1407 plvds_chip_info->output_interface = 1408 INTERFACE_LVDS0LVDS1; 1409 break; 1410 } 1411 1412 case HW_LAYOUT_LCD_DVI: 1413 { 1414 plvds_chip_info->output_interface = INTERFACE_LVDS1; 1415 break; 1416 } 1417 1418 default: 1419 { 1420 plvds_chip_info->output_interface = INTERFACE_LVDS1; 1421 break; 1422 } 1423 } 1424 1425 DEBUG_MSG(KERN_INFO 1426 "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n", 1427 viafb_display_hardware_layout, 1428 plvds_chip_info->output_interface); 1429} 1430 1431void viafb_init_lvds_output_interface(struct lvds_chip_information 1432 *plvds_chip_info, 1433 struct lvds_setting_information 1434 *plvds_setting_info) 1435{ 1436 if (INTERFACE_NONE != plvds_chip_info->output_interface) { 1437 /*Do nothing, lcd port is specified by module parameter */ 1438 return; 1439 } 1440 1441 switch (plvds_chip_info->lvds_chip_name) { 1442 1443 case VT1636_LVDS: 1444 switch (viaparinfo->chip_info->gfx_chip_name) { 1445 case UNICHROME_CX700: 1446 plvds_chip_info->output_interface = INTERFACE_DVP1; 1447 break; 1448 case UNICHROME_CN700: 1449 plvds_chip_info->output_interface = INTERFACE_DFP_LOW; 1450 break; 1451 default: 1452 plvds_chip_info->output_interface = INTERFACE_DVP0; 1453 break; 1454 } 1455 break; 1456 1457 case INTEGRATED_LVDS: 1458 check_diport_of_integrated_lvds(plvds_chip_info, 1459 plvds_setting_info); 1460 break; 1461 1462 default: 1463 switch (viaparinfo->chip_info->gfx_chip_name) { 1464 case UNICHROME_K8M890: 1465 case UNICHROME_P4M900: 1466 case UNICHROME_P4M890: 1467 plvds_chip_info->output_interface = INTERFACE_DFP_LOW; 1468 break; 1469 default: 1470 plvds_chip_info->output_interface = INTERFACE_DFP; 1471 break; 1472 } 1473 break; 1474 } 1475} 1476 1477static struct display_timing lcd_centering_timging(struct display_timing 1478 mode_crt_reg, 1479 struct display_timing panel_crt_reg) 1480{ 1481 struct display_timing crt_reg; 1482 1483 crt_reg.hor_total = panel_crt_reg.hor_total; 1484 crt_reg.hor_addr = mode_crt_reg.hor_addr; 1485 crt_reg.hor_blank_start = 1486 (panel_crt_reg.hor_addr - mode_crt_reg.hor_addr) / 2 + 1487 crt_reg.hor_addr; 1488 crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end; 1489 crt_reg.hor_sync_start = 1490 (panel_crt_reg.hor_sync_start - 1491 panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start; 1492 crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end; 1493 1494 crt_reg.ver_total = panel_crt_reg.ver_total; 1495 crt_reg.ver_addr = mode_crt_reg.ver_addr; 1496 crt_reg.ver_blank_start = 1497 (panel_crt_reg.ver_addr - mode_crt_reg.ver_addr) / 2 + 1498 crt_reg.ver_addr; 1499 crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end; 1500 crt_reg.ver_sync_start = 1501 (panel_crt_reg.ver_sync_start - 1502 panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start; 1503 crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end; 1504 1505 return crt_reg; 1506} 1507 1508static void load_crtc_shadow_timing(struct display_timing mode_timing, 1509 struct display_timing panel_timing) 1510{ 1511 struct io_register *reg = NULL; 1512 int i; 1513 int viafb_load_reg_Num = 0; 1514 int reg_value = 0; 1515 1516 if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) { 1517 /* Expansion */ 1518 for (i = 12; i < 20; i++) { 1519 switch (i) { 1520 case H_TOTAL_SHADOW_INDEX: 1521 reg_value = 1522 IGA2_HOR_TOTAL_SHADOW_FORMULA 1523 (panel_timing.hor_total); 1524 viafb_load_reg_Num = 1525 iga2_shadow_crtc_reg.hor_total_shadow. 1526 reg_num; 1527 reg = iga2_shadow_crtc_reg.hor_total_shadow.reg; 1528 break; 1529 case H_BLANK_END_SHADOW_INDEX: 1530 reg_value = 1531 IGA2_HOR_BLANK_END_SHADOW_FORMULA 1532 (panel_timing.hor_blank_start, 1533 panel_timing.hor_blank_end); 1534 viafb_load_reg_Num = 1535 iga2_shadow_crtc_reg. 1536 hor_blank_end_shadow.reg_num; 1537 reg = 1538 iga2_shadow_crtc_reg. 1539 hor_blank_end_shadow.reg; 1540 break; 1541 case V_TOTAL_SHADOW_INDEX: 1542 reg_value = 1543 IGA2_VER_TOTAL_SHADOW_FORMULA 1544 (panel_timing.ver_total); 1545 viafb_load_reg_Num = 1546 iga2_shadow_crtc_reg.ver_total_shadow. 1547 reg_num; 1548 reg = iga2_shadow_crtc_reg.ver_total_shadow.reg; 1549 break; 1550 case V_ADDR_SHADOW_INDEX: 1551 reg_value = 1552 IGA2_VER_ADDR_SHADOW_FORMULA 1553 (panel_timing.ver_addr); 1554 viafb_load_reg_Num = 1555 iga2_shadow_crtc_reg.ver_addr_shadow. 1556 reg_num; 1557 reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg; 1558 break; 1559 case V_BLANK_SATRT_SHADOW_INDEX: 1560 reg_value = 1561 IGA2_VER_BLANK_START_SHADOW_FORMULA 1562 (panel_timing.ver_blank_start); 1563 viafb_load_reg_Num = 1564 iga2_shadow_crtc_reg. 1565 ver_blank_start_shadow.reg_num; 1566 reg = 1567 iga2_shadow_crtc_reg. 1568 ver_blank_start_shadow.reg; 1569 break; 1570 case V_BLANK_END_SHADOW_INDEX: 1571 reg_value = 1572 IGA2_VER_BLANK_END_SHADOW_FORMULA 1573 (panel_timing.ver_blank_start, 1574 panel_timing.ver_blank_end); 1575 viafb_load_reg_Num = 1576 iga2_shadow_crtc_reg. 1577 ver_blank_end_shadow.reg_num; 1578 reg = 1579 iga2_shadow_crtc_reg. 1580 ver_blank_end_shadow.reg; 1581 break; 1582 case V_SYNC_SATRT_SHADOW_INDEX: 1583 reg_value = 1584 IGA2_VER_SYNC_START_SHADOW_FORMULA 1585 (panel_timing.ver_sync_start); 1586 viafb_load_reg_Num = 1587 iga2_shadow_crtc_reg. 1588 ver_sync_start_shadow.reg_num; 1589 reg = 1590 iga2_shadow_crtc_reg. 1591 ver_sync_start_shadow.reg; 1592 break; 1593 case V_SYNC_END_SHADOW_INDEX: 1594 reg_value = 1595 IGA2_VER_SYNC_END_SHADOW_FORMULA 1596 (panel_timing.ver_sync_start, 1597 panel_timing.ver_sync_end); 1598 viafb_load_reg_Num = 1599 iga2_shadow_crtc_reg. 1600 ver_sync_end_shadow.reg_num; 1601 reg = 1602 iga2_shadow_crtc_reg. 1603 ver_sync_end_shadow.reg; 1604 break; 1605 } 1606 viafb_load_reg(reg_value, 1607 viafb_load_reg_Num, reg, VIACR); 1608 } 1609 } else { /* Centering */ 1610 for (i = 12; i < 20; i++) { 1611 switch (i) { 1612 case H_TOTAL_SHADOW_INDEX: 1613 reg_value = 1614 IGA2_HOR_TOTAL_SHADOW_FORMULA 1615 (panel_timing.hor_total); 1616 viafb_load_reg_Num = 1617 iga2_shadow_crtc_reg.hor_total_shadow. 1618 reg_num; 1619 reg = iga2_shadow_crtc_reg.hor_total_shadow.reg; 1620 break; 1621 case H_BLANK_END_SHADOW_INDEX: 1622 reg_value = 1623 IGA2_HOR_BLANK_END_SHADOW_FORMULA 1624 (panel_timing.hor_blank_start, 1625 panel_timing.hor_blank_end); 1626 viafb_load_reg_Num = 1627 iga2_shadow_crtc_reg. 1628 hor_blank_end_shadow.reg_num; 1629 reg = 1630 iga2_shadow_crtc_reg. 1631 hor_blank_end_shadow.reg; 1632 break; 1633 case V_TOTAL_SHADOW_INDEX: 1634 reg_value = 1635 IGA2_VER_TOTAL_SHADOW_FORMULA 1636 (panel_timing.ver_total); 1637 viafb_load_reg_Num = 1638 iga2_shadow_crtc_reg.ver_total_shadow. 1639 reg_num; 1640 reg = iga2_shadow_crtc_reg.ver_total_shadow.reg; 1641 break; 1642 case V_ADDR_SHADOW_INDEX: 1643 reg_value = 1644 IGA2_VER_ADDR_SHADOW_FORMULA 1645 (mode_timing.ver_addr); 1646 viafb_load_reg_Num = 1647 iga2_shadow_crtc_reg.ver_addr_shadow. 1648 reg_num; 1649 reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg; 1650 break; 1651 case V_BLANK_SATRT_SHADOW_INDEX: 1652 reg_value = 1653 IGA2_VER_BLANK_START_SHADOW_FORMULA 1654 (mode_timing.ver_blank_start); 1655 viafb_load_reg_Num = 1656 iga2_shadow_crtc_reg. 1657 ver_blank_start_shadow.reg_num; 1658 reg = 1659 iga2_shadow_crtc_reg. 1660 ver_blank_start_shadow.reg; 1661 break; 1662 case V_BLANK_END_SHADOW_INDEX: 1663 reg_value = 1664 IGA2_VER_BLANK_END_SHADOW_FORMULA 1665 (panel_timing.ver_blank_start, 1666 panel_timing.ver_blank_end); 1667 viafb_load_reg_Num = 1668 iga2_shadow_crtc_reg. 1669 ver_blank_end_shadow.reg_num; 1670 reg = 1671 iga2_shadow_crtc_reg. 1672 ver_blank_end_shadow.reg; 1673 break; 1674 case V_SYNC_SATRT_SHADOW_INDEX: 1675 reg_value = 1676 IGA2_VER_SYNC_START_SHADOW_FORMULA( 1677 (panel_timing.ver_sync_start - 1678 panel_timing.ver_blank_start) + 1679 (panel_timing.ver_addr - 1680 mode_timing.ver_addr) / 2 + 1681 mode_timing.ver_addr); 1682 viafb_load_reg_Num = 1683 iga2_shadow_crtc_reg.ver_sync_start_shadow. 1684 reg_num; 1685 reg = 1686 iga2_shadow_crtc_reg.ver_sync_start_shadow. 1687 reg; 1688 break; 1689 case V_SYNC_END_SHADOW_INDEX: 1690 reg_value = 1691 IGA2_VER_SYNC_END_SHADOW_FORMULA( 1692 (panel_timing.ver_sync_start - 1693 panel_timing.ver_blank_start) + 1694 (panel_timing.ver_addr - 1695 mode_timing.ver_addr) / 2 + 1696 mode_timing.ver_addr, 1697 panel_timing.ver_sync_end); 1698 viafb_load_reg_Num = 1699 iga2_shadow_crtc_reg.ver_sync_end_shadow. 1700 reg_num; 1701 reg = 1702 iga2_shadow_crtc_reg.ver_sync_end_shadow. 1703 reg; 1704 break; 1705 } 1706 viafb_load_reg(reg_value, 1707 viafb_load_reg_Num, reg, VIACR); 1708 } 1709 } 1710} 1711 1712bool viafb_lcd_get_mobile_state(bool *mobile) 1713{ 1714 unsigned char *romptr, *tableptr; 1715 u8 core_base; 1716 unsigned char *biosptr; 1717 /* Rom address */ 1718 u32 romaddr = 0x000C0000; 1719 u16 start_pattern = 0; 1720 1721 biosptr = ioremap(romaddr, 0x10000); 1722 1723 memcpy(&start_pattern, biosptr, 2); 1724 /* Compare pattern */ 1725 if (start_pattern == 0xAA55) { 1726 /* Get the start of Table */ 1727 /* 0x1B means BIOS offset position */ 1728 romptr = biosptr + 0x1B; 1729 tableptr = biosptr + *((u16 *) romptr); 1730 1731 /* Get the start of biosver structure */ 1732 /* 18 means BIOS version position. */ 1733 romptr = tableptr + 18; 1734 romptr = biosptr + *((u16 *) romptr); 1735 1736 /* The offset should be 44, but the 1737 actual image is less three char. */ 1738 /* pRom += 44; */ 1739 romptr += 41; 1740 1741 core_base = *romptr++; 1742 1743 if (core_base & 0x8) 1744 *mobile = false; 1745 else 1746 *mobile = true; 1747 /* release memory */ 1748 iounmap(biosptr); 1749 1750 return true; 1751 } else { 1752 iounmap(biosptr); 1753 return false; 1754 } 1755} 1756 1757static void viafb_load_scaling_factor_for_p4m900(int set_hres, 1758 int set_vres, int panel_hres, int panel_vres) 1759{ 1760 int h_scaling_factor; 1761 int v_scaling_factor; 1762 u8 cra2 = 0; 1763 u8 cr77 = 0; 1764 u8 cr78 = 0; 1765 u8 cr79 = 0; 1766 u8 cr9f = 0; 1767 /* Check if expansion for horizontal */ 1768 if (set_hres < panel_hres) { 1769 /* Load Horizontal Scaling Factor */ 1770 1771 /* For VIA_K8M800 or later chipsets. */ 1772 h_scaling_factor = 1773 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); 1774 /* HSCaleFactor[1:0] at CR9F[1:0] */ 1775 cr9f = h_scaling_factor & 0x0003; 1776 /* HSCaleFactor[9:2] at CR77[7:0] */ 1777 cr77 = (h_scaling_factor & 0x03FC) >> 2; 1778 /* HSCaleFactor[11:10] at CR79[5:4] */ 1779 cr79 = (h_scaling_factor & 0x0C00) >> 10; 1780 cr79 <<= 4; 1781 1782 /* Horizontal scaling enabled */ 1783 cra2 = 0xC0; 1784 1785 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n", 1786 h_scaling_factor); 1787 } else { 1788 /* Horizontal scaling disabled */ 1789 cra2 = 0x00; 1790 } 1791 1792 /* Check if expansion for vertical */ 1793 if (set_vres < panel_vres) { 1794 /* Load Vertical Scaling Factor */ 1795 1796 /* For VIA_K8M800 or later chipsets. */ 1797 v_scaling_factor = 1798 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); 1799 1800 /* Vertical scaling enabled */ 1801 cra2 |= 0x08; 1802 /* VSCaleFactor[0] at CR79[3] */ 1803 cr79 |= ((v_scaling_factor & 0x0001) << 3); 1804 /* VSCaleFactor[8:1] at CR78[7:0] */ 1805 cr78 |= (v_scaling_factor & 0x01FE) >> 1; 1806 /* VSCaleFactor[10:9] at CR79[7:6] */ 1807 cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6; 1808 1809 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n", 1810 v_scaling_factor); 1811 } else { 1812 /* Vertical scaling disabled */ 1813 cra2 |= 0x00; 1814 } 1815 1816 viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7); 1817 viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF); 1818 viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF); 1819 viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8); 1820 viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1); 1821}