summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorAdrian Salido-Moreno <adrianm@codeaurora.org>2012-11-14 22:28:23 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:13:22 -0700
commit8828d8d33f25faca795c627f24cfbef137769bef (patch)
tree4f73f223e8e8062bb15350be137ea635a94962bf /drivers/video/fbdev
parent0dc94c0e3b74494492fd5e0025707846eec8485c (diff)
msm: mdss: release rotator sessions when all panels are suspended
When all panels are suspended MDP will be shutdown, need to ensure that all rotator sessions are finished and properly closed to avoid access to MDP hw. CRs-Fixed: 409234 Change-Id: Ic1d95365a28c453ec8779d9c482a885857bf6912 Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c51
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_rotator.c54
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_rotator.h5
3 files changed, 79 insertions, 31 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index e043da2baf7d..ca8b2f98e83f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -29,6 +29,8 @@
#define CHECK_BOUNDS(offset, size, max_size) \
(((size) > (max_size)) || ((offset) > ((max_size) - (size))))
+static atomic_t ov_active_panels = ATOMIC_INIT(0);
+
static int mdss_mdp_overlay_get(struct msm_fb_data_type *mfd,
struct mdp_overlay *req)
{
@@ -488,19 +490,6 @@ static int mdss_mdp_overlay_release(struct msm_fb_data_type *mfd, int ndx)
u32 pipe_ndx, unset_ndx = 0;
int i;
- if (ndx & MDSS_MDP_ROT_SESSION_MASK) {
- struct mdss_mdp_rotator_session *rot;
- rot = mdss_mdp_rotator_session_get(ndx);
- if (rot) {
- mdss_mdp_rotator_finish(rot);
- } else {
- pr_warn("unknown session id=%x\n", ndx);
- return -ENODEV;
- }
-
- return 0;
- }
-
for (i = 0; unset_ndx != ndx && i < MDSS_MDP_MAX_SSPP; i++) {
pipe_ndx = BIT(i);
if (pipe_ndx & ndx) {
@@ -538,7 +527,10 @@ static int mdss_mdp_overlay_unset(struct msm_fb_data_type *mfd, int ndx)
pr_debug("unset ndx=%x\n", ndx);
- ret = mdss_mdp_overlay_release(mfd, ndx);
+ if (ndx & MDSS_MDP_ROT_SESSION_MASK)
+ ret = mdss_mdp_rotator_release(ndx);
+ else
+ ret = mdss_mdp_overlay_release(mfd, ndx);
mutex_unlock(&mfd->ov_lock);
@@ -593,6 +585,12 @@ static int mdss_mdp_overlay_rotate(struct msm_fb_data_type *mfd,
struct mdss_mdp_data src_data, dst_data;
int ret;
+ rot = mdss_mdp_rotator_session_get(req->id);
+ if (!rot) {
+ pr_err("invalid session id=%x\n", req->id);
+ return -ENOENT;
+ }
+
ret = mdss_mdp_overlay_get_buf(mfd, &src_data, &req->data, 1);
if (ret) {
pr_err("src_data pmem error\n");
@@ -605,13 +603,6 @@ static int mdss_mdp_overlay_rotate(struct msm_fb_data_type *mfd,
goto rotate_done;
}
- rot = mdss_mdp_rotator_session_get(req->id);
- if (!rot) {
- pr_err("invalid session id=%x\n", req->id);
- ret = -ENODEV;
- goto rotate_done;
- }
-
ret = mdss_mdp_rotator_queue(rot, &src_data, &dst_data);
if (ret) {
pr_err("rotator queue error session id=%x\n", req->id);
@@ -1127,14 +1118,28 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
{
- return mdss_mdp_ctl_on(mfd);
+ int rc;
+
+ rc = mdss_mdp_ctl_on(mfd);
+ if (rc == 0)
+ atomic_inc(&ov_active_panels);
+
+ return rc;
}
static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
{
+ int rc;
+
mdss_mdp_overlay_release_all(mfd);
- return mdss_mdp_ctl_off(mfd);
+ rc = mdss_mdp_ctl_off(mfd);
+ if (rc == 0) {
+ if (atomic_dec_return(&ov_active_panels) == 0)
+ mdss_mdp_rotator_release_all();
+ }
+
+ return rc;
}
int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
diff --git a/drivers/video/fbdev/msm/mdss_mdp_rotator.c b/drivers/video/fbdev/msm/mdss_mdp_rotator.c
index a5d072b2ae58..647fddc0eb30 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_rotator.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_rotator.c
@@ -187,12 +187,17 @@ int mdss_mdp_rotator_queue(struct mdss_mdp_rotator_session *rot,
{
struct mdss_mdp_pipe *rot_pipe;
struct mdss_mdp_ctl *ctl;
- int ret;
+ int ret, need_wait = false;
- if (!rot)
+ ret = mutex_lock_interruptible(&rotator_lock);
+ if (ret)
+ return ret;
+
+ if (!rot || !rot->ref_cnt) {
+ mutex_unlock(&rotator_lock);
return -ENODEV;
+ }
- mutex_lock(&rotator_lock);
ret = mdss_mdp_rotator_pipe_dequeue(rot);
if (ret) {
pr_err("unable to acquire rotator\n");
@@ -225,16 +230,18 @@ int mdss_mdp_rotator_queue(struct mdss_mdp_rotator_session *rot,
ret = mdss_mdp_rotator_kickoff(ctl, rot, dst_data);
+ if (ret == 0 && !rot->no_wait)
+ need_wait = true;
done:
mutex_unlock(&rotator_lock);
- if (!rot->no_wait)
+ if (need_wait)
mdss_mdp_rotator_busy_wait(rot);
return ret;
}
-int mdss_mdp_rotator_finish(struct mdss_mdp_rotator_session *rot)
+static int mdss_mdp_rotator_finish(struct mdss_mdp_rotator_session *rot)
{
struct mdss_mdp_pipe *rot_pipe;
@@ -243,7 +250,6 @@ int mdss_mdp_rotator_finish(struct mdss_mdp_rotator_session *rot)
pr_debug("finish rot id=%x\n", rot->session_id);
- mutex_lock(&rotator_lock);
rot_pipe = rot->pipe;
if (rot_pipe) {
mdss_mdp_rotator_busy_wait(rot);
@@ -255,7 +261,43 @@ int mdss_mdp_rotator_finish(struct mdss_mdp_rotator_session *rot)
mdss_mdp_pipe_destroy(rot_pipe);
mdss_mdp_wb_mixer_destroy(mixer);
}
+
+ return 0;
+}
+
+int mdss_mdp_rotator_release(u32 ndx)
+{
+ struct mdss_mdp_rotator_session *rot;
+ mutex_lock(&rotator_lock);
+ rot = mdss_mdp_rotator_session_get(ndx);
+ if (rot) {
+ mdss_mdp_rotator_finish(rot);
+ } else {
+ pr_warn("unknown session id=%x\n", ndx);
+ return -ENOENT;
+ }
+ mutex_unlock(&rotator_lock);
+
+ return 0;
+}
+
+int mdss_mdp_rotator_release_all(void)
+{
+ struct mdss_mdp_rotator_session *rot;
+ int i, cnt;
+
+ mutex_lock(&rotator_lock);
+ for (i = 0, cnt = 0; i < MAX_ROTATOR_SESSIONS; i++) {
+ rot = &rotator_session[i];
+ if (rot->ref_cnt) {
+ mdss_mdp_rotator_finish(rot);
+ cnt++;
+ }
+ }
mutex_unlock(&rotator_lock);
+ if (cnt)
+ pr_debug("cleaned up %d rotator sessions\n", cnt);
+
return 0;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_rotator.h b/drivers/video/fbdev/msm/mdss_mdp_rotator.h
index c09db6fb7767..cc4e3393df36 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_rotator.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_rotator.h
@@ -48,7 +48,8 @@ struct mdss_mdp_rotator_session *mdss_mdp_rotator_session_get(u32 session_id);
int mdss_mdp_rotator_queue(struct mdss_mdp_rotator_session *rot,
struct mdss_mdp_data *src_data,
struct mdss_mdp_data *dst_data);
-int mdss_mdp_rotator_finish(struct mdss_mdp_rotator_session *rot);
-int mdss_mdp_rotator_ctl_busy_wait(struct mdss_mdp_ctl *ctl);
+
+int mdss_mdp_rotator_release(u32 ndx);
+int mdss_mdp_rotator_release_all(void);
#endif /* MDSS_MDP_ROTATOR_H */