diff options
| author | Siddhartha Agrawal <agrawals@codeaurora.org> | 2014-09-05 10:50:41 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:33:45 -0700 |
| commit | 3555d62dbcb02f43d3dbacd80b03fcd1e60551db (patch) | |
| tree | b44064734a4f85a507fdd1ce682c297c0c7c0a83 | |
| parent | 7fa4cb64514b5a4d8deb938222074a69dda347b6 (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.c | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.h | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/msm_mdss_io_8974.c | 49 |
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 |
