Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b8dcd40 authored by Adrian Salido-Moreno's avatar Adrian Salido-Moreno Committed by Gerrit - the friendly Code Review server
Browse files

msm: mdss: move rotator SMP reservation to rotator setup



Shared memory pool (SMP) blocks are limited, in some cases where there
are many overlay pipes used, we may not be able to get enough blocks for
rotator sessions. In such cases fall-back solution must be considered,
however for this to happen this would need to be identified during
rotator session setup. Move logic to do pipe resource reservation in
rotator setup if possible.

Change-Id: I223281fb51b81baf852cac415a8c61c0de35c2c4
Signed-off-by: default avatarAdrian Salido-Moreno <adrianm@codeaurora.org>
parent 89f15268
Loading
Loading
Loading
Loading
+95 −20
Original line number Diff line number Diff line
@@ -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;
}

@@ -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;
@@ -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,
@@ -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)
@@ -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;
	}

@@ -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)
{
@@ -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: