]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
arm: tegra: enterprise: disable dsi_csi_rail in LP0
authorVinayak Pane <vpane@nvidia.com>
Sat, 14 Apr 2012 00:13:15 +0000 (17:13 -0700)
committerDan Willemsen <dwillemsen@nvidia.com>
Sat, 14 Sep 2013 19:09:11 +0000 (12:09 -0700)
AVDD_DSI_CSI is shared by modem and dsi. If DSI turns
off this rail then HSIC fails after wakeup from modem.
This patch provides a way to turn on this rail from
modem as well as from DSI. Create two virtual power rails
from avdd_csi_dsi to control it from both the drivers separately.
This is enterprise specific change as per the power rail layout.

Bug 920881

(cherry picked from commit ab52b51c59f776ae770d48a28a2744e2db2e5d2f)
Reviewed-on: http://git-master/r/85656

Change-Id: I2e9c04a8f4e8d6fd20584b4e75657c1cb6d5c8bd
Signed-off-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-on: http://git-master/r/89134
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Puneet Saxena <puneets@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Rebase-Id: R6151e9d044c1a8c9fca222144e9644e8e0ea60cf

arch/arm/mach-tegra/baseband-xmm-power.c

index 45c00b7c436e6d849e1ce49ea66876eca911f9e9..13210bd68a4689bef8886664ecea24de20089d01 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/suspend.h>
 #include <mach/usb_phy.h>
 #include "board.h"
+#include "board-enterprise.h"
 #include "devices.h"
 #include "gpio-names.h"
 #include "baseband-xmm-power.h"
@@ -107,11 +108,70 @@ static bool modem_sleep_flag;
 static spinlock_t xmm_lock;
 static DEFINE_MUTEX(xmm_onoff_mutex);
 static bool system_suspending;
+static struct regulator *enterprise_hsic_reg;
+static bool _hsic_reg_status;
 
 static void baseband_xmm_power_L2_resume(void);
 static int baseband_xmm_power_driver_handle_resume(
                        struct baseband_power_platform_data *data);
 
+static int tegra_baseband_rail_on(void)
+{
+       int ret;
+       struct board_info bi;
+       tegra_get_board_info(&bi);
+
+       /* only applicable to enterprise */
+       if (bi.board_id != BOARD_E1197)
+               return 0;
+
+       if (_hsic_reg_status == true)
+               return 0;
+
+       if (enterprise_hsic_reg == NULL) {
+               enterprise_hsic_reg = regulator_get(NULL, "avdd_hsic");
+               if (IS_ERR_OR_NULL(enterprise_hsic_reg)) {
+                       pr_err("xmm: could not get regulator vddio_hsic\n");
+                       enterprise_hsic_reg = NULL;
+                       return PTR_ERR(enterprise_hsic_reg);
+               }
+       }
+       ret = regulator_enable(enterprise_hsic_reg);
+       if (ret < 0) {
+               pr_err("xmm: failed to enable regulator\n");
+               return ret;
+       }
+       _hsic_reg_status = true;
+       return 0;
+}
+
+static int tegra_baseband_rail_off(void)
+{
+       int ret;
+       struct board_info bi;
+       tegra_get_board_info(&bi);
+
+       /* only applicable to enterprise */
+       if (bi.board_id != BOARD_E1197)
+               return 0;
+
+       if (_hsic_reg_status == false)
+               return 0;
+
+       if (IS_ERR_OR_NULL(enterprise_hsic_reg)) {
+               pr_err("xmm: unbalanced disable on vddio_hsic regulator\n");
+               enterprise_hsic_reg = NULL;
+               return PTR_ERR(enterprise_hsic_reg);
+       }
+       ret = regulator_disable(enterprise_hsic_reg);
+       if (ret < 0) {
+               pr_err("xmm: failed to disable regulator\n");
+               return ret;
+       }
+       _hsic_reg_status = false;
+       return 0;
+}
+
 static int baseband_modem_power_on(struct baseband_power_platform_data *data)
 {
        /* set IPC_HSIC_ACTIVE active */
@@ -146,6 +206,8 @@ static int baseband_xmm_power_on(struct platform_device *device)
        if (baseband_xmm_powerstate != BBXMM_PS_UNINIT)
                return -EINVAL;
 
+       tegra_baseband_rail_on();
+
        /* reset the state machine */
        baseband_xmm_powerstate = BBXMM_PS_INIT;
        modem_sleep_flag = false;
@@ -245,6 +307,8 @@ static int baseband_xmm_power_off(struct platform_device *device)
        spin_unlock_irqrestore(&xmm_lock, flags);
        /* start registration process once again on xmm on */
        register_hsic_device = true;
+
+       tegra_baseband_rail_off();
        pr_debug("%s }\n", __func__);
 
        return 0;
@@ -358,6 +422,10 @@ void baseband_xmm_set_power_status(unsigned int status)
                        }
                }
                pr_info("L3\n");
+               /* system is going to suspend */
+               if (baseband_xmm_powerstate == BBXMM_PS_L2)
+                       tegra_baseband_rail_off();
+
                baseband_xmm_powerstate = status;
                spin_lock_irqsave(&xmm_lock, flags);
                system_suspending = false;
@@ -383,6 +451,12 @@ void baseband_xmm_set_power_status(unsigned int status)
                }
                baseband_xmm_powerstate = status;
                break;
+       case BBXMM_PS_L3TOL0:
+               /* poweron rail for L3 -> L0 (system resume) */
+               pr_debug("L3 -> L0, turning on power rail.\n");
+               tegra_baseband_rail_on();
+               baseband_xmm_powerstate = status;
+               break;
        default:
                baseband_xmm_powerstate = status;
                break;