summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdp3_ctrl.c84
-rw-r--r--drivers/video/fbdev/msm/mdp3_ctrl.h1
2 files changed, 84 insertions, 1 deletions
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index 03dc4d9c8b57..2b0b966d6c2a 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -481,12 +481,13 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd)
pr_err("fail to start the MDP display interface\n");
goto on_error;
}
+ } else {
+ mdp3_session->first_commit = true;
}
on_error:
if (!rc)
mdp3_session->status = 1;
-
mutex_unlock(&mdp3_session->lock);
return rc;
}
@@ -557,6 +558,57 @@ off_error:
return 0;
}
+static int mdp3_ctrl_reset_cmd(struct msm_fb_data_type *mfd)
+{
+ int rc = 0;
+ struct mdp3_session_data *mdp3_session;
+ struct mdp3_dma *mdp3_dma;
+ struct mdss_panel_data *panel;
+ struct mdp3_vsync_notification vsync_client;
+
+ pr_debug("mdp3_ctrl_reset_cmd\n");
+ mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
+ if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma ||
+ !mdp3_session->intf) {
+ pr_err("mdp3_ctrl_reset no device");
+ return -ENODEV;
+ }
+
+ panel = mdp3_session->panel;
+ mdp3_dma = mdp3_session->dma;
+ mutex_lock(&mdp3_session->lock);
+
+ vsync_client = mdp3_dma->vsync_client;
+
+ rc = mdp3_dma->stop(mdp3_dma, mdp3_session->intf);
+ if (rc) {
+ pr_err("fail to stop the MDP3 dma\n");
+ goto reset_error;
+ }
+
+ rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
+ if (rc) {
+ pr_err("fail to attach dma iommu\n");
+ goto reset_error;
+ }
+
+ mdp3_ctrl_intf_init(mfd, mdp3_session->intf);
+ mdp3_ctrl_dma_init(mfd, mdp3_dma);
+
+ if (vsync_client.handler)
+ mdp3_dma->vsync_enable(mdp3_dma, &vsync_client);
+
+ if (mfd->fbi->screen_base)
+ rc = mdp3_dma->start(mdp3_dma, mdp3_session->intf);
+ else
+ mdp3_session->first_commit = true;
+
+reset_error:
+ mutex_unlock(&mdp3_session->lock);
+ return rc;
+}
+
+
static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd)
{
int rc = 0;
@@ -573,6 +625,11 @@ static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd)
return -ENODEV;
}
+ if (mfd->panel.type == MIPI_CMD_PANEL) {
+ rc = mdp3_ctrl_reset_cmd(mfd);
+ return rc;
+ }
+
panel = mdp3_session->panel;
mdp3_dma = mdp3_session->dma;
mutex_lock(&mdp3_session->lock);
@@ -633,6 +690,8 @@ static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd)
if (mfd->fbi->screen_base)
rc = mdp3_dma->start(mdp3_dma, mdp3_session->intf);
+ else
+ mdp3_session->first_commit = true;
reset_error:
mutex_unlock(&mdp3_session->lock);
@@ -747,6 +806,7 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,
{
struct mdp3_session_data *mdp3_session;
struct mdp3_img_data *data;
+ struct mdss_panel_info *panel_info = mfd->panel_info;
int rc = 0;
if (!mfd || !mfd->mdp.private1)
@@ -756,6 +816,11 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,
if (!mdp3_session || !mdp3_session->dma)
return -EINVAL;
+ if (mdp3_bufq_count(&mdp3_session->bufq_in) == 0) {
+ pr_debug("no buffer in queue yet\n");
+ return -EPERM;
+ }
+
if (!mdp3_iommu_is_attached(MDP3_CLIENT_DMA_P)) {
pr_debug("continuous splash screen, IOMMU not attached\n");
mdp3_ctrl_reset(mfd);
@@ -782,6 +847,13 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,
data = mdp3_bufq_pop(&mdp3_session->bufq_out);
mdp3_put_img(data, MDP3_CLIENT_DMA_P);
}
+
+ if (mdp3_session->first_commit) {
+ /*wait for one frame time to ensure frame is sent to panel*/
+ msleep(1000 / panel_info->mipi.frame_rate);
+ mdp3_session->first_commit = false;
+ }
+
mutex_unlock(&mdp3_session->lock);
mdss_fb_update_notify_update(mfd);
@@ -795,6 +867,7 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
struct mdp3_session_data *mdp3_session;
u32 offset;
int bpp;
+ struct mdss_panel_info *panel_info = mfd->panel_info;
pr_debug("mdp3_ctrl_pan_display\n");
if (!mfd || !mfd->mdp.private1)
@@ -809,6 +882,8 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
mdp3_ctrl_reset(mfd);
}
+ mdp3_release_splash_memory();
+
mutex_lock(&mdp3_session->lock);
if (!mdp3_session->status) {
@@ -836,6 +911,13 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
pr_debug("mdp3_ctrl_pan_display no memory, stop interface");
mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
}
+
+ if (mdp3_session->first_commit) {
+ /*wait for one frame time to ensure frame is sent to panel*/
+ msleep(1000 / panel_info->mipi.frame_rate);
+ mdp3_session->first_commit = false;
+ }
+
pan_error:
mutex_unlock(&mdp3_session->lock);
}
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.h b/drivers/video/fbdev/msm/mdp3_ctrl.h
index eb32797ec058..7c4f6ac7eb44 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.h
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.h
@@ -51,6 +51,7 @@ struct mdp3_session_data {
struct mutex histo_lock;
int lut_sel;
int cc_vect_sel;
+ bool first_commit;
};
int mdp3_ctrl_init(struct msm_fb_data_type *mfd);