162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 462306a36Sopenharmony_ci * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include <linux/via-core.h> 862306a36Sopenharmony_ci#include <linux/via_i2c.h> 962306a36Sopenharmony_ci#include "global.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#define viafb_compact_res(x, y) (((x)<<16)|(y)) 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* CLE266 Software Power Sequence */ 1462306a36Sopenharmony_ci/* {Mask}, {Data}, {Delay} */ 1562306a36Sopenharmony_cistatic const int PowerSequenceOn[3][3] = { 1662306a36Sopenharmony_ci {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} 1762306a36Sopenharmony_ci}; 1862306a36Sopenharmony_cistatic const int PowerSequenceOff[3][3] = { 1962306a36Sopenharmony_ci {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} 2062306a36Sopenharmony_ci}; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistatic struct _lcd_scaling_factor lcd_scaling_factor = { 2362306a36Sopenharmony_ci /* LCD Horizontal Scaling Factor Register */ 2462306a36Sopenharmony_ci {LCD_HOR_SCALING_FACTOR_REG_NUM, 2562306a36Sopenharmony_ci {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } }, 2662306a36Sopenharmony_ci /* LCD Vertical Scaling Factor Register */ 2762306a36Sopenharmony_ci {LCD_VER_SCALING_FACTOR_REG_NUM, 2862306a36Sopenharmony_ci {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } } 2962306a36Sopenharmony_ci}; 3062306a36Sopenharmony_cistatic struct _lcd_scaling_factor lcd_scaling_factor_CLE = { 3162306a36Sopenharmony_ci /* LCD Horizontal Scaling Factor Register */ 3262306a36Sopenharmony_ci {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } }, 3362306a36Sopenharmony_ci /* LCD Vertical Scaling Factor Register */ 3462306a36Sopenharmony_ci {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } } 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic bool lvds_identify_integratedlvds(void); 3862306a36Sopenharmony_cistatic void fp_id_to_vindex(int panel_id); 3962306a36Sopenharmony_cistatic int lvds_register_read(int index); 4062306a36Sopenharmony_cistatic void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, 4162306a36Sopenharmony_ci int panel_vres); 4262306a36Sopenharmony_cistatic void lcd_patch_skew_dvp0(struct lvds_setting_information 4362306a36Sopenharmony_ci *plvds_setting_info, 4462306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info); 4562306a36Sopenharmony_cistatic void lcd_patch_skew_dvp1(struct lvds_setting_information 4662306a36Sopenharmony_ci *plvds_setting_info, 4762306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info); 4862306a36Sopenharmony_cistatic void lcd_patch_skew(struct lvds_setting_information 4962306a36Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic void integrated_lvds_disable(struct lvds_setting_information 5262306a36Sopenharmony_ci *plvds_setting_info, 5362306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info); 5462306a36Sopenharmony_cistatic void integrated_lvds_enable(struct lvds_setting_information 5562306a36Sopenharmony_ci *plvds_setting_info, 5662306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info); 5762306a36Sopenharmony_cistatic void lcd_powersequence_off(void); 5862306a36Sopenharmony_cistatic void lcd_powersequence_on(void); 5962306a36Sopenharmony_cistatic void fill_lcd_format(void); 6062306a36Sopenharmony_cistatic void check_diport_of_integrated_lvds( 6162306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info, 6262306a36Sopenharmony_ci struct lvds_setting_information 6362306a36Sopenharmony_ci *plvds_setting_info); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic inline bool check_lvds_chip(int device_id_subaddr, int device_id) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci return lvds_register_read(device_id_subaddr) == device_id; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_civoid viafb_init_lcd_size(void) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci fp_id_to_vindex(viafb_lcd_panel_id); 7562306a36Sopenharmony_ci viaparinfo->lvds_setting_info2->lcd_panel_hres = 7662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres; 7762306a36Sopenharmony_ci viaparinfo->lvds_setting_info2->lcd_panel_vres = 7862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres; 7962306a36Sopenharmony_ci viaparinfo->lvds_setting_info2->device_lcd_dualedge = 8062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge; 8162306a36Sopenharmony_ci viaparinfo->lvds_setting_info2->LCDDithering = 8262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering; 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic bool lvds_identify_integratedlvds(void) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) { 8862306a36Sopenharmony_ci /* Two dual channel LCD (Internal LVDS + External LVDS): */ 8962306a36Sopenharmony_ci /* If we have an external LVDS, such as VT1636, we should 9062306a36Sopenharmony_ci have its chip ID already. */ 9162306a36Sopenharmony_ci if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 9262306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = 9362306a36Sopenharmony_ci INTEGRATED_LVDS; 9462306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "Support two dual channel LVDS! " 9562306a36Sopenharmony_ci "(Internal LVDS + External LVDS)\n"); 9662306a36Sopenharmony_ci } else { 9762306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 9862306a36Sopenharmony_ci INTEGRATED_LVDS; 9962306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "Not found external LVDS, " 10062306a36Sopenharmony_ci "so can't support two dual channel LVDS!\n"); 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) { 10362306a36Sopenharmony_ci /* Two single channel LCD (Internal LVDS + Internal LVDS): */ 10462306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 10562306a36Sopenharmony_ci INTEGRATED_LVDS; 10662306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = 10762306a36Sopenharmony_ci INTEGRATED_LVDS; 10862306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "Support two single channel LVDS! " 10962306a36Sopenharmony_ci "(Internal LVDS + Internal LVDS)\n"); 11062306a36Sopenharmony_ci } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) { 11162306a36Sopenharmony_ci /* If we have found external LVDS, just use it, 11262306a36Sopenharmony_ci otherwise, we will use internal LVDS as default. */ 11362306a36Sopenharmony_ci if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 11462306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 11562306a36Sopenharmony_ci INTEGRATED_LVDS; 11662306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n"); 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci } else { 11962306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 12062306a36Sopenharmony_ci NON_LVDS_TRANSMITTER; 12162306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "Do not support LVDS!\n"); 12262306a36Sopenharmony_ci return false; 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci return true; 12662306a36Sopenharmony_ci} 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cibool viafb_lvds_trasmitter_identify(void) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci if (viafb_lvds_identify_vt1636(VIA_PORT_31)) { 13162306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31; 13262306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO 13362306a36Sopenharmony_ci "Found VIA VT1636 LVDS on port i2c 0x31\n"); 13462306a36Sopenharmony_ci } else { 13562306a36Sopenharmony_ci if (viafb_lvds_identify_vt1636(VIA_PORT_2C)) { 13662306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.i2c_port = 13762306a36Sopenharmony_ci VIA_PORT_2C; 13862306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO 13962306a36Sopenharmony_ci "Found VIA VT1636 LVDS on port gpio 0x2c\n"); 14062306a36Sopenharmony_ci } 14162306a36Sopenharmony_ci } 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) 14462306a36Sopenharmony_ci lvds_identify_integratedlvds(); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) 14762306a36Sopenharmony_ci return true; 14862306a36Sopenharmony_ci /* Check for VT1631: */ 14962306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS; 15062306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 15162306a36Sopenharmony_ci VT1631_LVDS_I2C_ADDR; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID)) { 15462306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n"); 15562306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "\n %2d", 15662306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); 15762306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "\n %2d", 15862306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); 15962306a36Sopenharmony_ci return true; 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 16362306a36Sopenharmony_ci NON_LVDS_TRANSMITTER; 16462306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 16562306a36Sopenharmony_ci VT1631_LVDS_I2C_ADDR; 16662306a36Sopenharmony_ci return false; 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic void fp_id_to_vindex(int panel_id) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci if (panel_id > LCD_PANEL_ID_MAXIMUM) 17462306a36Sopenharmony_ci viafb_lcd_panel_id = panel_id = 17562306a36Sopenharmony_ci viafb_read_reg(VIACR, CR3F) & 0x0F; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci switch (panel_id) { 17862306a36Sopenharmony_ci case 0x0: 17962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 640; 18062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 480; 18162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 18262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 18362306a36Sopenharmony_ci break; 18462306a36Sopenharmony_ci case 0x1: 18562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 18662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 18762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 18862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 18962306a36Sopenharmony_ci break; 19062306a36Sopenharmony_ci case 0x2: 19162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 19262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 19362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 19462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 19562306a36Sopenharmony_ci break; 19662306a36Sopenharmony_ci case 0x3: 19762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 19862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 19962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 20062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 20162306a36Sopenharmony_ci break; 20262306a36Sopenharmony_ci case 0x4: 20362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 20462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; 20562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 20662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 20762306a36Sopenharmony_ci break; 20862306a36Sopenharmony_ci case 0x5: 20962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; 21062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; 21162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 21262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 21362306a36Sopenharmony_ci break; 21462306a36Sopenharmony_ci case 0x6: 21562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; 21662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; 21762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 21862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 21962306a36Sopenharmony_ci break; 22062306a36Sopenharmony_ci case 0x8: 22162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 22262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 480; 22362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 22462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 22562306a36Sopenharmony_ci break; 22662306a36Sopenharmony_ci case 0x9: 22762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 22862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 22962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 23062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 23162306a36Sopenharmony_ci break; 23262306a36Sopenharmony_ci case 0xA: 23362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 23462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 23562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 23662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 23762306a36Sopenharmony_ci break; 23862306a36Sopenharmony_ci case 0xB: 23962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 24062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 24162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 24262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 24362306a36Sopenharmony_ci break; 24462306a36Sopenharmony_ci case 0xC: 24562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 24662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 24762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 24862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 24962306a36Sopenharmony_ci break; 25062306a36Sopenharmony_ci case 0xD: 25162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 25262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; 25362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 25462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 25562306a36Sopenharmony_ci break; 25662306a36Sopenharmony_ci case 0xE: 25762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; 25862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; 25962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 26062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 26162306a36Sopenharmony_ci break; 26262306a36Sopenharmony_ci case 0xF: 26362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; 26462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; 26562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 26662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 26762306a36Sopenharmony_ci break; 26862306a36Sopenharmony_ci case 0x10: 26962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; 27062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 27162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 27262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 27362306a36Sopenharmony_ci break; 27462306a36Sopenharmony_ci case 0x11: 27562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; 27662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 27762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 27862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 27962306a36Sopenharmony_ci break; 28062306a36Sopenharmony_ci case 0x12: 28162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 28262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 28362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 28462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 28562306a36Sopenharmony_ci break; 28662306a36Sopenharmony_ci case 0x13: 28762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 28862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 800; 28962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 29062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 29162306a36Sopenharmony_ci break; 29262306a36Sopenharmony_ci case 0x14: 29362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; 29462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 29562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 29662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 29762306a36Sopenharmony_ci break; 29862306a36Sopenharmony_ci case 0x15: 29962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; 30062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 768; 30162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; 30262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 30362306a36Sopenharmony_ci break; 30462306a36Sopenharmony_ci case 0x16: 30562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 480; 30662306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 640; 30762306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 30862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 30962306a36Sopenharmony_ci break; 31062306a36Sopenharmony_ci case 0x17: 31162306a36Sopenharmony_ci /* OLPC XO-1.5 panel */ 31262306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 1200; 31362306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 900; 31462306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 31562306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 0; 31662306a36Sopenharmony_ci break; 31762306a36Sopenharmony_ci default: 31862306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 31962306a36Sopenharmony_ci viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 32062306a36Sopenharmony_ci viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 32162306a36Sopenharmony_ci viaparinfo->lvds_setting_info->LCDDithering = 1; 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistatic int lvds_register_read(int index) 32662306a36Sopenharmony_ci{ 32762306a36Sopenharmony_ci u8 data; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci viafb_i2c_readbyte(VIA_PORT_2C, 33062306a36Sopenharmony_ci (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, 33162306a36Sopenharmony_ci (u8) index, &data); 33262306a36Sopenharmony_ci return data; 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_cistatic void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, 33662306a36Sopenharmony_ci int panel_vres) 33762306a36Sopenharmony_ci{ 33862306a36Sopenharmony_ci int reg_value = 0; 33962306a36Sopenharmony_ci int viafb_load_reg_num; 34062306a36Sopenharmony_ci struct io_register *reg = NULL; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n"); 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci /* LCD Scaling Enable */ 34562306a36Sopenharmony_ci viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci /* Check if expansion for horizontal */ 34862306a36Sopenharmony_ci if (set_hres < panel_hres) { 34962306a36Sopenharmony_ci /* Load Horizontal Scaling Factor */ 35062306a36Sopenharmony_ci switch (viaparinfo->chip_info->gfx_chip_name) { 35162306a36Sopenharmony_ci case UNICHROME_CLE266: 35262306a36Sopenharmony_ci case UNICHROME_K400: 35362306a36Sopenharmony_ci reg_value = 35462306a36Sopenharmony_ci CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); 35562306a36Sopenharmony_ci viafb_load_reg_num = 35662306a36Sopenharmony_ci lcd_scaling_factor_CLE.lcd_hor_scaling_factor. 35762306a36Sopenharmony_ci reg_num; 35862306a36Sopenharmony_ci reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg; 35962306a36Sopenharmony_ci viafb_load_reg(reg_value, 36062306a36Sopenharmony_ci viafb_load_reg_num, reg, VIACR); 36162306a36Sopenharmony_ci break; 36262306a36Sopenharmony_ci case UNICHROME_K800: 36362306a36Sopenharmony_ci case UNICHROME_PM800: 36462306a36Sopenharmony_ci case UNICHROME_CN700: 36562306a36Sopenharmony_ci case UNICHROME_CX700: 36662306a36Sopenharmony_ci case UNICHROME_K8M890: 36762306a36Sopenharmony_ci case UNICHROME_P4M890: 36862306a36Sopenharmony_ci case UNICHROME_P4M900: 36962306a36Sopenharmony_ci case UNICHROME_CN750: 37062306a36Sopenharmony_ci case UNICHROME_VX800: 37162306a36Sopenharmony_ci case UNICHROME_VX855: 37262306a36Sopenharmony_ci case UNICHROME_VX900: 37362306a36Sopenharmony_ci reg_value = 37462306a36Sopenharmony_ci K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); 37562306a36Sopenharmony_ci /* Horizontal scaling enabled */ 37662306a36Sopenharmony_ci viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6); 37762306a36Sopenharmony_ci viafb_load_reg_num = 37862306a36Sopenharmony_ci lcd_scaling_factor.lcd_hor_scaling_factor.reg_num; 37962306a36Sopenharmony_ci reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg; 38062306a36Sopenharmony_ci viafb_load_reg(reg_value, 38162306a36Sopenharmony_ci viafb_load_reg_num, reg, VIACR); 38262306a36Sopenharmony_ci break; 38362306a36Sopenharmony_ci } 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value); 38662306a36Sopenharmony_ci } else { 38762306a36Sopenharmony_ci /* Horizontal scaling disabled */ 38862306a36Sopenharmony_ci viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7); 38962306a36Sopenharmony_ci } 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci /* Check if expansion for vertical */ 39262306a36Sopenharmony_ci if (set_vres < panel_vres) { 39362306a36Sopenharmony_ci /* Load Vertical Scaling Factor */ 39462306a36Sopenharmony_ci switch (viaparinfo->chip_info->gfx_chip_name) { 39562306a36Sopenharmony_ci case UNICHROME_CLE266: 39662306a36Sopenharmony_ci case UNICHROME_K400: 39762306a36Sopenharmony_ci reg_value = 39862306a36Sopenharmony_ci CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres); 39962306a36Sopenharmony_ci viafb_load_reg_num = 40062306a36Sopenharmony_ci lcd_scaling_factor_CLE.lcd_ver_scaling_factor. 40162306a36Sopenharmony_ci reg_num; 40262306a36Sopenharmony_ci reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg; 40362306a36Sopenharmony_ci viafb_load_reg(reg_value, 40462306a36Sopenharmony_ci viafb_load_reg_num, reg, VIACR); 40562306a36Sopenharmony_ci break; 40662306a36Sopenharmony_ci case UNICHROME_K800: 40762306a36Sopenharmony_ci case UNICHROME_PM800: 40862306a36Sopenharmony_ci case UNICHROME_CN700: 40962306a36Sopenharmony_ci case UNICHROME_CX700: 41062306a36Sopenharmony_ci case UNICHROME_K8M890: 41162306a36Sopenharmony_ci case UNICHROME_P4M890: 41262306a36Sopenharmony_ci case UNICHROME_P4M900: 41362306a36Sopenharmony_ci case UNICHROME_CN750: 41462306a36Sopenharmony_ci case UNICHROME_VX800: 41562306a36Sopenharmony_ci case UNICHROME_VX855: 41662306a36Sopenharmony_ci case UNICHROME_VX900: 41762306a36Sopenharmony_ci reg_value = 41862306a36Sopenharmony_ci K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); 41962306a36Sopenharmony_ci /* Vertical scaling enabled */ 42062306a36Sopenharmony_ci viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3); 42162306a36Sopenharmony_ci viafb_load_reg_num = 42262306a36Sopenharmony_ci lcd_scaling_factor.lcd_ver_scaling_factor.reg_num; 42362306a36Sopenharmony_ci reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg; 42462306a36Sopenharmony_ci viafb_load_reg(reg_value, 42562306a36Sopenharmony_ci viafb_load_reg_num, reg, VIACR); 42662306a36Sopenharmony_ci break; 42762306a36Sopenharmony_ci } 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value); 43062306a36Sopenharmony_ci } else { 43162306a36Sopenharmony_ci /* Vertical scaling disabled */ 43262306a36Sopenharmony_ci viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3); 43362306a36Sopenharmony_ci } 43462306a36Sopenharmony_ci} 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_cistatic void via_pitch_alignment_patch_lcd(int iga_path, int hres, int bpp) 43762306a36Sopenharmony_ci{ 43862306a36Sopenharmony_ci unsigned char cr13, cr35, cr65, cr66, cr67; 43962306a36Sopenharmony_ci unsigned long dwScreenPitch = 0; 44062306a36Sopenharmony_ci unsigned long dwPitch; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci dwPitch = hres * (bpp >> 3); 44362306a36Sopenharmony_ci if (dwPitch & 0x1F) { 44462306a36Sopenharmony_ci dwScreenPitch = ((dwPitch + 31) & ~31) >> 3; 44562306a36Sopenharmony_ci if (iga_path == IGA2) { 44662306a36Sopenharmony_ci if (bpp > 8) { 44762306a36Sopenharmony_ci cr66 = (unsigned char)(dwScreenPitch & 0xFF); 44862306a36Sopenharmony_ci viafb_write_reg(CR66, VIACR, cr66); 44962306a36Sopenharmony_ci cr67 = viafb_read_reg(VIACR, CR67) & 0xFC; 45062306a36Sopenharmony_ci cr67 |= 45162306a36Sopenharmony_ci (unsigned 45262306a36Sopenharmony_ci char)((dwScreenPitch & 0x300) >> 8); 45362306a36Sopenharmony_ci viafb_write_reg(CR67, VIACR, cr67); 45462306a36Sopenharmony_ci } 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci /* Fetch Count */ 45762306a36Sopenharmony_ci cr67 = viafb_read_reg(VIACR, CR67) & 0xF3; 45862306a36Sopenharmony_ci cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7); 45962306a36Sopenharmony_ci viafb_write_reg(CR67, VIACR, cr67); 46062306a36Sopenharmony_ci cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF); 46162306a36Sopenharmony_ci cr65 += 2; 46262306a36Sopenharmony_ci viafb_write_reg(CR65, VIACR, cr65); 46362306a36Sopenharmony_ci } else { 46462306a36Sopenharmony_ci if (bpp > 8) { 46562306a36Sopenharmony_ci cr13 = (unsigned char)(dwScreenPitch & 0xFF); 46662306a36Sopenharmony_ci viafb_write_reg(CR13, VIACR, cr13); 46762306a36Sopenharmony_ci cr35 = viafb_read_reg(VIACR, CR35) & 0x1F; 46862306a36Sopenharmony_ci cr35 |= 46962306a36Sopenharmony_ci (unsigned 47062306a36Sopenharmony_ci char)((dwScreenPitch & 0x700) >> 3); 47162306a36Sopenharmony_ci viafb_write_reg(CR35, VIACR, cr35); 47262306a36Sopenharmony_ci } 47362306a36Sopenharmony_ci } 47462306a36Sopenharmony_ci } 47562306a36Sopenharmony_ci} 47662306a36Sopenharmony_cistatic void lcd_patch_skew_dvp0(struct lvds_setting_information 47762306a36Sopenharmony_ci *plvds_setting_info, 47862306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 47962306a36Sopenharmony_ci{ 48062306a36Sopenharmony_ci if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) { 48162306a36Sopenharmony_ci switch (viaparinfo->chip_info->gfx_chip_name) { 48262306a36Sopenharmony_ci case UNICHROME_P4M900: 48362306a36Sopenharmony_ci viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info, 48462306a36Sopenharmony_ci plvds_chip_info); 48562306a36Sopenharmony_ci break; 48662306a36Sopenharmony_ci case UNICHROME_P4M890: 48762306a36Sopenharmony_ci viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info, 48862306a36Sopenharmony_ci plvds_chip_info); 48962306a36Sopenharmony_ci break; 49062306a36Sopenharmony_ci } 49162306a36Sopenharmony_ci } 49262306a36Sopenharmony_ci} 49362306a36Sopenharmony_cistatic void lcd_patch_skew_dvp1(struct lvds_setting_information 49462306a36Sopenharmony_ci *plvds_setting_info, 49562306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 49662306a36Sopenharmony_ci{ 49762306a36Sopenharmony_ci if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) { 49862306a36Sopenharmony_ci switch (viaparinfo->chip_info->gfx_chip_name) { 49962306a36Sopenharmony_ci case UNICHROME_CX700: 50062306a36Sopenharmony_ci viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info, 50162306a36Sopenharmony_ci plvds_chip_info); 50262306a36Sopenharmony_ci break; 50362306a36Sopenharmony_ci } 50462306a36Sopenharmony_ci } 50562306a36Sopenharmony_ci} 50662306a36Sopenharmony_cistatic void lcd_patch_skew(struct lvds_setting_information 50762306a36Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) 50862306a36Sopenharmony_ci{ 50962306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "lcd_patch_skew\n"); 51062306a36Sopenharmony_ci switch (plvds_chip_info->output_interface) { 51162306a36Sopenharmony_ci case INTERFACE_DVP0: 51262306a36Sopenharmony_ci lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info); 51362306a36Sopenharmony_ci break; 51462306a36Sopenharmony_ci case INTERFACE_DVP1: 51562306a36Sopenharmony_ci lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info); 51662306a36Sopenharmony_ci break; 51762306a36Sopenharmony_ci case INTERFACE_DFP_LOW: 51862306a36Sopenharmony_ci if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) { 51962306a36Sopenharmony_ci viafb_write_reg_mask(CR99, VIACR, 0x08, 52062306a36Sopenharmony_ci BIT0 + BIT1 + BIT2 + BIT3); 52162306a36Sopenharmony_ci } 52262306a36Sopenharmony_ci break; 52362306a36Sopenharmony_ci } 52462306a36Sopenharmony_ci} 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci/* LCD Set Mode */ 52762306a36Sopenharmony_civoid viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres, 52862306a36Sopenharmony_ci u16 cyres, struct lvds_setting_information *plvds_setting_info, 52962306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci int set_iga = plvds_setting_info->iga_path; 53262306a36Sopenharmony_ci int mode_bpp = var->bits_per_pixel; 53362306a36Sopenharmony_ci int set_hres = cxres ? cxres : var->xres; 53462306a36Sopenharmony_ci int set_vres = cyres ? cyres : var->yres; 53562306a36Sopenharmony_ci int panel_hres = plvds_setting_info->lcd_panel_hres; 53662306a36Sopenharmony_ci int panel_vres = plvds_setting_info->lcd_panel_vres; 53762306a36Sopenharmony_ci u32 clock; 53862306a36Sopenharmony_ci struct via_display_timing timing; 53962306a36Sopenharmony_ci struct fb_var_screeninfo panel_var; 54062306a36Sopenharmony_ci const struct fb_videomode *panel_crt_table; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n"); 54362306a36Sopenharmony_ci /* Get panel table Pointer */ 54462306a36Sopenharmony_ci panel_crt_table = viafb_get_best_mode(panel_hres, panel_vres, 60); 54562306a36Sopenharmony_ci viafb_fill_var_timing_info(&panel_var, panel_crt_table); 54662306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "below viafb_lcd_set_mode!!\n"); 54762306a36Sopenharmony_ci if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) 54862306a36Sopenharmony_ci viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info); 54962306a36Sopenharmony_ci clock = PICOS2KHZ(panel_crt_table->pixclock) * 1000; 55062306a36Sopenharmony_ci plvds_setting_info->vclk = clock; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci if (set_iga == IGA2 && (set_hres < panel_hres || set_vres < panel_vres) 55362306a36Sopenharmony_ci && plvds_setting_info->display_method == LCD_EXPANDSION) { 55462306a36Sopenharmony_ci timing = var_to_timing(&panel_var, panel_hres, panel_vres); 55562306a36Sopenharmony_ci load_lcd_scaling(set_hres, set_vres, panel_hres, panel_vres); 55662306a36Sopenharmony_ci } else { 55762306a36Sopenharmony_ci timing = var_to_timing(&panel_var, set_hres, set_vres); 55862306a36Sopenharmony_ci if (set_iga == IGA2) 55962306a36Sopenharmony_ci /* disable scaling */ 56062306a36Sopenharmony_ci via_write_reg_mask(VIACR, 0x79, 0x00, 56162306a36Sopenharmony_ci BIT0 + BIT1 + BIT2); 56262306a36Sopenharmony_ci } 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci if (set_iga == IGA1) 56562306a36Sopenharmony_ci via_set_primary_timing(&timing); 56662306a36Sopenharmony_ci else if (set_iga == IGA2) 56762306a36Sopenharmony_ci via_set_secondary_timing(&timing); 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci /* Fetch count for IGA2 only */ 57062306a36Sopenharmony_ci viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) 57362306a36Sopenharmony_ci && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) 57462306a36Sopenharmony_ci viafb_load_FIFO_reg(set_iga, set_hres, set_vres); 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci fill_lcd_format(); 57762306a36Sopenharmony_ci viafb_set_vclock(clock, set_iga); 57862306a36Sopenharmony_ci lcd_patch_skew(plvds_setting_info, plvds_chip_info); 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci /* If K8M800, enable LCD Prefetch Mode. */ 58162306a36Sopenharmony_ci if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) 58262306a36Sopenharmony_ci || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)) 58362306a36Sopenharmony_ci viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci /* Patch for non 32bit alignment mode */ 58662306a36Sopenharmony_ci via_pitch_alignment_patch_lcd(plvds_setting_info->iga_path, set_hres, 58762306a36Sopenharmony_ci var->bits_per_pixel); 58862306a36Sopenharmony_ci} 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_cistatic void integrated_lvds_disable(struct lvds_setting_information 59162306a36Sopenharmony_ci *plvds_setting_info, 59262306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 59362306a36Sopenharmony_ci{ 59462306a36Sopenharmony_ci bool turn_off_first_powersequence = false; 59562306a36Sopenharmony_ci bool turn_off_second_powersequence = false; 59662306a36Sopenharmony_ci if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface) 59762306a36Sopenharmony_ci turn_off_first_powersequence = true; 59862306a36Sopenharmony_ci if (INTERFACE_LVDS0 == plvds_chip_info->output_interface) 59962306a36Sopenharmony_ci turn_off_first_powersequence = true; 60062306a36Sopenharmony_ci if (INTERFACE_LVDS1 == plvds_chip_info->output_interface) 60162306a36Sopenharmony_ci turn_off_second_powersequence = true; 60262306a36Sopenharmony_ci if (turn_off_second_powersequence) { 60362306a36Sopenharmony_ci /* Use second power sequence control: */ 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci /* Turn off power sequence. */ 60662306a36Sopenharmony_ci viafb_write_reg_mask(CRD4, VIACR, 0, BIT1); 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci /* Turn off back light. */ 60962306a36Sopenharmony_ci viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7); 61062306a36Sopenharmony_ci } 61162306a36Sopenharmony_ci if (turn_off_first_powersequence) { 61262306a36Sopenharmony_ci /* Use first power sequence control: */ 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci /* Turn off power sequence. */ 61562306a36Sopenharmony_ci viafb_write_reg_mask(CR6A, VIACR, 0, BIT3); 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci /* Turn off back light. */ 61862306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7); 61962306a36Sopenharmony_ci } 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci /* Power off LVDS channel. */ 62262306a36Sopenharmony_ci switch (plvds_chip_info->output_interface) { 62362306a36Sopenharmony_ci case INTERFACE_LVDS0: 62462306a36Sopenharmony_ci { 62562306a36Sopenharmony_ci viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7); 62662306a36Sopenharmony_ci break; 62762306a36Sopenharmony_ci } 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci case INTERFACE_LVDS1: 63062306a36Sopenharmony_ci { 63162306a36Sopenharmony_ci viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6); 63262306a36Sopenharmony_ci break; 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci case INTERFACE_LVDS0LVDS1: 63662306a36Sopenharmony_ci { 63762306a36Sopenharmony_ci viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7); 63862306a36Sopenharmony_ci break; 63962306a36Sopenharmony_ci } 64062306a36Sopenharmony_ci } 64162306a36Sopenharmony_ci} 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_cistatic void integrated_lvds_enable(struct lvds_setting_information 64462306a36Sopenharmony_ci *plvds_setting_info, 64562306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 64662306a36Sopenharmony_ci{ 64762306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n", 64862306a36Sopenharmony_ci plvds_chip_info->output_interface); 64962306a36Sopenharmony_ci if (plvds_setting_info->lcd_mode == LCD_SPWG) 65062306a36Sopenharmony_ci viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1); 65162306a36Sopenharmony_ci else 65262306a36Sopenharmony_ci viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1); 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci switch (plvds_chip_info->output_interface) { 65562306a36Sopenharmony_ci case INTERFACE_LVDS0LVDS1: 65662306a36Sopenharmony_ci case INTERFACE_LVDS0: 65762306a36Sopenharmony_ci /* Use first power sequence control: */ 65862306a36Sopenharmony_ci /* Use hardware control power sequence. */ 65962306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, 0, BIT0); 66062306a36Sopenharmony_ci /* Turn on back light. */ 66162306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7); 66262306a36Sopenharmony_ci /* Turn on hardware power sequence. */ 66362306a36Sopenharmony_ci viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); 66462306a36Sopenharmony_ci break; 66562306a36Sopenharmony_ci case INTERFACE_LVDS1: 66662306a36Sopenharmony_ci /* Use second power sequence control: */ 66762306a36Sopenharmony_ci /* Use hardware control power sequence. */ 66862306a36Sopenharmony_ci viafb_write_reg_mask(CRD3, VIACR, 0, BIT0); 66962306a36Sopenharmony_ci /* Turn on back light. */ 67062306a36Sopenharmony_ci viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7); 67162306a36Sopenharmony_ci /* Turn on hardware power sequence. */ 67262306a36Sopenharmony_ci viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1); 67362306a36Sopenharmony_ci break; 67462306a36Sopenharmony_ci } 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci /* Power on LVDS channel. */ 67762306a36Sopenharmony_ci switch (plvds_chip_info->output_interface) { 67862306a36Sopenharmony_ci case INTERFACE_LVDS0: 67962306a36Sopenharmony_ci { 68062306a36Sopenharmony_ci viafb_write_reg_mask(CRD2, VIACR, 0, BIT7); 68162306a36Sopenharmony_ci break; 68262306a36Sopenharmony_ci } 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci case INTERFACE_LVDS1: 68562306a36Sopenharmony_ci { 68662306a36Sopenharmony_ci viafb_write_reg_mask(CRD2, VIACR, 0, BIT6); 68762306a36Sopenharmony_ci break; 68862306a36Sopenharmony_ci } 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci case INTERFACE_LVDS0LVDS1: 69162306a36Sopenharmony_ci { 69262306a36Sopenharmony_ci viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7); 69362306a36Sopenharmony_ci break; 69462306a36Sopenharmony_ci } 69562306a36Sopenharmony_ci } 69662306a36Sopenharmony_ci} 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_civoid viafb_lcd_disable(void) 69962306a36Sopenharmony_ci{ 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 70262306a36Sopenharmony_ci lcd_powersequence_off(); 70362306a36Sopenharmony_ci /* DI1 pad off */ 70462306a36Sopenharmony_ci viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30); 70562306a36Sopenharmony_ci } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { 70662306a36Sopenharmony_ci if (viafb_LCD2_ON 70762306a36Sopenharmony_ci && (INTEGRATED_LVDS == 70862306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name)) 70962306a36Sopenharmony_ci integrated_lvds_disable(viaparinfo->lvds_setting_info, 71062306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info2); 71162306a36Sopenharmony_ci if (INTEGRATED_LVDS == 71262306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) 71362306a36Sopenharmony_ci integrated_lvds_disable(viaparinfo->lvds_setting_info, 71462306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info); 71562306a36Sopenharmony_ci if (VT1636_LVDS == viaparinfo->chip_info-> 71662306a36Sopenharmony_ci lvds_chip_info.lvds_chip_name) 71762306a36Sopenharmony_ci viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, 71862306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info); 71962306a36Sopenharmony_ci } else if (VT1636_LVDS == 72062306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 72162306a36Sopenharmony_ci viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, 72262306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info); 72362306a36Sopenharmony_ci } else { 72462306a36Sopenharmony_ci /* Backlight off */ 72562306a36Sopenharmony_ci viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20); 72662306a36Sopenharmony_ci /* 24 bit DI data paht off */ 72762306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80); 72862306a36Sopenharmony_ci } 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci /* Disable expansion bit */ 73162306a36Sopenharmony_ci viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01); 73262306a36Sopenharmony_ci /* Simultaneout disabled */ 73362306a36Sopenharmony_ci viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); 73462306a36Sopenharmony_ci} 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_cistatic void set_lcd_output_path(int set_iga, int output_interface) 73762306a36Sopenharmony_ci{ 73862306a36Sopenharmony_ci switch (output_interface) { 73962306a36Sopenharmony_ci case INTERFACE_DFP: 74062306a36Sopenharmony_ci if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name) 74162306a36Sopenharmony_ci || (UNICHROME_P4M890 == 74262306a36Sopenharmony_ci viaparinfo->chip_info->gfx_chip_name)) 74362306a36Sopenharmony_ci viafb_write_reg_mask(CR97, VIACR, 0x84, 74462306a36Sopenharmony_ci BIT7 + BIT2 + BIT1 + BIT0); 74562306a36Sopenharmony_ci fallthrough; 74662306a36Sopenharmony_ci case INTERFACE_DVP0: 74762306a36Sopenharmony_ci case INTERFACE_DVP1: 74862306a36Sopenharmony_ci case INTERFACE_DFP_HIGH: 74962306a36Sopenharmony_ci case INTERFACE_DFP_LOW: 75062306a36Sopenharmony_ci if (set_iga == IGA2) 75162306a36Sopenharmony_ci viafb_write_reg(CR91, VIACR, 0x00); 75262306a36Sopenharmony_ci break; 75362306a36Sopenharmony_ci } 75462306a36Sopenharmony_ci} 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_civoid viafb_lcd_enable(void) 75762306a36Sopenharmony_ci{ 75862306a36Sopenharmony_ci viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); 75962306a36Sopenharmony_ci viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); 76062306a36Sopenharmony_ci set_lcd_output_path(viaparinfo->lvds_setting_info->iga_path, 76162306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.output_interface); 76262306a36Sopenharmony_ci if (viafb_LCD2_ON) 76362306a36Sopenharmony_ci set_lcd_output_path(viaparinfo->lvds_setting_info2->iga_path, 76462306a36Sopenharmony_ci viaparinfo->chip_info-> 76562306a36Sopenharmony_ci lvds_chip_info2.output_interface); 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 76862306a36Sopenharmony_ci /* DI1 pad on */ 76962306a36Sopenharmony_ci viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); 77062306a36Sopenharmony_ci lcd_powersequence_on(); 77162306a36Sopenharmony_ci } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) { 77262306a36Sopenharmony_ci if (viafb_LCD2_ON && (INTEGRATED_LVDS == 77362306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name)) 77462306a36Sopenharmony_ci integrated_lvds_enable(viaparinfo->lvds_setting_info2, \ 77562306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info2); 77662306a36Sopenharmony_ci if (INTEGRATED_LVDS == 77762306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) 77862306a36Sopenharmony_ci integrated_lvds_enable(viaparinfo->lvds_setting_info, 77962306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info); 78062306a36Sopenharmony_ci if (VT1636_LVDS == viaparinfo->chip_info-> 78162306a36Sopenharmony_ci lvds_chip_info.lvds_chip_name) 78262306a36Sopenharmony_ci viafb_enable_lvds_vt1636(viaparinfo-> 78362306a36Sopenharmony_ci lvds_setting_info, &viaparinfo->chip_info-> 78462306a36Sopenharmony_ci lvds_chip_info); 78562306a36Sopenharmony_ci } else if (VT1636_LVDS == 78662306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 78762306a36Sopenharmony_ci viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info, 78862306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info); 78962306a36Sopenharmony_ci } else { 79062306a36Sopenharmony_ci /* Backlight on */ 79162306a36Sopenharmony_ci viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20); 79262306a36Sopenharmony_ci /* 24 bit DI data paht on */ 79362306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80); 79462306a36Sopenharmony_ci /* LCD enabled */ 79562306a36Sopenharmony_ci viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48); 79662306a36Sopenharmony_ci } 79762306a36Sopenharmony_ci} 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_cistatic void lcd_powersequence_off(void) 80062306a36Sopenharmony_ci{ 80162306a36Sopenharmony_ci int i, mask, data; 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci /* Software control power sequence */ 80462306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11); 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 80762306a36Sopenharmony_ci mask = PowerSequenceOff[0][i]; 80862306a36Sopenharmony_ci data = PowerSequenceOff[1][i] & mask; 80962306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask); 81062306a36Sopenharmony_ci udelay(PowerSequenceOff[2][i]); 81162306a36Sopenharmony_ci } 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci /* Disable LCD */ 81462306a36Sopenharmony_ci viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08); 81562306a36Sopenharmony_ci} 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_cistatic void lcd_powersequence_on(void) 81862306a36Sopenharmony_ci{ 81962306a36Sopenharmony_ci int i, mask, data; 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci /* Software control power sequence */ 82262306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11); 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_ci /* Enable LCD */ 82562306a36Sopenharmony_ci viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08); 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 82862306a36Sopenharmony_ci mask = PowerSequenceOn[0][i]; 82962306a36Sopenharmony_ci data = PowerSequenceOn[1][i] & mask; 83062306a36Sopenharmony_ci viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask); 83162306a36Sopenharmony_ci udelay(PowerSequenceOn[2][i]); 83262306a36Sopenharmony_ci } 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci udelay(1); 83562306a36Sopenharmony_ci} 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_cistatic void fill_lcd_format(void) 83862306a36Sopenharmony_ci{ 83962306a36Sopenharmony_ci u8 bdithering = 0, bdual = 0; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci if (viaparinfo->lvds_setting_info->device_lcd_dualedge) 84262306a36Sopenharmony_ci bdual = BIT4; 84362306a36Sopenharmony_ci if (viaparinfo->lvds_setting_info->LCDDithering) 84462306a36Sopenharmony_ci bdithering = BIT0; 84562306a36Sopenharmony_ci /* Dual & Dithering */ 84662306a36Sopenharmony_ci viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0); 84762306a36Sopenharmony_ci} 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_cistatic void check_diport_of_integrated_lvds( 85062306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info, 85162306a36Sopenharmony_ci struct lvds_setting_information 85262306a36Sopenharmony_ci *plvds_setting_info) 85362306a36Sopenharmony_ci{ 85462306a36Sopenharmony_ci /* Determine LCD DI Port by hardware layout. */ 85562306a36Sopenharmony_ci switch (viafb_display_hardware_layout) { 85662306a36Sopenharmony_ci case HW_LAYOUT_LCD_ONLY: 85762306a36Sopenharmony_ci { 85862306a36Sopenharmony_ci if (plvds_setting_info->device_lcd_dualedge) { 85962306a36Sopenharmony_ci plvds_chip_info->output_interface = 86062306a36Sopenharmony_ci INTERFACE_LVDS0LVDS1; 86162306a36Sopenharmony_ci } else { 86262306a36Sopenharmony_ci plvds_chip_info->output_interface = 86362306a36Sopenharmony_ci INTERFACE_LVDS0; 86462306a36Sopenharmony_ci } 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci break; 86762306a36Sopenharmony_ci } 86862306a36Sopenharmony_ci 86962306a36Sopenharmony_ci case HW_LAYOUT_DVI_ONLY: 87062306a36Sopenharmony_ci { 87162306a36Sopenharmony_ci plvds_chip_info->output_interface = INTERFACE_NONE; 87262306a36Sopenharmony_ci break; 87362306a36Sopenharmony_ci } 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci case HW_LAYOUT_LCD1_LCD2: 87662306a36Sopenharmony_ci case HW_LAYOUT_LCD_EXTERNAL_LCD2: 87762306a36Sopenharmony_ci { 87862306a36Sopenharmony_ci plvds_chip_info->output_interface = 87962306a36Sopenharmony_ci INTERFACE_LVDS0LVDS1; 88062306a36Sopenharmony_ci break; 88162306a36Sopenharmony_ci } 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci case HW_LAYOUT_LCD_DVI: 88462306a36Sopenharmony_ci { 88562306a36Sopenharmony_ci plvds_chip_info->output_interface = INTERFACE_LVDS1; 88662306a36Sopenharmony_ci break; 88762306a36Sopenharmony_ci } 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_ci default: 89062306a36Sopenharmony_ci { 89162306a36Sopenharmony_ci plvds_chip_info->output_interface = INTERFACE_LVDS1; 89262306a36Sopenharmony_ci break; 89362306a36Sopenharmony_ci } 89462306a36Sopenharmony_ci } 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO 89762306a36Sopenharmony_ci "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n", 89862306a36Sopenharmony_ci viafb_display_hardware_layout, 89962306a36Sopenharmony_ci plvds_chip_info->output_interface); 90062306a36Sopenharmony_ci} 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_civoid viafb_init_lvds_output_interface(struct lvds_chip_information 90362306a36Sopenharmony_ci *plvds_chip_info, 90462306a36Sopenharmony_ci struct lvds_setting_information 90562306a36Sopenharmony_ci *plvds_setting_info) 90662306a36Sopenharmony_ci{ 90762306a36Sopenharmony_ci if (INTERFACE_NONE != plvds_chip_info->output_interface) { 90862306a36Sopenharmony_ci /*Do nothing, lcd port is specified by module parameter */ 90962306a36Sopenharmony_ci return; 91062306a36Sopenharmony_ci } 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci switch (plvds_chip_info->lvds_chip_name) { 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci case VT1636_LVDS: 91562306a36Sopenharmony_ci switch (viaparinfo->chip_info->gfx_chip_name) { 91662306a36Sopenharmony_ci case UNICHROME_CX700: 91762306a36Sopenharmony_ci plvds_chip_info->output_interface = INTERFACE_DVP1; 91862306a36Sopenharmony_ci break; 91962306a36Sopenharmony_ci case UNICHROME_CN700: 92062306a36Sopenharmony_ci plvds_chip_info->output_interface = INTERFACE_DFP_LOW; 92162306a36Sopenharmony_ci break; 92262306a36Sopenharmony_ci default: 92362306a36Sopenharmony_ci plvds_chip_info->output_interface = INTERFACE_DVP0; 92462306a36Sopenharmony_ci break; 92562306a36Sopenharmony_ci } 92662306a36Sopenharmony_ci break; 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci case INTEGRATED_LVDS: 92962306a36Sopenharmony_ci check_diport_of_integrated_lvds(plvds_chip_info, 93062306a36Sopenharmony_ci plvds_setting_info); 93162306a36Sopenharmony_ci break; 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci default: 93462306a36Sopenharmony_ci switch (viaparinfo->chip_info->gfx_chip_name) { 93562306a36Sopenharmony_ci case UNICHROME_K8M890: 93662306a36Sopenharmony_ci case UNICHROME_P4M900: 93762306a36Sopenharmony_ci case UNICHROME_P4M890: 93862306a36Sopenharmony_ci plvds_chip_info->output_interface = INTERFACE_DFP_LOW; 93962306a36Sopenharmony_ci break; 94062306a36Sopenharmony_ci default: 94162306a36Sopenharmony_ci plvds_chip_info->output_interface = INTERFACE_DFP; 94262306a36Sopenharmony_ci break; 94362306a36Sopenharmony_ci } 94462306a36Sopenharmony_ci break; 94562306a36Sopenharmony_ci } 94662306a36Sopenharmony_ci} 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_cibool viafb_lcd_get_mobile_state(bool *mobile) 94962306a36Sopenharmony_ci{ 95062306a36Sopenharmony_ci unsigned char __iomem *romptr, *tableptr, *biosptr; 95162306a36Sopenharmony_ci u8 core_base; 95262306a36Sopenharmony_ci /* Rom address */ 95362306a36Sopenharmony_ci const u32 romaddr = 0x000C0000; 95462306a36Sopenharmony_ci u16 start_pattern; 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci biosptr = ioremap(romaddr, 0x10000); 95762306a36Sopenharmony_ci start_pattern = readw(biosptr); 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci /* Compare pattern */ 96062306a36Sopenharmony_ci if (start_pattern == 0xAA55) { 96162306a36Sopenharmony_ci /* Get the start of Table */ 96262306a36Sopenharmony_ci /* 0x1B means BIOS offset position */ 96362306a36Sopenharmony_ci romptr = biosptr + 0x1B; 96462306a36Sopenharmony_ci tableptr = biosptr + readw(romptr); 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_ci /* Get the start of biosver structure */ 96762306a36Sopenharmony_ci /* 18 means BIOS version position. */ 96862306a36Sopenharmony_ci romptr = tableptr + 18; 96962306a36Sopenharmony_ci romptr = biosptr + readw(romptr); 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci /* The offset should be 44, but the 97262306a36Sopenharmony_ci actual image is less three char. */ 97362306a36Sopenharmony_ci /* pRom += 44; */ 97462306a36Sopenharmony_ci romptr += 41; 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci core_base = readb(romptr); 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci if (core_base & 0x8) 97962306a36Sopenharmony_ci *mobile = false; 98062306a36Sopenharmony_ci else 98162306a36Sopenharmony_ci *mobile = true; 98262306a36Sopenharmony_ci /* release memory */ 98362306a36Sopenharmony_ci iounmap(biosptr); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci return true; 98662306a36Sopenharmony_ci } else { 98762306a36Sopenharmony_ci iounmap(biosptr); 98862306a36Sopenharmony_ci return false; 98962306a36Sopenharmony_ci } 99062306a36Sopenharmony_ci} 991