diff options
| author | Aravind Venkateswaran <aravindh@codeaurora.org> | 2014-04-14 13:34:06 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:29:44 -0700 |
| commit | e34e985389bfc2835ebb53bdd85ba525ccaab2f3 (patch) | |
| tree | 58cc66d6191f489b5c2e002e539486361a832ca6 | |
| parent | 31ed8dc3afab04830cc12bf7fb08d7492280a90d (diff) | |
msm: mdss: dsi: Add ULPS mode support for dual dsi configuration
For dual dsi panels with broadcast mode enabled, the two dsi
controllers work in a master-slave configuration. Add support for
enabling ultra low power state (ULPS) mode in this use case.
Change-Id: I9e4383ca60174d6ffa599ce6caa47676a5eea216
Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 87 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 28 |
2 files changed, 96 insertions, 19 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 2a62da4ee91f..02aaf97b59b4 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -486,6 +486,7 @@ static int mdss_dsi_ulps_config_sub(struct mdss_dsi_ctrl_pdata *ctrl_pdata, struct mipi_panel_info *pinfo = NULL; u32 lane_status = 0; u32 active_lanes = 0; + u32 regval = 0; if (!ctrl_pdata) { pr_err("%s: invalid input\n", __func__); @@ -554,11 +555,27 @@ static int mdss_dsi_ulps_config_sub(struct mdss_dsi_ctrl_pdata *ctrl_pdata, } /* Enable MMSS DSI Clamps */ - MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x3FF); - MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x83FF); + if (ctrl_pdata->ndx == DSI_CTRL_0) { + regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); + MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, + regval | 0x3FF); + MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, + regval | 0x83FF); + } else if (ctrl_pdata->ndx == DSI_CTRL_1) { + regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); + MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, + regval | 0x3FF0000); + MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, + regval | 0x83FF0000); + } wmb(); + /* + * This register write ensures that DSI PHY will not be + * reset when mdss ahb clock reset is asserted while coming + * out of power collapse + */ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x108, 0x1); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); @@ -593,8 +610,15 @@ static int mdss_dsi_ulps_config_sub(struct mdss_dsi_ctrl_pdata *ctrl_pdata, usleep(100); /* Disable MMSS DSI Clamps */ - MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x3FF); - MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x0); + if (ctrl_pdata->ndx == DSI_CTRL_0) { + regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); + MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, + regval & ~0x83FF); + } else if (ctrl_pdata->ndx == DSI_CTRL_1) { + regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); + MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, + regval & ~0x83FF0000); + } ret = mdss_dsi_clk_ctrl(ctrl_pdata, DSI_LINK_CLKS, 1); if (ret) { @@ -636,31 +660,72 @@ static int mdss_dsi_ulps_config(struct mdss_dsi_ctrl_pdata *ctrl, { int rc; struct mdss_dsi_ctrl_pdata *mctrl = NULL; + struct mdss_dsi_ctrl_pdata *sctrl = NULL; if (&ctrl->mmss_misc_io == NULL) { pr_err("%s: mmss_misc_io is NULL. ULPS not valid\n", __func__); return -EINVAL; } + if (mdss_dsi_is_master_ctrl(ctrl)) { + if (enable) { + pr_debug("%s: skipping enable for master ctrl%d\n", + __func__, ctrl->ndx); + rc = 0; + goto error; + } else { + sctrl = mdss_dsi_get_slave_ctrl(); + if (!sctrl) { + pr_err("%s: Unable to get slave control\n", + __func__); + rc = -EINVAL; + goto error; + } + } + } + if (mdss_dsi_is_slave_ctrl(ctrl)) { - mctrl = mdss_dsi_get_master_ctrl(); - if (!mctrl) { - pr_err("%s: Unable to get master control\n", __func__); - return -EINVAL; + if (enable) { + mctrl = mdss_dsi_get_master_ctrl(); + if (!mctrl) { + pr_err("%s: Unable to get master control\n", + __func__); + rc = -EINVAL; + goto error; + } + } else { + pr_debug("%s: skipping disable for slave ctrl%d\n", + __func__, ctrl->ndx); + rc = 0; + goto error; } } if (mctrl) { pr_debug("%s: configuring ulps (%s) for master ctrl%d\n", - __func__, (enable ? "on" : "off"), ctrl->ndx); + __func__, (enable ? "on" : "off"), mctrl->ndx); rc = mdss_dsi_ulps_config_sub(mctrl, enable); if (rc) - return rc; + goto error; } pr_debug("%s: configuring ulps (%s) for ctrl%d\n", __func__, (enable ? "on" : "off"), ctrl->ndx); - return mdss_dsi_ulps_config_sub(ctrl, enable); + rc = mdss_dsi_ulps_config_sub(ctrl, enable); + if (rc) + goto error; + + if (sctrl) { + pr_debug("%s: configuring ulps (%s) for slave ctrl%d\n", + __func__, (enable ? "on" : "off"), sctrl->ndx); + rc = mdss_dsi_ulps_config_sub(sctrl, enable); + } + +error: + if (rc) + pr_err("%s: Failed to configure ulps (%s) for ctrl%d\n", + __func__, (enable ? "on" : "off"), ctrl->ndx); + return rc; } int mdss_dsi_on(struct mdss_panel_data *pdata) diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 138d43c9e0df..cca4c1df613a 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -1815,6 +1815,19 @@ int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg) return rc; } +static void mdss_mdp_ctl_restore_sub(struct mdss_mdp_ctl *ctl) +{ + u32 temp; + + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); + temp = readl_relaxed(ctl->mdata->mdp_base + + MDSS_MDP_REG_DISP_INTF_SEL); + temp |= (ctl->intf_type << ((ctl->intf_num - MDSS_MDP_INTF0) * 8)); + writel_relaxed(temp, ctl->mdata->mdp_base + + MDSS_MDP_REG_DISP_INTF_SEL); + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); +} + /* * mdss_mdp_ctl_restore() - restore mdp ctl path * @ctl: mdp controller. @@ -1825,15 +1838,14 @@ int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg) */ void mdss_mdp_ctl_restore(struct mdss_mdp_ctl *ctl) { - u32 temp; + struct mdss_mdp_ctl *sctl; - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); - temp = readl_relaxed(ctl->mdata->mdp_base + - MDSS_MDP_REG_DISP_INTF_SEL); - temp |= (ctl->intf_type << ((ctl->intf_num - MDSS_MDP_INTF0) * 8)); - writel_relaxed(temp, ctl->mdata->mdp_base + - MDSS_MDP_REG_DISP_INTF_SEL); - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); + sctl = mdss_mdp_get_split_ctl(ctl); + mdss_mdp_ctl_restore_sub(ctl); + if (sctl) { + mdss_mdp_ctl_restore_sub(sctl); + mdss_mdp_ctl_split_display_enable(1, ctl, sctl); + } } static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff) |
