summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@codeaurora.org>2014-04-03 18:17:06 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:29:29 -0700
commit6b26faccfaf66a7a21b46bad0401db89306f0fcb (patch)
tree25013536310cda579d7b589585c4a5c2c7f53457
parentdbb88ca56b73971d483cf89cc3e5e7f1620df58c (diff)
msm: mdss: add error check for iommu attach API
Iommu device attach api returns error code if it fails. MDP driver will check this error code and fall back to recovery path if device attach fails. Change-Id: I2b9d2d3aa16bc814739e466e9fc5a2c51c7b2b4b Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c6
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c61
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c74
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_wb.c9
6 files changed, 114 insertions, 40 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index f91cb6b62a53..225fe345fffe 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -232,7 +232,7 @@ int mdss_register_irq(struct mdss_hw *hw);
void mdss_enable_irq(struct mdss_hw *hw);
void mdss_disable_irq(struct mdss_hw *hw);
void mdss_disable_irq_nosync(struct mdss_hw *hw);
-void mdss_bus_bandwidth_ctrl(int enable);
+int mdss_bus_bandwidth_ctrl(int enable);
static inline struct ion_client *mdss_get_ionclient(void)
{
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index 7c1f184c1f51..69577158dedd 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -1267,7 +1267,11 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
* also, axi bus bandwidth need since dsi controller will
* fetch dcs commands from axi bus
*/
- mdss_bus_bandwidth_ctrl(1);
+ ret = mdss_bus_bandwidth_ctrl(1);
+ if (ret) {
+ pr_err("bus bandwidth request failed ret=%d\n", ret);
+ goto need_lock;
+ }
pr_debug("%s: from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index ada8764f9453..75f2e77a8c4d 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -675,18 +675,29 @@ unsigned long mdss_mdp_get_clk_rate(u32 clk_idx)
* Function place bus bandwidth request to allocate saved bandwidth
* if enabled or free bus bandwidth allocation if disabled.
* Bus bandwidth is required by mdp.For dsi, it only requires to send
- * dcs coammnd.
+ * dcs coammnd. It returns error if bandwidth request fails.
*/
-void mdss_bus_bandwidth_ctrl(int enable)
+int mdss_bus_bandwidth_ctrl(int enable)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
static int bus_bw_cnt;
int changed = 0;
+ int rc = 0;
mutex_lock(&bus_bw_lock);
if (enable) {
- if (bus_bw_cnt == 0)
+ if (bus_bw_cnt == 0) {
changed++;
+ if (!mdata->handoff_pending) {
+ rc = mdss_iommu_attach(mdata);
+ if (rc) {
+ pr_err("iommu attach failed rc=%d\n",
+ rc);
+ goto end;
+ }
+ }
+ }
+
bus_bw_cnt++;
} else {
if (bus_bw_cnt) {
@@ -711,12 +722,12 @@ void mdss_bus_bandwidth_ctrl(int enable)
pm_runtime_get_sync(&mdata->pdev->dev);
msm_bus_scale_client_update_request(
mdata->bus_hdl, mdata->curr_bw_uc_idx);
- if (!mdata->handoff_pending)
- mdss_iommu_attach(mdata);
}
}
+end:
mutex_unlock(&bus_bw_lock);
+ return rc;
}
EXPORT_SYMBOL(mdss_bus_bandwidth_ctrl);
@@ -724,7 +735,7 @@ void mdss_mdp_clk_ctrl(int enable, int isr)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
static int mdp_clk_cnt;
- int changed = 0;
+ int changed = 0, rc;
mutex_lock(&mdp_clk_lock);
if (enable) {
@@ -757,7 +768,9 @@ void mdss_mdp_clk_ctrl(int enable, int isr)
if (mdata->vsync_ena)
mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable);
- mdss_bus_bandwidth_ctrl(enable);
+ rc = mdss_bus_bandwidth_ctrl(enable);
+ if (rc)
+ pr_err("bus bandwidth control failed rc=%d", rc);
if (!enable)
pm_runtime_put(&mdata->pdev->dev);
@@ -846,15 +859,14 @@ int mdss_iommu_attach(struct mdss_data_type *mdata)
{
struct iommu_domain *domain;
struct mdss_iommu_map_type *iomap;
- int i;
+ int i, rc = 0;
mutex_lock(&mdp_iommu_lock);
MDSS_XLOG(mdata->iommu_attached);
if (mdata->iommu_attached) {
pr_debug("mdp iommu already attached\n");
- mutex_unlock(&mdp_iommu_lock);
- return 0;
+ goto end;
}
for (i = 0; i < MDSS_IOMMU_MAX_DOMAIN; i++) {
@@ -866,13 +878,23 @@ int mdss_iommu_attach(struct mdss_data_type *mdata)
iomap->client_name, iomap->ctx_name);
continue;
}
- iommu_attach_device(domain, iomap->ctx);
+
+ rc = iommu_attach_device(domain, iomap->ctx);
+ if (rc) {
+ WARN(1, "mdp::iommu device attach failed rc:%d\n", rc);
+ for (i--; i >= 0; i--) {
+ iomap = mdata->iommu_map + i;
+ iommu_detach_device(domain, iomap->ctx);
+ }
+ goto end;
+ }
}
mdata->iommu_attached = true;
+end:
mutex_unlock(&mdp_iommu_lock);
- return 0;
+ return rc;
}
int mdss_iommu_dettach(struct mdss_data_type *mdata)
@@ -2723,22 +2745,31 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
* MDSS GDSC can be voted off during idle-screen usecase for MIPI DSI command
* mode displays with Ultra-Low Power State (ULPS) feature enabled. Upon
* subsequent frame update, MDSS GDSC needs to turned back on and hw state
- * needs to be restored.
+ * needs to be restored. It returns error if footswitch control API
+ * fails.
*/
-void mdss_mdp_footswitch_ctrl_ulps(int on, struct device *dev)
+int mdss_mdp_footswitch_ctrl_ulps(int on, struct device *dev)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ int rc = 0;
pr_debug("called on=%d\n", on);
if (on) {
pm_runtime_get_sync(dev);
- mdss_iommu_attach(mdata);
+ rc = mdss_iommu_attach(mdata);
+ if (rc) {
+ pr_err("mdss iommu attach failed rc=%d\n", rc);
+ goto end;
+ }
mdss_hw_init(mdata);
mdata->ulps = false;
} else {
mdata->ulps = true;
pm_runtime_put_sync(dev);
}
+
+end:
+ return rc;
}
static inline int mdss_mdp_suspend_sub(struct mdss_data_type *mdata)
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index 08c8b15d1632..0ca1396b4d5b 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -782,7 +782,7 @@ int mdss_mdp_pipe_program_pixel_extn(struct mdss_mdp_pipe *pipe);
int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable);
int mdss_mdp_wb_get_secure(struct msm_fb_data_type *mfd, uint8_t *enable);
void mdss_mdp_ctl_restore(struct mdss_mdp_ctl *ctl);
-void mdss_mdp_footswitch_ctrl_ulps(int on, struct device *dev);
+int mdss_mdp_footswitch_ctrl_ulps(int on, struct device *dev);
#define mfd_to_mdp5_data(mfd) (mfd->mdp.private1)
#define mfd_to_mdata(mfd) (((struct mdss_overlay_private *)\
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 5c6e5d3119b8..615f94606d1c 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -909,12 +909,15 @@ int mdss_mdp_overlay_get_buf(struct msm_fb_data_type *mfd,
int num_planes,
u32 flags)
{
- int i, rc = 0;
+ int i, rc;
if ((num_planes <= 0) || (num_planes > MAX_PLANES))
return -EINVAL;
- mdss_bus_bandwidth_ctrl(1);
+ rc = mdss_bus_bandwidth_ctrl(1);
+ if (rc)
+ goto end;
+
memset(data, 0, sizeof(*data));
for (i = 0; i < num_planes; i++) {
data->p[i].flags = flags;
@@ -932,21 +935,27 @@ int mdss_mdp_overlay_get_buf(struct msm_fb_data_type *mfd,
data->num_planes = i;
+end:
return rc;
}
int mdss_mdp_overlay_free_buf(struct mdss_mdp_data *data)
{
int i;
+ int rc;
+
+ rc = mdss_bus_bandwidth_ctrl(1);
+ if (rc)
+ goto end;
- mdss_bus_bandwidth_ctrl(1);
for (i = 0; i < data->num_planes && data->p[i].len; i++)
mdss_mdp_put_img(&data->p[i]);
mdss_bus_bandwidth_ctrl(0);
data->num_planes = 0;
- return 0;
+end:
+ return rc;
}
/**
@@ -1104,14 +1113,25 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
if (ctl->power_on) {
if (mdp5_data->mdata->ulps) {
- mdss_mdp_footswitch_ctrl_ulps(1, &mfd->pdev->dev);
+ rc = mdss_mdp_footswitch_ctrl_ulps(1, &mfd->pdev->dev);
+ if (rc) {
+ pr_err("footswtich control power on failed rc=%d\n",
+ rc);
+ goto end;
+ }
+
mdss_mdp_ctl_restore(ctl);
}
if (!mdp5_data->mdata->batfet)
mdss_mdp_batfet_ctrl(mdp5_data->mdata, true);
- if (!mfd->panel_info->cont_splash_enabled)
- mdss_iommu_attach(mdp5_data->mdata);
+ if (!mfd->panel_info->cont_splash_enabled) {
+ rc = mdss_iommu_attach(mdp5_data->mdata);
+ if (rc) {
+ pr_err("mdss iommu attach failed rc=%d\n", rc);
+ goto end;
+ }
+ }
mdss_mdp_release_splash_pipe(mfd);
return 0;
}
@@ -1121,7 +1141,7 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
rc = pm_runtime_get_sync(&mfd->pdev->dev);
if (IS_ERR_VALUE(rc)) {
pr_err("unable to resume with pm_runtime_get_sync rc=%d\n", rc);
- return rc;
+ goto end;
}
/*
@@ -1133,8 +1153,13 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
* we would have called in to TZ to restore security configs from LK.
*/
if (!is_mdss_iommu_attached()) {
- if (!mfd->panel_info->cont_splash_enabled)
- mdss_iommu_attach(mdss_res);
+ if (!mfd->panel_info->cont_splash_enabled) {
+ rc = mdss_iommu_attach(mdss_res);
+ if (rc) {
+ pr_err("mdss iommu attach failed rc=%d\n", rc);
+ goto pm_error;
+ }
+ }
mdss_hw_init(mdss_res);
}
@@ -1146,17 +1171,19 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
&mfd->mdp_sync_pt_data.notifier);
} else {
pr_err("mdp ctl start failed.\n");
- goto error;
+ goto ctl_error;
}
rc = mdss_mdp_splash_cleanup(mfd, true);
-error:
- if (rc) {
- mdss_mdp_ctl_destroy(ctl);
- mdp5_data->ctl = NULL;
- pm_runtime_put(&mfd->pdev->dev);
- }
-
+ if (!rc)
+ goto end;
+
+ctl_error:
+ mdss_mdp_ctl_destroy(ctl);
+ mdp5_data->ctl = NULL;
+pm_error:
+ pm_runtime_put(&mfd->pdev->dev);
+end:
return rc;
}
@@ -1545,8 +1572,13 @@ static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
flags = (pipe->flags & MDP_SECURE_OVERLAY_SESSION);
- if (!mfd->panel_info->cont_splash_enabled)
- mdss_iommu_attach(mdata);
+ if (!mfd->panel_info->cont_splash_enabled) {
+ ret = mdss_iommu_attach(mdata);
+ if (ret) {
+ pr_err("mdss iommu attach failed ret=%d\n", ret);
+ goto end;
+ }
+ }
src_data = &pipe->back_buf;
if (src_data->num_planes) {
@@ -1560,6 +1592,8 @@ static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
pr_err("src_data pmem error\n");
}
pipe->has_buf = 1;
+
+end:
mdss_mdp_pipe_unmap(pipe);
return ret;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_wb.c b/drivers/video/fbdev/msm/mdss_mdp_wb.c
index b91a486160b1..1d0e9362b0f4 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_wb.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_wb.c
@@ -491,8 +491,13 @@ static int mdss_mdp_wb_queue(struct msm_fb_data_type *mfd,
pr_debug("fb%d queue\n", wb->fb_ndx);
- if (!mfd->panel_info->cont_splash_enabled)
- mdss_iommu_attach(mdp5_data->mdata);
+ if (!mfd->panel_info->cont_splash_enabled) {
+ ret = mdss_iommu_attach(mdp5_data->mdata);
+ if (ret) {
+ pr_err("mdss iommu attach failed rc=%d", ret);
+ return ret;
+ }
+ }
mutex_lock(&wb->lock);
if (local)