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;
}
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)) {

View file

@ -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);

View file

@ -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