summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorVinayak Pane <vpane@nvidia.com>2012-04-13 17:13:15 -0700
committerSimone Willett <swillett@nvidia.com>2012-04-18 16:46:32 -0700
commit69b3378dd9151627f621b40a5fe82fe697494ee3 (patch)
treef2189bc56bf100cce4f4c77c0558ca1bcf38f008 /arch/arm
parent25eb47aef9013f06b3560719966e682e3064907b (diff)
arm: tegra: enterprise: disable dsi_csi_rail in LP0
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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power.c74
-rw-r--r--arch/arm/mach-tegra/board-enterprise-panel.c53
-rw-r--r--arch/arm/mach-tegra/board-enterprise-power.c1
3 files changed, 119 insertions, 9 deletions
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.c b/arch/arm/mach-tegra/baseband-xmm-power.c
index 0e642d8ebcb3..2d41abc8571a 100644
--- a/arch/arm/mach-tegra/baseband-xmm-power.c
+++ b/arch/arm/mach-tegra/baseband-xmm-power.c
@@ -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;
diff --git a/arch/arm/mach-tegra/board-enterprise-panel.c b/arch/arm/mach-tegra/board-enterprise-panel.c
index 913a5775eaf3..dbc1c4890285 100644
--- a/arch/arm/mach-tegra/board-enterprise-panel.c
+++ b/arch/arm/mach-tegra/board-enterprise-panel.c
@@ -63,6 +63,7 @@
#ifdef CONFIG_TEGRA_DC
static struct regulator *enterprise_dsi_reg;
+static bool dsi_regulator_status;
static struct regulator *enterprise_lcd_reg;
static struct regulator *enterprise_hdmi_reg;
@@ -454,27 +455,61 @@ static struct tegra_dc_platform_data enterprise_disp2_pdata = {
.emc_clk_rate = 300000000,
};
-static int enterprise_dsi_panel_enable(void)
+static int avdd_dsi_csi_rail_enable(void)
{
int ret;
- struct board_info board_info;
- tegra_get_board_info(&board_info);
+ if (dsi_regulator_status == true)
+ return 0;
if (enterprise_dsi_reg == NULL) {
enterprise_dsi_reg = regulator_get(NULL, "avdd_dsi_csi");
if (IS_ERR_OR_NULL(enterprise_dsi_reg)) {
pr_err("dsi: Could not get regulator avdd_dsi_csi\n");
- enterprise_dsi_reg = NULL;
- return PTR_ERR(enterprise_dsi_reg);
+ enterprise_dsi_reg = NULL;
+ return PTR_ERR(enterprise_dsi_reg);
}
}
ret = regulator_enable(enterprise_dsi_reg);
if (ret < 0) {
- printk(KERN_ERR
- "DSI regulator avdd_dsi_csi could not be enabled\n");
+ pr_err("DSI regulator avdd_dsi_csi could not be enabled\n");
+ return ret;
+ }
+ dsi_regulator_status = true;
+ return 0;
+}
+
+static int avdd_dsi_csi_rail_disable(void)
+{
+ int ret;
+
+ if (dsi_regulator_status == false)
+ return 0;
+
+ if (enterprise_dsi_reg == NULL) {
+ pr_warn("%s: unbalanced disable\n", __func__);
+ return -EIO;
+ }
+
+ ret = regulator_disable(enterprise_dsi_reg);
+ if (ret < 0) {
+ pr_err("DSI regulator avdd_dsi_csi cannot be disabled\n");
return ret;
}
+ dsi_regulator_status = false;
+ return 0;
+}
+
+static int enterprise_dsi_panel_enable(void)
+{
+ int ret;
+ struct board_info board_info;
+
+ tegra_get_board_info(&board_info);
+
+ ret = avdd_dsi_csi_rail_enable();
+ if (ret)
+ return ret;
#if DSI_PANEL_RESET
@@ -562,8 +597,8 @@ static void enterprise_stereo_set_orientation(int mode)
#ifdef CONFIG_TEGRA_DC
static int enterprise_dsi_panel_postsuspend(void)
{
- /* Do nothing for enterprise dsi panel */
- return 0;
+ /* Disable enterprise dsi rail */
+ return avdd_dsi_csi_rail_disable();
}
#endif
diff --git a/arch/arm/mach-tegra/board-enterprise-power.c b/arch/arm/mach-tegra/board-enterprise-power.c
index 9d7a4d6e6dff..c17c3eaf5cfa 100644
--- a/arch/arm/mach-tegra/board-enterprise-power.c
+++ b/arch/arm/mach-tegra/board-enterprise-power.c
@@ -147,6 +147,7 @@ static struct regulator_consumer_supply tps80031_vana_supply_common[] = {
static struct regulator_consumer_supply tps80031_ldo1_supply_a02[] = {
REGULATOR_SUPPLY("avdd_dsi_csi", NULL),
+ REGULATOR_SUPPLY("avdd_hsic", NULL),
REGULATOR_SUPPLY("pwrdet_mipi", NULL),
};