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 } 993