Loading drivers/video/msm/mdss/mdss_mdp_rotator.c +95 −20 Original line number Diff line number Diff line Loading @@ -106,8 +106,11 @@ static struct mdss_mdp_pipe *mdss_mdp_rotator_pipe_alloc(void) if (!pipe) { mdss_mdp_wb_mixer_destroy(mixer); pr_debug("dma pipe allocation failed\n"); return NULL; } pipe->mixer_stage = MDSS_MDP_STAGE_UNUSED; return pipe; } Loading @@ -127,7 +130,6 @@ static int mdss_mdp_rotator_busy_wait(struct mdss_mdp_rotator_session *rot) if (ctl->shared_lock) mutex_unlock(ctl->shared_lock); } mdss_mdp_smp_release(rot->pipe); mutex_unlock(&rot->lock); return 0; Loading Loading @@ -169,7 +171,6 @@ static int mdss_mdp_rotator_pipe_dequeue(struct mdss_mdp_rotator_session *rot) if (rot->pipe) { pr_debug("use new rotator pipe=%d\n", rot->pipe->num); rot->pipe->mixer_stage = MDSS_MDP_STAGE_UNUSED; list_add_tail(&rot->head, &rotator_queue); } else if (!list_empty(&rotator_queue)) { tmp = list_first_entry(&rotator_queue, Loading Loading @@ -199,6 +200,45 @@ static int mdss_mdp_rotator_pipe_dequeue(struct mdss_mdp_rotator_session *rot) return 0; } /** * __mdss_mdp_rotator_to_pipe() - setup pipe according to rotator session params * @rot: Pointer to rotator session * @pipe: Pointer to pipe driving structure * * After calling this the pipe structure will contain all parameters required * to use rotator pipe. Note that this function assumes rotator pipe is idle. */ static int __mdss_mdp_rotator_to_pipe(struct mdss_mdp_rotator_session *rot, struct mdss_mdp_pipe *pipe) { int ret; pipe->flags = rot->flags; pipe->src_fmt = mdss_mdp_get_format_params(rot->format); pipe->img_width = rot->img_width; pipe->img_height = rot->img_height; pipe->src = rot->src_rect; pipe->dst = rot->src_rect; pipe->dst.x = 0; pipe->dst.y = 0; 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"); return ret; } return 0; } static int mdss_mdp_rotator_queue_sub(struct mdss_mdp_rotator_session *rot, struct mdss_mdp_data *src_data, struct mdss_mdp_data *dst_data) Loading Loading @@ -234,28 +274,17 @@ static int mdss_mdp_rotator_queue_sub(struct mdss_mdp_rotator_session *rot, } if (rot->params_changed || rot_ctl->mdata->mixer_switched) { rot->params_changed = 0; rot_pipe->flags = rot->flags; rot_pipe->src_fmt = mdss_mdp_get_format_params(rot->format); rot_pipe->img_width = rot->img_width; rot_pipe->img_height = rot->img_height; rot_pipe->src = rot->src_rect; rot_pipe->dst = rot->src_rect; rot_pipe->dst.x = 0; rot_pipe->dst.y = 0; rot_pipe->params_changed++; } ret = mdss_mdp_smp_reserve(rot->pipe); ret = __mdss_mdp_rotator_to_pipe(rot, rot_pipe); if (ret) { pr_err("unable to mdss_mdp_smp_reserve rot data\n"); pr_err("rotator session=%x to pipe=%d failed %d\n", rot->session_id, rot_pipe->num, ret); goto error; } } ret = mdss_mdp_pipe_queue_data(rot->pipe, src_data); ret = mdss_mdp_pipe_queue_data(rot_pipe, src_data); if (ret) { pr_err("unable to queue rot data\n"); mdss_mdp_smp_unreserve(rot->pipe); goto error; } Loading Loading @@ -373,6 +402,45 @@ static int mdss_mdp_rotator_queue(struct mdss_mdp_rotator_session *rot) return ret; } /* * Try to reserve hardware resources for rotator session if possible, if this * is not possible we may still have a chance to reuse existing pipes used by * other sessions at a later point. */ static int __mdss_mdp_rotator_pipe_reserve(struct mdss_mdp_rotator_session *rot) { int ret; if (!rot->pipe) { rot->pipe = mdss_mdp_rotator_pipe_alloc(); if (rot->pipe) { pr_debug("reserved rotator pipe=%d\n", rot->pipe->num); list_add_tail(&rot->head, &rotator_queue); } else { /* * if rotator queue is not empty means that we'll be * able to reuse existing rotator pipes for this rotator * session, otherwise it means that there are no DMA * pipes available so we should abort now */ if (list_empty(&rotator_queue)) { pr_err("unable to reserve rot pipe\n"); return -ENODEV; } pr_debug("unable to get rot pipe but some in queue\n"); return 0; } } ret = __mdss_mdp_rotator_to_pipe(rot, rot->pipe); if (ret) pr_err("rotator session=%x to pipe=%d failed %d\n", rot->session_id, rot->pipe->num, ret); return ret; } int mdss_mdp_rotator_setup(struct msm_fb_data_type *mfd, struct mdp_overlay *req) { Loading Loading @@ -532,6 +600,13 @@ int mdss_mdp_rotator_setup(struct msm_fb_data_type *mfd, rot->params_changed++; ret = __mdss_mdp_rotator_pipe_reserve(rot); if (!ret && rot->next) ret = __mdss_mdp_rotator_pipe_reserve(rot->next); if (ret) goto rot_err; req->id = rot->session_id; rot_err: Loading Loading
drivers/video/msm/mdss/mdss_mdp_rotator.c +95 −20 Original line number Diff line number Diff line Loading @@ -106,8 +106,11 @@ static struct mdss_mdp_pipe *mdss_mdp_rotator_pipe_alloc(void) if (!pipe) { mdss_mdp_wb_mixer_destroy(mixer); pr_debug("dma pipe allocation failed\n"); return NULL; } pipe->mixer_stage = MDSS_MDP_STAGE_UNUSED; return pipe; } Loading @@ -127,7 +130,6 @@ static int mdss_mdp_rotator_busy_wait(struct mdss_mdp_rotator_session *rot) if (ctl->shared_lock) mutex_unlock(ctl->shared_lock); } mdss_mdp_smp_release(rot->pipe); mutex_unlock(&rot->lock); return 0; Loading Loading @@ -169,7 +171,6 @@ static int mdss_mdp_rotator_pipe_dequeue(struct mdss_mdp_rotator_session *rot) if (rot->pipe) { pr_debug("use new rotator pipe=%d\n", rot->pipe->num); rot->pipe->mixer_stage = MDSS_MDP_STAGE_UNUSED; list_add_tail(&rot->head, &rotator_queue); } else if (!list_empty(&rotator_queue)) { tmp = list_first_entry(&rotator_queue, Loading Loading @@ -199,6 +200,45 @@ static int mdss_mdp_rotator_pipe_dequeue(struct mdss_mdp_rotator_session *rot) return 0; } /** * __mdss_mdp_rotator_to_pipe() - setup pipe according to rotator session params * @rot: Pointer to rotator session * @pipe: Pointer to pipe driving structure * * After calling this the pipe structure will contain all parameters required * to use rotator pipe. Note that this function assumes rotator pipe is idle. */ static int __mdss_mdp_rotator_to_pipe(struct mdss_mdp_rotator_session *rot, struct mdss_mdp_pipe *pipe) { int ret; pipe->flags = rot->flags; pipe->src_fmt = mdss_mdp_get_format_params(rot->format); pipe->img_width = rot->img_width; pipe->img_height = rot->img_height; pipe->src = rot->src_rect; pipe->dst = rot->src_rect; pipe->dst.x = 0; pipe->dst.y = 0; 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"); return ret; } return 0; } static int mdss_mdp_rotator_queue_sub(struct mdss_mdp_rotator_session *rot, struct mdss_mdp_data *src_data, struct mdss_mdp_data *dst_data) Loading Loading @@ -234,28 +274,17 @@ static int mdss_mdp_rotator_queue_sub(struct mdss_mdp_rotator_session *rot, } if (rot->params_changed || rot_ctl->mdata->mixer_switched) { rot->params_changed = 0; rot_pipe->flags = rot->flags; rot_pipe->src_fmt = mdss_mdp_get_format_params(rot->format); rot_pipe->img_width = rot->img_width; rot_pipe->img_height = rot->img_height; rot_pipe->src = rot->src_rect; rot_pipe->dst = rot->src_rect; rot_pipe->dst.x = 0; rot_pipe->dst.y = 0; rot_pipe->params_changed++; } ret = mdss_mdp_smp_reserve(rot->pipe); ret = __mdss_mdp_rotator_to_pipe(rot, rot_pipe); if (ret) { pr_err("unable to mdss_mdp_smp_reserve rot data\n"); pr_err("rotator session=%x to pipe=%d failed %d\n", rot->session_id, rot_pipe->num, ret); goto error; } } ret = mdss_mdp_pipe_queue_data(rot->pipe, src_data); ret = mdss_mdp_pipe_queue_data(rot_pipe, src_data); if (ret) { pr_err("unable to queue rot data\n"); mdss_mdp_smp_unreserve(rot->pipe); goto error; } Loading Loading @@ -373,6 +402,45 @@ static int mdss_mdp_rotator_queue(struct mdss_mdp_rotator_session *rot) return ret; } /* * Try to reserve hardware resources for rotator session if possible, if this * is not possible we may still have a chance to reuse existing pipes used by * other sessions at a later point. */ static int __mdss_mdp_rotator_pipe_reserve(struct mdss_mdp_rotator_session *rot) { int ret; if (!rot->pipe) { rot->pipe = mdss_mdp_rotator_pipe_alloc(); if (rot->pipe) { pr_debug("reserved rotator pipe=%d\n", rot->pipe->num); list_add_tail(&rot->head, &rotator_queue); } else { /* * if rotator queue is not empty means that we'll be * able to reuse existing rotator pipes for this rotator * session, otherwise it means that there are no DMA * pipes available so we should abort now */ if (list_empty(&rotator_queue)) { pr_err("unable to reserve rot pipe\n"); return -ENODEV; } pr_debug("unable to get rot pipe but some in queue\n"); return 0; } } ret = __mdss_mdp_rotator_to_pipe(rot, rot->pipe); if (ret) pr_err("rotator session=%x to pipe=%d failed %d\n", rot->session_id, rot->pipe->num, ret); return ret; } int mdss_mdp_rotator_setup(struct msm_fb_data_type *mfd, struct mdp_overlay *req) { Loading Loading @@ -532,6 +600,13 @@ int mdss_mdp_rotator_setup(struct msm_fb_data_type *mfd, rot->params_changed++; ret = __mdss_mdp_rotator_pipe_reserve(rot); if (!ret && rot->next) ret = __mdss_mdp_rotator_pipe_reserve(rot->next); if (ret) goto rot_err; req->id = rot->session_id; rot_err: Loading