viafb: add initial VX900 support
[pandora-kernel.git] / drivers / video / via / lcd.c
index 2ab0f15..3425c39 100644 (file)
 #include <linux/via-core.h>
 #include <linux/via_i2c.h>
 #include "global.h"
-#include "lcdtbl.h"
 
 #define viafb_compact_res(x, y) (((x)<<16)|(y))
 
+/* CLE266 Software Power Sequence */
+/* {Mask}, {Data}, {Delay} */
+int PowerSequenceOn[3][3] = { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06},
+       {0x19, 0x1FE, 0x01} };
+int PowerSequenceOff[3][3] = { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00},
+       {0xD2, 0x19, 0x01} };
+
 static struct _lcd_scaling_factor lcd_scaling_factor = {
        /* LCD Horizontal Scaling Factor Register */
        {LCD_HOR_SCALING_FACTOR_REG_NUM,
@@ -42,7 +48,7 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
 
 static int check_lvds_chip(int device_id_subaddr, int device_id);
 static bool lvds_identify_integratedlvds(void);
-static void fp_id_to_vindex(int panel_id);
+static void __devinit fp_id_to_vindex(int panel_id);
 static int lvds_register_read(int index);
 static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
                      int panel_vres);
@@ -75,8 +81,6 @@ static void check_diport_of_integrated_lvds(
 static struct display_timing lcd_centering_timging(struct display_timing
                                            mode_crt_reg,
                                           struct display_timing panel_crt_reg);
-static void viafb_load_scaling_factor_for_p4m900(int set_hres,
-       int set_vres, int panel_hres, int panel_vres);
 
 static int check_lvds_chip(int device_id_subaddr, int device_id)
 {
@@ -86,36 +90,11 @@ static int check_lvds_chip(int device_id_subaddr, int device_id)
                return FAIL;
 }
 
-void viafb_init_lcd_size(void)
+void __devinit viafb_init_lcd_size(void)
 {
        DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
-       DEBUG_MSG(KERN_INFO
-               "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
-               viaparinfo->lvds_setting_info->get_lcd_size_method);
 
-       switch (viaparinfo->lvds_setting_info->get_lcd_size_method) {
-       case GET_LCD_SIZE_BY_SYSTEM_BIOS:
-               break;
-       case GET_LCD_SZIE_BY_HW_STRAPPING:
-               break;
-       case GET_LCD_SIZE_BY_VGA_BIOS:
-               DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
-               fp_id_to_vindex(viafb_lcd_panel_id);
-               DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
-                         viaparinfo->lvds_setting_info->lcd_panel_id);
-               break;
-       case GET_LCD_SIZE_BY_USER_SETTING:
-               DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
-               fp_id_to_vindex(viafb_lcd_panel_id);
-               DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
-                         viaparinfo->lvds_setting_info->lcd_panel_id);
-               break;
-       default:
-               DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
-               viaparinfo->lvds_setting_info->lcd_panel_id =
-                       LCD_PANEL_ID1_800X600;
-               fp_id_to_vindex(LCD_PANEL_ID1_800X600);
-       }
+       fp_id_to_vindex(viafb_lcd_panel_id);
        viaparinfo->lvds_setting_info2->lcd_panel_id =
                viaparinfo->lvds_setting_info->lcd_panel_id;
        viaparinfo->lvds_setting_info2->lcd_panel_hres =
@@ -171,7 +150,7 @@ static bool lvds_identify_integratedlvds(void)
        return true;
 }
 
-int viafb_lvds_trasmitter_identify(void)
+int __devinit viafb_lvds_trasmitter_identify(void)
 {
        if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
                viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
@@ -212,7 +191,7 @@ int viafb_lvds_trasmitter_identify(void)
        return FAIL;
 }
 
-static void fp_id_to_vindex(int panel_id)
+static void __devinit fp_id_to_vindex(int panel_id)
 {
        DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
 
@@ -437,14 +416,9 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
 
        /* LCD Scaling Enable */
        viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
-       if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
-               viafb_load_scaling_factor_for_p4m900(set_hres, set_vres,
-                                              panel_hres, panel_vres);
-               return;
-       }
 
        /* Check if expansion for horizontal */
-       if (set_hres != panel_hres) {
+       if (set_hres < panel_hres) {
                /* Load Horizontal Scaling Factor */
                switch (viaparinfo->chip_info->gfx_chip_name) {
                case UNICHROME_CLE266:
@@ -464,6 +438,11 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
                case UNICHROME_CX700:
                case UNICHROME_K8M890:
                case UNICHROME_P4M890:
+               case UNICHROME_P4M900:
+               case UNICHROME_CN750:
+               case UNICHROME_VX800:
+               case UNICHROME_VX855:
+               case UNICHROME_VX900:
                        reg_value =
                            K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
                        /* Horizontal scaling enabled */
@@ -483,7 +462,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
        }
 
        /* Check if expansion for vertical */
-       if (set_vres != panel_vres) {
+       if (set_vres < panel_vres) {
                /* Load Vertical Scaling Factor */
                switch (viaparinfo->chip_info->gfx_chip_name) {
                case UNICHROME_CLE266:
@@ -503,6 +482,11 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
                case UNICHROME_CX700:
                case UNICHROME_K8M890:
                case UNICHROME_P4M890:
+               case UNICHROME_P4M900:
+               case UNICHROME_CN750:
+               case UNICHROME_VX800:
+               case UNICHROME_VX855:
+               case UNICHROME_VX900:
                        reg_value =
                            K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
                        /* Vertical scaling enabled */
@@ -648,9 +632,8 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
                                 (mode_crt_reg, panel_crt_reg), IGA1);
        } else {
                /* Expansion */
-               if ((plvds_setting_info->display_method ==
-                    LCD_EXPANDSION) & ((set_hres != panel_hres)
-                                       || (set_vres != panel_vres))) {
+               if (plvds_setting_info->display_method == LCD_EXPANDSION
+                       && (set_hres < panel_hres || set_vres < panel_vres)) {
                        /* expansion timing IGA2 loaded panel set timing*/
                        viafb_load_crtc_timing(panel_crt_reg, IGA2);
                        DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
@@ -680,9 +663,6 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
        pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk);
        DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
        viafb_set_vclock(pll_D_N, set_iga);
-
-       viafb_set_output_path(DEVICE_LCD, set_iga,
-               plvds_chip_info->output_interface);
        lcd_patch_skew(plvds_setting_info, plvds_chip_info);
 
        /* If K8M800, enable LCD Prefetch Mode. */
@@ -725,9 +705,6 @@ static void integrated_lvds_disable(struct lvds_setting_information
                viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
        }
 
-       /* Turn DFP High/Low Pad off. */
-       viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3);
-
        /* Power off LVDS channel. */
        switch (plvds_chip_info->output_interface) {
        case INTERFACE_LVDS0:
@@ -783,9 +760,6 @@ static void integrated_lvds_enable(struct lvds_setting_information
                break;
        }
 
-       /* Turn DFP High/Low pad on. */
-       viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3);
-
        /* Power on LVDS channel. */
        switch (plvds_chip_info->output_interface) {
        case INTERFACE_LVDS0:
@@ -834,29 +808,48 @@ void viafb_lcd_disable(void)
                viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
                                    &viaparinfo->chip_info->lvds_chip_info);
        } else {
-               /* DFP-HL pad off          */
-               viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F);
                /* Backlight off           */
                viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
                /* 24 bit DI data paht off */
                viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
-               /* Simultaneout disabled   */
-               viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
        }
 
        /* Disable expansion bit   */
        viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
-       /* CRT path set to IGA1    */
-       viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40);
        /* Simultaneout disabled   */
        viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
-       /* IGA2 path disabled      */
-       viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
+}
 
+static void set_lcd_output_path(int set_iga, int output_interface)
+{
+       switch (output_interface) {
+       case INTERFACE_DFP:
+               if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
+                   || (UNICHROME_P4M890 ==
+                   viaparinfo->chip_info->gfx_chip_name))
+                       viafb_write_reg_mask(CR97, VIACR, 0x84,
+                                      BIT7 + BIT2 + BIT1 + BIT0);
+       case INTERFACE_DVP0:
+       case INTERFACE_DVP1:
+       case INTERFACE_DFP_HIGH:
+       case INTERFACE_DFP_LOW:
+               if (set_iga == IGA2)
+                       viafb_write_reg(CR91, VIACR, 0x00);
+               break;
+       }
 }
 
 void viafb_lcd_enable(void)
 {
+       viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
+       viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+       set_lcd_output_path(viaparinfo->lvds_setting_info->iga_path,
+               viaparinfo->chip_info->lvds_chip_info.output_interface);
+       if (viafb_LCD2_ON)
+               set_lcd_output_path(viaparinfo->lvds_setting_info2->iga_path,
+                       viaparinfo->chip_info->
+                       lvds_chip_info2.output_interface);
+
        if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
                /* DI1 pad on */
                viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
@@ -880,39 +873,13 @@ void viafb_lcd_enable(void)
                viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
                                   &viaparinfo->chip_info->lvds_chip_info);
        } else {
-               /* DFP-HL pad on           */
-               viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F);
                /* Backlight on            */
                viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
                /* 24 bit DI data paht on  */
                viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
-
-               /* Set data source selection bit by iga path */
-               if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
-                       /* DFP-H set to IGA1       */
-                       viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10);
-                       /* DFP-L set to IGA1       */
-                       viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10);
-               } else {
-                       /* DFP-H set to IGA2       */
-                       viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10);
-                       /* DFP-L set to IGA2       */
-                       viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10);
-               }
                /* LCD enabled             */
                viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
        }
-
-       if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
-               /* CRT path set to IGA2    */
-               viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40);
-               /* IGA2 path disabled      */
-               viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
-               /* IGA2 path enabled       */
-       } else {                /* IGA2 */
-               viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80);
-       }
-
 }
 
 static void lcd_powersequence_off(void)
@@ -1018,7 +985,7 @@ static void check_diport_of_integrated_lvds(
                  plvds_chip_info->output_interface);
 }
 
-void viafb_init_lvds_output_interface(struct lvds_chip_information
+void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
                                *plvds_chip_info,
                                struct lvds_setting_information
                                *plvds_setting_info)
@@ -1139,69 +1106,3 @@ bool viafb_lcd_get_mobile_state(bool *mobile)
                return false;
        }
 }
-
-static void viafb_load_scaling_factor_for_p4m900(int set_hres,
-       int set_vres, int panel_hres, int panel_vres)
-{
-       int h_scaling_factor;
-       int v_scaling_factor;
-       u8 cra2 = 0;
-       u8 cr77 = 0;
-       u8 cr78 = 0;
-       u8 cr79 = 0;
-       u8 cr9f = 0;
-       /* Check if expansion for horizontal */
-       if (set_hres < panel_hres) {
-               /* Load Horizontal Scaling Factor */
-
-               /* For VIA_K8M800 or later chipsets. */
-               h_scaling_factor =
-                   K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
-               /* HSCaleFactor[1:0] at CR9F[1:0] */
-               cr9f = h_scaling_factor & 0x0003;
-               /* HSCaleFactor[9:2] at CR77[7:0] */
-               cr77 = (h_scaling_factor & 0x03FC) >> 2;
-               /* HSCaleFactor[11:10] at CR79[5:4] */
-               cr79 = (h_scaling_factor & 0x0C00) >> 10;
-               cr79 <<= 4;
-
-               /* Horizontal scaling enabled */
-               cra2 = 0xC0;
-
-               DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n",
-                         h_scaling_factor);
-       } else {
-               /* Horizontal scaling disabled */
-               cra2 = 0x00;
-       }
-
-       /* Check if expansion for vertical */
-       if (set_vres < panel_vres) {
-               /* Load Vertical Scaling Factor */
-
-               /* For VIA_K8M800 or later chipsets. */
-               v_scaling_factor =
-                   K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
-
-               /* Vertical scaling enabled */
-               cra2 |= 0x08;
-               /* VSCaleFactor[0] at CR79[3] */
-               cr79 |= ((v_scaling_factor & 0x0001) << 3);
-               /* VSCaleFactor[8:1] at CR78[7:0] */
-               cr78 |= (v_scaling_factor & 0x01FE) >> 1;
-               /* VSCaleFactor[10:9] at CR79[7:6] */
-               cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6;
-
-               DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n",
-                         v_scaling_factor);
-       } else {
-               /* Vertical scaling disabled */
-               cra2 |= 0x00;
-       }
-
-       viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7);
-       viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF);
-       viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF);
-       viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8);
-       viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1);
-}