Merge "msm: mdss: cleanup dsi clock handling"
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index d51bef1..7c55702 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -151,7 +151,6 @@
#define DSI_CMD_TERM BIT(0)
extern struct device dsi_dev;
-extern int mdss_dsi_clk_on;
extern u32 dsi_irq;
extern struct mdss_dsi_ctrl_pdata *ctrl_list[];
@@ -246,7 +245,6 @@
struct dss_io_data phy_io;
int reg_size;
u32 clk_cnt;
- int clk_cnt_sub;
u32 flags;
struct clk *mdp_core_clk;
struct clk *ahb_clk;
@@ -258,7 +256,6 @@
u8 ctrl_state;
int panel_mode;
int irq_cnt;
- int mdss_dsi_clk_on;
int rst_gpio;
int disp_en_gpio;
int disp_te_gpio;
@@ -317,7 +314,7 @@
void mdss_dsi_cmd_mdp_start(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmd_bta_sw_trigger(struct mdss_panel_data *pdata);
void mdss_dsi_ack_err_status(struct mdss_dsi_ctrl_pdata *ctrl);
-void mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable);
+int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable);
int mdss_dsi_link_clk_start(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_link_clk_stop(struct mdss_dsi_ctrl_pdata *ctrl);
int mdss_dsi_bus_clk_start(struct mdss_dsi_ctrl_pdata *ctrl);
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index 73e0ebe..b16ad0d 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -408,11 +408,6 @@
pr_debug("%s: ndx=%d\n", __func__, ctrl_pdata->ndx);
- if (ctrl_pdata->mdss_dsi_clk_on) {
- pr_info("%s: mdss_dsi_clks already ON\n", __func__);
- return 0;
- }
-
rc = clk_enable(ctrl_pdata->esc_clk);
if (rc) {
pr_err("%s: Failed to enable dsi esc clk\n", __func__);
@@ -431,8 +426,6 @@
goto pixel_clk_err;
}
- ctrl_pdata->mdss_dsi_clk_on = 1;
-
return rc;
pixel_clk_err:
@@ -452,16 +445,9 @@
pr_debug("%s: ndx=%d\n", __func__, ctrl_pdata->ndx);
- if (ctrl_pdata->mdss_dsi_clk_on == 0) {
- pr_info("%s: mdss_dsi_clks already OFF\n", __func__);
- return;
- }
-
clk_disable(ctrl_pdata->esc_clk);
clk_disable(ctrl_pdata->pixel_clk);
clk_disable(ctrl_pdata->byte_clk);
-
- ctrl_pdata->mdss_dsi_clk_on = 0;
}
int mdss_dsi_link_clk_start(struct mdss_dsi_ctrl_pdata *ctrl)
@@ -500,35 +486,52 @@
mdss_dsi_link_clk_unprepare(ctrl);
}
-static void mdss_dsi_clk_ctrl_sub(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
+static int __mdss_dsi_update_clk_cnt(u32 *clk_cnt, int enable)
{
int changed = 0;
if (enable) {
- if (ctrl->clk_cnt_sub == 0)
+ if (*clk_cnt == 0)
changed++;
- ctrl->clk_cnt_sub++;
+ (*clk_cnt)++;
} else {
- if (ctrl->clk_cnt_sub) {
- ctrl->clk_cnt_sub--;
- if (ctrl->clk_cnt_sub == 0)
+ if (*clk_cnt != 0) {
+ (*clk_cnt)--;
+ if (*clk_cnt == 0)
changed++;
} else {
- pr_debug("%s: Can not be turned off\n", __func__);
+ pr_debug("%s: clk cnt already zero\n", __func__);
}
}
- pr_debug("%s: ndx=%d clk_cnt_sub=%d changed=%d enable=%d\n",
- __func__, ctrl->ndx, ctrl->clk_cnt_sub, changed, enable);
- if (changed) {
- if (enable) {
- if (mdss_dsi_bus_clk_start(ctrl) == 0)
- mdss_dsi_link_clk_start(ctrl);
- } else {
- mdss_dsi_link_clk_stop(ctrl);
- mdss_dsi_bus_clk_stop(ctrl);
+ return changed;
+}
+
+static int mdss_dsi_clk_ctrl_sub(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
+{
+ int rc = 0;
+
+ pr_debug("%s: ndx=%d enable=%d\n", __func__, ctrl->ndx, enable);
+
+ if (enable) {
+ rc = mdss_dsi_bus_clk_start(ctrl);
+ if (rc) {
+ pr_err("Failed to start bus clocks. rc=%d\n", rc);
+ goto error;
}
+ rc = mdss_dsi_link_clk_start(ctrl);
+ if (rc) {
+ pr_err("Failed to start link clocks. rc=%d\n", rc);
+ mdss_dsi_bus_clk_stop(ctrl);
+ goto error;
+ }
+ } else {
+ mdss_dsi_link_clk_stop(ctrl);
+ mdss_dsi_bus_clk_stop(ctrl);
}
+
+error:
+ return rc;
}
static DEFINE_MUTEX(dsi_clk_lock); /* per system */
@@ -543,11 +546,17 @@
return enabled;
}
-void mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
+int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
{
- int changed = 0;
+ int rc = 0;
+ int changed = 0, m_changed = 0;
struct mdss_dsi_ctrl_pdata *mctrl = NULL;
+ if (!ctrl) {
+ pr_err("%s: Invalid arg\n", __func__);
+ return -EINVAL;
+ }
+
/*
* In broadcast mode, we need to enable clocks for the
* master controller as well when enabling clocks for the
@@ -559,34 +568,61 @@
pr_warn("%s: Unable to get master control\n", __func__);
}
+ pr_debug("%s++: ndx=%d clk_cnt=%d mctrl=%s m_clk_cnt=%d\n, enable=%d\n",
+ __func__, ctrl->ndx, ctrl->clk_cnt,
+ mctrl ? "yes" : "no", mctrl ? mctrl->clk_cnt : -1, enable);
+
mutex_lock(&dsi_clk_lock);
- if (enable) {
- if (ctrl->clk_cnt == 0)
- changed++;
- ctrl->clk_cnt++;
- } else {
- if (ctrl->clk_cnt) {
- ctrl->clk_cnt--;
- if (ctrl->clk_cnt == 0)
- changed++;
- } else {
- pr_debug("%s: Can not be turned off\n", __func__);
+ changed = __mdss_dsi_update_clk_cnt(&ctrl->clk_cnt, enable);
+ if (changed && mctrl)
+ m_changed = __mdss_dsi_update_clk_cnt(&mctrl->clk_cnt, enable);
+
+ if (changed) {
+ if (enable && m_changed) {
+ rc = mdss_dsi_clk_ctrl_sub(mctrl, enable);
+ if (rc) {
+ pr_err("Failed to start mctrl clocks. rc=%d\n",
+ rc);
+ goto error_mctrl_start;
+ }
+ }
+
+ rc = mdss_dsi_clk_ctrl_sub(ctrl, enable);
+ if (rc) {
+ pr_err("Failed to %s ctrl clocks. rc=%d\n",
+ (enable ? "start" : "stop"), rc);
+ goto error_ctrl;
+ }
+
+ if (!enable && m_changed) {
+ rc = mdss_dsi_clk_ctrl_sub(mctrl, enable);
+ if (rc) {
+ pr_err("Failed to stop mctrl clocks. rc=%d\n",
+ rc);
+ goto error_mctrl_stop;
+ }
}
}
- pr_debug("%s: ndx=%d clk_cnt=%d changed=%d enable=%d\n",
- __func__, ctrl->ndx, ctrl->clk_cnt, changed, enable);
+ goto no_error;
- if (changed) {
- if (enable && mctrl)
- mdss_dsi_clk_ctrl_sub(mctrl, enable);
+error_mctrl_stop:
+ mdss_dsi_clk_ctrl_sub(ctrl, enable ? 0 : 1);
+error_ctrl:
+ mdss_dsi_clk_ctrl_sub(mctrl, 0);
+error_mctrl_start:
+ __mdss_dsi_update_clk_cnt(&mctrl->clk_cnt, enable ? 0 : 1);
+ __mdss_dsi_update_clk_cnt(&ctrl->clk_cnt, enable ? 0 : 1);
- mdss_dsi_clk_ctrl_sub(ctrl, enable);
-
- if (!enable && mctrl)
- mdss_dsi_clk_ctrl_sub(mctrl, enable);
- }
+no_error:
mutex_unlock(&dsi_clk_lock);
+ pr_debug("%s--: ndx=%d clk_cnt=%d changed=%d mctrl=%s m_clk_cnt=%d\n",
+ __func__, ctrl->ndx, ctrl->clk_cnt, changed,
+ mctrl ? "yes" : "no", mctrl ? mctrl->clk_cnt : -1);
+ pr_debug("%s--: m_changed=%d enable=%d\n", __func__,
+ mctrl ? m_changed : -1, enable);
+
+ return rc;
}
void mdss_dsi_phy_sw_reset(unsigned char *ctrl_base)