From: Geng Xiujun Date: Fri, 4 May 2012 07:54:59 +0000 (+0800) Subject: display: [REVERTME] add access count for AVDD gpio pin for DV20 X-Git-Tag: 2.1b_release~822 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dd9223029e27f261354abcd2d304c75fc77d4063;p=kernel%2Fkernel-mfld-blackbay.git display: [REVERTME] add access count for AVDD gpio pin for DV20 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 Reviewed-on: http://android.intel.com:8080/47423 Reviewed-by: Xu, Randy Reviewed-by: Ai, Ke Reviewed-by: Zhang, Lei Reviewed-by: Yang, Bin Reviewed-by: Hogander, Jouni Tested-by: Tong, BoX Reviewed-by: buildbot Tested-by: buildbot --- diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 3a39bf1..2de78d3 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -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 */ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 45ea3b8..c30224e 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -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... */ diff --git a/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.c b/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.c index 6b79002..121795b 100644 --- a/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.c +++ b/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.c @@ -28,15 +28,11 @@ #include "mdfld_dsi_lvds_bridge.h" #include "psb_drv.h" #include +#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 diff --git a/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h b/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h index 9c18efa..87d4c07 100644 --- a/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h +++ b/drivers/staging/mrst/drv/mdfld_dsi_lvds_bridge.h @@ -25,6 +25,12 @@ #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 */ diff --git a/drivers/staging/mrst/drv/psb_powermgmt.c b/drivers/staging/mrst/drv/psb_powermgmt.c index 128286d..3698b3e 100644 --- a/drivers/staging/mrst/drv/psb_powermgmt.c +++ b/drivers/staging/mrst/drv/psb_powermgmt.c @@ -41,11 +41,13 @@ #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 #endif #include +#include #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 diff --git a/drivers/staging/mrst/drv/psb_powermgmt.h b/drivers/staging/mrst/drv/psb_powermgmt.h index 0bcc193..de2e078 100644 --- a/drivers/staging/mrst/drv/psb_powermgmt.h +++ b/drivers/staging/mrst/drv/psb_powermgmt.h @@ -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_*/