summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c87
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c28
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)