display: [REVERTME] add access count for AVDD gpio pin for DV20
authorGeng Xiujun <xiujun.geng@intel.com>
Fri, 4 May 2012 07:54:59 +0000 (15:54 +0800)
committerbuildbot <buildbot@intel.com>
Wed, 9 May 2012 02:30:50 +0000 (19:30 -0700)
BZ: 32593

[WORKAROUND]: 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.

This workaround uses access count to control VADD gpio pin. when one device
uses i2c device, increase the count, after that decrease it. and if LVDS panel
is powered on, increase it, once powered off, decrease it. if the count reaches 0,
pull down the gpio pin, otherwise pull it high. Thus it can make sure when
there's transition on the i2c bus, VADD keeps on.

Change-Id: Ide625a1ee3de544ba9ee0a71d005b22d20af4307
Signed-off-by: Geng Xiujun <xiujun.geng@intel.com>
Reviewed-on: http://android.intel.com:8080/47423
Reviewed-by: Xu, Randy <randy.xu@intel.com>
Reviewed-by: Ai, Ke <ke.ai@intel.com>
Reviewed-by: Zhang, Lei <lei.zhang@intel.com>
Reviewed-by: Yang, Bin <bin.yang@intel.com>
Reviewed-by: Hogander, Jouni <jouni.hogander@intel.com>
Tested-by: Tong, BoX <box.tong@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/pci/pci.h
drivers/pci/quirks.c
drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.c
drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h
drivers/staging/mrst/drv/psb_powermgmt.c
drivers/staging/mrst/drv/psb_powermgmt.h

index 3a39bf1..2de78d3 100644 (file)
@@ -314,4 +314,9 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 }
 #endif
 
+#ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
+extern void vlcm_vadd_get(void);
+extern void vlcm_vadd_put(void);
+#endif
+
 #endif /* DRIVERS_PCI_H */
index 45ea3b8..c30224e 100644 (file)
@@ -1425,6 +1425,24 @@ DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ICH6_1,     asus_
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6_resume);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6_resume_early);
 
+#if CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
+static void tc35876x_lvds_panel_fixup_suspend(struct pci_dev *dev)
+{
+       vlcm_vadd_put();
+}
+DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_INTEL,
+               0x082E,
+               tc35876x_lvds_panel_fixup_suspend);
+
+static void tc35876x_lvds_panel_fixup_resume(struct pci_dev *dev)
+{
+       vlcm_vadd_get();
+}
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,
+               0x082E,
+               tc35876x_lvds_panel_fixup_resume);
+#endif
+
 /*
  * SiS 96x south bridge: BIOS typically hides SMBus device...
  */
index 6b79002..121795b 100644 (file)
 #include "mdfld_dsi_lvds_bridge.h"
 #include "psb_drv.h"
 #include <asm/intel_scu_ipc.h>
+#include "psb_powermgmt.h"
 
 #define CONFIG_LVDS_HARD_RESET
 #ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
 
-/*GPIO Pins */
-#define GPIO_MIPI_BRIDGE_RESET 115
-
-#define GPIO_MIPI_LCD_BL_EN    112  /* DV1.0 GP_CORE_016 (+96 = GPIO number), 6S6P_BL_EN */
-#define GPIO_MIPI_LCD_VADD     110
 /* All these pins removed on DV1.0 */
 #define GPIO_MIPI_LCD_BIAS_EN  -1
 #define GPIO_MIPI_PANEL_RESET  -1
@@ -541,8 +537,8 @@ void dsi_lvds_toshiba_bridge_panel_off(void)
                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);
+       /* try to turn vadd off */
+       vlcm_vadd_put();
 }
 
 /* ************************************************************************* *\
@@ -556,9 +552,8 @@ 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);
+       /* get vadd count, and make sure vadd is on */
+       vlcm_vadd_get();
 
        if (cmi_lcd_i2c_client) {
                int ret;
@@ -1060,5 +1055,4 @@ static void __exit dsi_lvds_bridge_exit(void)
 
 module_init(dsi_lvds_bridge_init);
 module_exit(dsi_lvds_bridge_exit);
-
 #endif
index 9c18efa..87d4c07 100644 (file)
 #ifndef __MDFLD_DSI_LVDS_BRIDGE_H__
 #define __MDFLD_DSI_LVDS_BRIDGE_H__
 
+/*GPIO Pins */
+#define GPIO_MIPI_BRIDGE_RESET 115
+
+#define GPIO_MIPI_LCD_BL_EN    112
+#define GPIO_MIPI_LCD_VADD     110
+
 #define GPIOPWMCTRL    0x38F
 #define PWM0CLKDIV0    0x62 /* low byte */
 #define PWM0CLKDIV1    0x61 /* high byte */
index 128286d..3698b3e 100644 (file)
 #include "psb_intel_hdmi.h"
 #include "mdfld_ti_tpd.h"
 #include "mdfld_dsi_dpi.h"
+#include "mdfld_dsi_lvds_bridge.h"
 #ifdef CONFIG_GFX_RTPM
 #include <linux/pm_runtime.h>
 #endif
 
 #include <linux/earlysuspend.h>
+#include <linux/atomic.h>
 
 #undef OSPM_GFX_DPK
 #define SCU_CMD_VPROG2  0xe3
@@ -2584,3 +2586,49 @@ int psb_runtime_idle(struct device *dev)
                else
                        return 0;
 }
+
+#ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
+DEFINE_MUTEX(vadd_mutex);
+static int i2c_access_count;
+
+/* use access count to mark status of i2c bus 2, and make sure avdd is turned on
+ * when accessing this i2c. when accaccess count reaches 1, then turn on lvds
+ * panel's avdd
+ */
+void vlcm_vadd_get()
+{
+       mutex_lock(&vadd_mutex);
+       ++i2c_access_count;
+       if (i2c_access_count == 1) {
+               if (gpio_direction_output(GPIO_MIPI_LCD_VADD, 1)) {
+                       pr_err("%s: faild to pull high VADD\n", __func__);
+                       goto unlock;
+               }
+               msleep(260);
+       }
+unlock:
+       mutex_unlock(&vadd_mutex);
+}
+
+/* decrease reference count, and turn vadd off when count reaches 0
+ */
+void vlcm_vadd_put()
+{
+       mutex_lock(&vadd_mutex);
+       if (i2c_access_count == 0) {
+               pr_warn("%s: i2c_access_count is 0\n", __func__);
+               goto unlock;
+       }
+
+       --i2c_access_count;
+       if (i2c_access_count > 0)
+               goto unlock;
+       /* i2c_access_count == 0 */
+       if (gpio_direction_output(GPIO_MIPI_LCD_VADD, 0)) {
+               pr_err("%s: faild to pull low VADD\n",
+                               __func__);
+       }
+unlock:
+       mutex_unlock(&vadd_mutex);
+}
+#endif
index 0bcc193..de2e078 100644 (file)
@@ -127,5 +127,9 @@ void ospm_runtime_pm_forbid(struct drm_device * dev);
 void acquire_ospm_lock(void);
 void release_ospm_lock(void);
 
+#ifdef CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
+extern void vlcm_vadd_get(void);
+extern void vlcm_vadd_put(void);
+#endif
 
 #endif /*_PSB_POWERMGMT_H_*/