[display-dv20]: turn off panel power rail only if no operation exists
authorGeng Xiujun <xiujun.geng@intel.com>
Fri, 27 Apr 2012 01:09:22 +0000 (09:09 +0800)
committerbuildbot <buildbot@intel.com>
Sat, 28 Apr 2012 22:52:26 +0000 (15:52 -0700)
BZ: 32593

The I2C bus of LVDS panel is shared with other devices, such as dsi-lvds bridge
and pn544, if we turn off panel power through GPIO, then it will pull voltage of
i2c down to 1v, and if there's other device's transition on this bus at this
time, then it will be unstable, and unrecoverable. experiments show that, if we
don't turn off LVDS panel power rail in early suspend, then I2C error will be
disappear.

The patch turn off panel's power rail only when there's no device active.

Change-Id: Iea6223370598fd648fe74a3269df3f4c2da6a430
Signed-off-by: Geng Xiujun <xiujun.geng@intel.com>
Reviewed-on: http://android.intel.com:8080/46539
Reviewed-by: Tong, BoX <box.tong@intel.com>
Tested-by: Tong, BoX <box.tong@intel.com>
Reviewed-by: Mansoor, Illyas <illyas.mansoor@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.c
drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h
drivers/staging/mrst/drv/psb_drv.c

index 6b79002..38626b5 100644 (file)
@@ -334,7 +334,6 @@ static int tc35876x_bridge_remove(struct i2c_client *client)
        return 0;
 }
 
-
 static const struct i2c_device_id tc35876x_bridge_id[] = {
        { "i2c_disp_brig", 0 },
        { }
@@ -540,9 +539,6 @@ void dsi_lvds_toshiba_bridge_panel_off(void)
        if (gpio_direction_output(GPIO_MIPI_LCD_BL_EN, 0))
                gpio_set_value_cansleep(GPIO_MIPI_LCD_BL_EN, 0);
        mdelay(1);
-
-       if (gpio_direction_output(GPIO_MIPI_LCD_VADD, 0))
-               gpio_set_value_cansleep(GPIO_MIPI_LCD_VADD, 0);
 }
 
 /* ************************************************************************* *\
@@ -556,10 +552,6 @@ void dsi_lvds_toshiba_bridge_panel_on(struct drm_device *dev)
 
        printk(KERN_INFO "[DISPLAY ] %s\n", __func__);
 
-       if (gpio_direction_output(GPIO_MIPI_LCD_VADD, 1))
-               gpio_set_value_cansleep(GPIO_MIPI_LCD_VADD, 1);
-       msleep(260);
-
        if (cmi_lcd_i2c_client) {
                int ret;
                PSB_DEBUG_ENTRY("setting TCON\n");
@@ -614,6 +606,27 @@ void dsi_lvds_toshiba_bridge_panel_on(struct drm_device *dev)
                        dev_priv->brightness_adjusted);
 }
 
+/*
+ * Turn off/on power of LVDS panel only if no device is active
+ */
+int tc35876x_lvds_panel_suspend_noirq(struct device *dev)
+{
+       if (gpio_direction_output(GPIO_MIPI_LCD_VADD, 0))
+               gpio_set_value_cansleep(GPIO_MIPI_LCD_VADD, 0);
+       mdelay(1);
+
+       return 0;
+}
+
+int tc35876x_lvds_panel_resume_noirq(struct device *dev)
+{
+       if (gpio_direction_output(GPIO_MIPI_LCD_VADD, 1))
+               gpio_set_value_cansleep(GPIO_MIPI_LCD_VADD, 1);
+       msleep(260);
+
+       return 0;
+}
+
 /* ************************************************************************* *\
  * FUNCTION: dsi_lvds_init_lvds_bridge
  *
index 9c18efa..ae50941 100644 (file)
@@ -68,5 +68,7 @@ void dsi_lvds_deinit_lvds_bridge(struct drm_device *dev);
 void dsi_lvds_bridge_get_display_params(struct drm_display_mode *mode);
 void dsi_lvds_resume_lvds_bridge(struct drm_device *dev);
 void dsi_lvds_suspend_lvds_bridge(struct drm_device *dev);
+int tc35876x_lvds_panel_resume_noirq(struct device *dev);
+int tc35876x_lvds_panel_suspend_noirq(struct device *dev);
 
 #endif /*__MDFLD_DSI_LVDS_BRIDGE_H__*/
index 43024ed..eb1eef8 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/cpu.h>
 #include <linux/notifier.h>
 #include <linux/spinlock.h>
+#include "mdfld_dsi_lvds_bridge.h"
 #ifdef CONFIG_GFX_RTPM
 #include <linux/pm_runtime.h>
 #endif
@@ -3870,6 +3871,10 @@ static const struct dev_pm_ops psb_pm_ops = {
        .runtime_idle = psb_runtime_idle,
        .suspend = psb_runtime_suspend,
        .resume = psb_runtime_resume,
+#ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
+       .suspend_noirq = tc35876x_lvds_panel_suspend_noirq,
+       .resume_noirq = tc35876x_lvds_panel_resume_noirq,
+#endif
 };
 
 static struct drm_driver driver = {