summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiddhartha Agrawal <agrawals@codeaurora.org>2014-09-05 10:50:41 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:33:45 -0700
commit3555d62dbcb02f43d3dbacd80b03fcd1e60551db (patch)
treeb44064734a4f85a507fdd1ce682c297c0c7c0a83
parent7fa4cb64514b5a4d8deb938222074a69dda347b6 (diff)
msm: mdss: dsi: Fix current leakage issue for DSI PLL 1
DSI PLL 1 leaks current after a phy s/w reset. Add support to re-program the PLL 1 registers and correctly turn it off. Change-Id: I9184951d0d095b188ade13faff8d834fa9bd5010 Signed-off-by: Siddhartha Agrawal <agrawals@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h3
-rw-r--r--drivers/video/fbdev/msm/msm_mdss_io_8974.c49
3 files changed, 52 insertions, 4 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 02cc293a8d3c..63e1c5ac308a 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1765,6 +1765,10 @@ int dsi_panel_device_register(struct device_node *pan_node,
return -EPERM;
}
+ rc = mdss_dsi_pll_1_clk_init(ctrl_pdev, ctrl_pdata);
+ if (rc)
+ pr_err("PLL 1 Clock's did not register\n");
+
if (pinfo->dynamic_fps &&
pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
if (mdss_dsi_shadow_clk_init(ctrl_pdev, ctrl_pdata)) {
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index 6c38210d606f..e7e3bd307c2a 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -308,6 +308,7 @@ struct mdss_dsi_ctrl_pdata {
struct clk *pll_pixel_clk;
struct clk *shadow_byte_clk;
struct clk *shadow_pixel_clk;
+ struct clk *vco_clk;
u8 ctrl_state;
int panel_mode;
int irq_cnt;
@@ -424,6 +425,8 @@ int mdss_dsi_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+int mdss_dsi_pll_1_clk_init(struct platform_device *pdev,
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_shadow_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index dee32aa4de94..29faeb010bce 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -26,16 +26,34 @@
static struct dsi_clk_desc dsi_pclk;
-static void mdss_dsi_phy_sw_reset(unsigned char *ctrl_base)
+static void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl)
{
+ u32 ctrl_rev;
+ if (ctrl == NULL) {
+ pr_err("%s: Invalid input data\n", __func__);
+ return;
+ }
+
/* start phy sw reset */
- MIPI_OUTP(ctrl_base + 0x12c, 0x0001);
+ MIPI_OUTP(ctrl->ctrl_base + 0x12c, 0x0001);
udelay(1000);
wmb();
/* end phy sw reset */
- MIPI_OUTP(ctrl_base + 0x12c, 0x0000);
+ MIPI_OUTP(ctrl->ctrl_base + 0x12c, 0x0000);
udelay(100);
wmb();
+
+ /*
+ * phy sw reset will wipe out the pll settings for PLL.
+ * Need to turn off the PLL1 to avoid current leakage issues
+ */
+ if (ctrl->ndx == DSI_CTRL_1) {
+ ctrl_rev = MIPI_INP(ctrl->ctrl_base);
+ if (ctrl_rev == MDSS_DSI_HW_REV_103) {
+ pr_err("Turn off PLL 1 registers\n");
+ clk_set_rate(ctrl->vco_clk, 1);
+ }
+ }
}
void mdss_dsi_phy_disable(struct mdss_dsi_ctrl_pdata *ctrl)
@@ -418,6 +436,29 @@ mdss_dsi_clk_err:
return rc;
}
+int mdss_dsi_pll_1_clk_init(struct platform_device *pdev,
+ struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ struct device *dev = NULL;
+ int rc = 0;
+
+ if (!pdev) {
+ pr_err("%s: Invalid pdev\n", __func__);
+ return -EINVAL;
+ }
+
+ dev = &pdev->dev;
+ ctrl->vco_clk = clk_get(dev, "clk_mdss_dsi1_vco_clk_src");
+ if (IS_ERR(ctrl->vco_clk)) {
+ rc = PTR_ERR(ctrl->vco_clk);
+ pr_err("%s: can't find vco_clk. rc=%d\n",
+ __func__, rc);
+ ctrl->vco_clk = NULL;
+ }
+
+ return rc;
+}
+
int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl)
{
@@ -1183,7 +1224,7 @@ static int mdss_dsi_core_power_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
* unblanking the panel.
*/
if (pdata->panel_info.blank_state == MDSS_PANEL_BLANK_BLANK)
- mdss_dsi_phy_sw_reset(ctrl->ctrl_base);
+ mdss_dsi_phy_sw_reset(ctrl);
/*
* Phy and controller setup need not be done during bootup