diff options
| author | Mayank Chopra <makchopra@codeaurora.org> | 2013-11-26 20:42:11 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:25:53 -0700 |
| commit | 330f310c6b7ef499eaa8d98f7d4ed55380c3ce2f (patch) | |
| tree | bb3fe374456d7eb43258a779db05936fab2f5c0d | |
| parent | 97ab5f3924d737a9a32f33aaaece4cfea3e6aae3 (diff) | |
msm: mdss: Check extra mmb allocated to a pipe
If set call to a pipe changes smp configuration such that
calculated no. of mmb blocks are less than allocated mmb
blocks, fail this set call. This ensures pipe disconnection
and smp configuration is possible in next commit cycle.
Also, check that no extra mmb is left allocated to any plane
when pipe's format changes. If so, fail the set call to let
correct smp configuration happen in next commit cycle.
Change-Id: Iec2b8cb18088587655cf0c68dc81e3ac7b819cbc
Signed-off-by: Mayank Chopra <makchopra@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 34 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_rotator.c | 6 |
3 files changed, 32 insertions, 14 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 64d9a63b06c0..7c1234c09f48 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -611,12 +611,6 @@ static int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, !mdp5_data->mdata->has_wfd_blk) mdss_mdp_smp_release(pipe); - /* - * Clear previous SMP reservations and reserve according to the - * latest configuration - */ - mdss_mdp_smp_unreserve(pipe); - ret = mdss_mdp_smp_reserve(pipe); if (ret) { pr_debug("mdss_mdp_smp_reserve failed. ret=%d\n", ret); diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index b97e2eca087f..45b211a58fcd 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -32,6 +32,8 @@ static DEFINE_MUTEX(mdss_mdp_sspp_lock); static DEFINE_MUTEX(mdss_mdp_smp_lock); static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe); +static int mdss_mdp_smp_mmb_set(int client_id, unsigned long *smp); +static void mdss_mdp_smp_mmb_free(unsigned long *smp, bool write); static struct mdss_mdp_pipe *mdss_mdp_pipe_search_by_client_id( struct mdss_data_type *mdata, int client_id); @@ -58,8 +60,27 @@ static u32 mdss_mdp_smp_mmb_reserve(struct mdss_mdp_pipe_smp_map *smp_map, else n -= fixed_cnt; - /* reserve more blocks if needed, but can't free mmb at this point */ - for (i = bitmap_weight(smp_map->allocated, SMP_MB_CNT); i < n; i++) { + i = bitmap_weight(smp_map->allocated, SMP_MB_CNT); + + /* + * SMP programming is not double buffered. Fail the request, + * that calls for change in smp configuration (addition/removal + * of smp blocks), so that fallback solution happens. + */ + if (i != 0 && n != i) { + pr_debug("Can't change mmb config, num_blks: %d alloc: %d\n", + n, i); + return 0; + } + + /* + * Clear previous SMP reservations and reserve according to the + * latest configuration + */ + mdss_mdp_smp_mmb_free(smp_map->reserved, false); + + /* Reserve mmb blocks*/ + for (; i < n; i++) { if (bitmap_full(mdata->mmb_alloc_map, SMP_MB_CNT)) break; @@ -280,6 +301,15 @@ int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe) wb_mixer = 1; mutex_lock(&mdss_mdp_smp_lock); + for (i = (MAX_PLANES - 1); i >= ps.num_planes; i--) { + if (bitmap_weight(pipe->smp_map[i].allocated, SMP_MB_CNT)) { + pr_debug("Extra mmb identified for pnum=%d plane=%d\n", + pipe->num, i); + mutex_unlock(&mdss_mdp_smp_lock); + return -EAGAIN; + } + } + for (i = 0; i < ps.num_planes; i++) { if (rot_mode || wb_mixer) { num_blks = 1; diff --git a/drivers/video/fbdev/msm/mdss_mdp_rotator.c b/drivers/video/fbdev/msm/mdss_mdp_rotator.c index 5dc18f7d7316..66ed0f560132 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_rotator.c +++ b/drivers/video/fbdev/msm/mdss_mdp_rotator.c @@ -225,12 +225,6 @@ static int __mdss_mdp_rotator_to_pipe(struct mdss_mdp_rotator_session *rot, pipe->params_changed++; rot->params_changed = 0; - /* - * Clear previous SMP reservations and reserve according - * to the latest configuration - */ - mdss_mdp_smp_unreserve(pipe); - ret = mdss_mdp_smp_reserve(pipe); if (ret) { pr_err("unable to mdss_mdp_smp_reserve rot data\n"); |
