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>
This commit is contained in:
Siddhartha Agrawal 2014-09-05 10:50:41 -07:00 committed by David Keitel
parent 7fa4cb6451
commit 3555d62dbc
3 changed files with 52 additions and 4 deletions

View file

@ -1765,6 +1765,10 @@ int dsi_panel_device_register(struct device_node *pan_node,
return -EPERM; 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 && if (pinfo->dynamic_fps &&
pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) { pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
if (mdss_dsi_shadow_clk_init(ctrl_pdev, ctrl_pdata)) { if (mdss_dsi_shadow_clk_init(ctrl_pdev, ctrl_pdata)) {

View file

@ -308,6 +308,7 @@ struct mdss_dsi_ctrl_pdata {
struct clk *pll_pixel_clk; struct clk *pll_pixel_clk;
struct clk *shadow_byte_clk; struct clk *shadow_byte_clk;
struct clk *shadow_pixel_clk; struct clk *shadow_pixel_clk;
struct clk *vco_clk;
u8 ctrl_state; u8 ctrl_state;
int panel_mode; int panel_mode;
int irq_cnt; int irq_cnt;
@ -424,6 +425,8 @@ int mdss_dsi_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata); struct mdss_dsi_ctrl_pdata *ctrl_pdata);
int mdss_dsi_shadow_clk_init(struct platform_device *pdev, int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata); 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_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_shadow_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); int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);

View file

@ -26,16 +26,34 @@
static struct dsi_clk_desc dsi_pclk; 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 */ /* start phy sw reset */
MIPI_OUTP(ctrl_base + 0x12c, 0x0001); MIPI_OUTP(ctrl->ctrl_base + 0x12c, 0x0001);
udelay(1000); udelay(1000);
wmb(); wmb();
/* end phy sw reset */ /* end phy sw reset */
MIPI_OUTP(ctrl_base + 0x12c, 0x0000); MIPI_OUTP(ctrl->ctrl_base + 0x12c, 0x0000);
udelay(100); udelay(100);
wmb(); 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) void mdss_dsi_phy_disable(struct mdss_dsi_ctrl_pdata *ctrl)
@ -418,6 +436,29 @@ mdss_dsi_clk_err:
return rc; 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, int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl) 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. * unblanking the panel.
*/ */
if (pdata->panel_info.blank_state == MDSS_PANEL_BLANK_BLANK) 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 * Phy and controller setup need not be done during bootup