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

Commit f17196e2 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: refactor pipe list management"

parents fbe4de39 1930d6db
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -491,7 +491,6 @@ static int mdss_fb_probe(struct platform_device *pdev)
	mfd->mdp = *mdp_instance;
	INIT_LIST_HEAD(&mfd->proc_list);

	mutex_init(&mfd->lock);
	mutex_init(&mfd->bl_lock);

	fbi_list[fbi_list_index++] = fbi;
+0 −1
Original line number Diff line number Diff line
@@ -199,7 +199,6 @@ struct msm_fb_data_type {
	u32 bl_updated;
	u32 bl_level_old;
	struct mutex bl_lock;
	struct mutex lock;

	struct platform_device *pdev;

+3 −2
Original line number Diff line number Diff line
@@ -406,8 +406,7 @@ struct mdss_mdp_pipe {
	struct mdss_mdp_data back_buf;
	struct mdss_mdp_data front_buf;

	struct list_head used_list;
	struct list_head cleanup_list;
	struct list_head list;

	struct mdp_overlay_pp_params pp_cfg;
	struct mdss_pipe_pp_res pp_res;
@@ -433,6 +432,8 @@ struct mdss_overlay_private {
	struct mutex ov_lock;
	struct mdss_mdp_ctl *ctl;
	struct mdss_mdp_wb *wb;

	struct mutex list_lock;
	struct list_head overlay_list;
	struct list_head pipes_used;
	struct list_head pipes_cleanup;
+55 −49
Original line number Diff line number Diff line
@@ -562,9 +562,9 @@ static int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
			return ret;
		}

		mutex_lock(&mfd->lock);
		list_add(&pipe->used_list, &mdp5_data->pipes_used);
		mutex_unlock(&mfd->lock);
		mutex_lock(&mdp5_data->list_lock);
		list_add(&pipe->list, &mdp5_data->pipes_used);
		mutex_unlock(&mdp5_data->list_lock);
		pipe->mixer_left = mixer;
		pipe->mfd = mfd;
		pipe->pid = current->tgid;
@@ -804,21 +804,21 @@ static int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
exit_fail:
	mdss_mdp_pipe_unmap(pipe);

	mutex_lock(&mfd->lock);
	mutex_lock(&mdp5_data->list_lock);
	if (pipe->play_cnt == 0) {
		pr_debug("failed for pipe %d\n", pipe->num);
		if (!list_empty(&pipe->used_list))
			list_del_init(&pipe->used_list);
		if (!list_empty(&pipe->list))
			list_del_init(&pipe->list);
		mdss_mdp_pipe_destroy(pipe);
	}

	/* invalidate any overlays in this framebuffer after failure */
	list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
	list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
		pr_debug("freeing allocations for pipe %d\n", pipe->num);
		mdss_mdp_smp_unreserve(pipe);
		pipe->params_changed = 0;
	}
	mutex_unlock(&mfd->lock);
	mutex_unlock(&mdp5_data->list_lock);
	return ret;
}

@@ -950,10 +950,9 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd)
	bool recovery_mode = false;
	LIST_HEAD(destroy_pipes);

	mutex_lock(&mfd->lock);
	list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_cleanup,
				cleanup_list) {
		list_move(&pipe->cleanup_list, &destroy_pipes);
	mutex_lock(&mdp5_data->list_lock);
	list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_cleanup, list) {
		list_move(&pipe->list, &destroy_pipes);

		/* make sure pipe fetch has been halted before freeing buffer */
		if (mdss_mdp_pipe_fetch_halt(pipe)) {
@@ -981,7 +980,7 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd)

	__mdss_mdp_overlay_free_list_purge(mfd);

	list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
	list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
		if (pipe->back_buf.num_planes) {
			/* make back buffer active */
			__mdss_mdp_overlay_free_list_add(mfd, &pipe->front_buf);
@@ -989,7 +988,7 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd)
		}
	}

	list_for_each_entry_safe(pipe, tmp, &destroy_pipes, cleanup_list) {
	list_for_each_entry_safe(pipe, tmp, &destroy_pipes, list) {
		/*
		 * in case of secure UI, the buffer needs to be released as
		 * soon as session is closed.
@@ -999,10 +998,10 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd)
		else
			__mdss_mdp_overlay_free_list_add(mfd, &pipe->front_buf);
		mdss_mdp_overlay_free_buf(&pipe->back_buf);
		list_del_init(&pipe->cleanup_list);
		list_del_init(&pipe->list);
		mdss_mdp_pipe_destroy(pipe);
	}
	mutex_unlock(&mfd->lock);
	mutex_unlock(&mdp5_data->list_lock);
}

static void __mdss_mdp_handoff_cleanup_pipes(struct msm_fb_data_type *mfd,
@@ -1035,8 +1034,7 @@ static void __mdss_mdp_handoff_cleanup_pipes(struct msm_fb_data_type *mfd,
		pipe = &pipes[i];
		if (pipe->is_handed_off) {
			pr_debug("Unmapping handed off pipe %d\n", pipe->num);
			list_add(&pipe->cleanup_list,
				&mdp5_data->pipes_cleanup);
			list_add(&pipe->list, &mdp5_data->pipes_cleanup);
			mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left);
			pipe->is_handed_off = false;
		}
@@ -1177,7 +1175,7 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
	struct mdss_mdp_ctl *tmp;
	int ret = 0;

	list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
	list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
		struct mdss_mdp_data *buf;
		/*
		 * When secure display is enabled, if there is a non secure
@@ -1270,12 +1268,12 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
		mutex_lock(ctl->shared_lock);

	mutex_lock(&mdp5_data->ov_lock);
	mutex_lock(&mfd->lock);
	mutex_lock(&mdp5_data->list_lock);

	/*
	 * check if there is a secure display session
	 */
	list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
	list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
		if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
			sd_in_pipe = 1;
			pr_debug("Secure pipe: %u : %08X\n",
@@ -1301,21 +1299,20 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	 * Setup pipe in solid fill before unstaging,
	 * to ensure no fetches are happening after dettach or reattach.
	 */
	list_for_each_entry(pipe, &mdp5_data->pipes_cleanup, cleanup_list) {
	list_for_each_entry(pipe, &mdp5_data->pipes_cleanup, list) {
		mdss_mdp_pipe_queue_data(pipe, NULL);
		mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left);
		mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right);
	}

	ret = __overlay_queue_pipes(mfd);
	mutex_unlock(&mdp5_data->list_lock);

	if (mfd->panel.type == WRITEBACK_PANEL)
		ret = mdss_mdp_wb_kickoff(mfd);
	else
		ret = mdss_mdp_display_commit(mdp5_data->ctl, NULL);

	mutex_unlock(&mfd->lock);

	if (IS_ERR_VALUE(ret))
		goto commit_fail;

@@ -1324,13 +1321,11 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	ret = mdss_mdp_display_wait4comp(mdp5_data->ctl);

	if (ret == 0) {
		mutex_lock(&mfd->lock);
		if (!mdp5_data->sd_enabled && sd_in_pipe) {
			ret = mdss_mdp_overlay_sd_ctrl(mfd, 1);
			if (ret == 0)
				mdp5_data->sd_enabled = 1;
		}
		mutex_unlock(&mfd->lock);
	}

	mdss_fb_update_notify_update(mfd);
@@ -1348,37 +1343,47 @@ commit_fail:

static int mdss_mdp_overlay_release(struct msm_fb_data_type *mfd, int ndx)
{
	struct mdss_mdp_pipe *pipe;
	struct mdss_mdp_pipe *pipe, *tmp;
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
	u32 pipe_ndx, unset_ndx = 0;
	int i, destroy_pipe;

	for (i = 0; unset_ndx != ndx && i < MDSS_MDP_MAX_SSPP; i++) {
		pipe_ndx = BIT(i);
		if (pipe_ndx & ndx) {
			unset_ndx |= pipe_ndx;
			pipe = mdss_mdp_pipe_get(mdp5_data->mdata, pipe_ndx);
			if (IS_ERR_OR_NULL(pipe)) {
				pr_warn("unknown pipe ndx=%x\n", pipe_ndx);
	u32 unset_ndx = 0;
	int destroy_pipe;

	mutex_lock(&mdp5_data->list_lock);
	list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
		if (pipe->ndx & ndx) {
			if (mdss_mdp_pipe_map(pipe)) {
				pr_err("Unable to map used pipe%d ndx=%x\n",
						pipe->num, pipe->ndx);
				continue;
			}

			mutex_lock(&mfd->lock);
			unset_ndx |= ndx;

			pipe->pid = 0;
			destroy_pipe = pipe->play_cnt == 0;

			if (!list_empty(&pipe->used_list)) {
				list_del_init(&pipe->used_list);
				if (!destroy_pipe)
					list_add(&pipe->cleanup_list,
			if (destroy_pipe)
				list_del_init(&pipe->list);
			else
				list_move(&pipe->list,
						&mdp5_data->pipes_cleanup);
			}
			mutex_unlock(&mfd->lock);

			mdss_mdp_pipe_unmap(pipe);
			if (destroy_pipe)
				mdss_mdp_pipe_destroy(pipe);

			if (unset_ndx == ndx)
				break;
		}
	}
	mutex_unlock(&mdp5_data->list_lock);

	if (unset_ndx != ndx) {
		pr_warn("Unable to unset pipe(s) ndx=0x%x unset=0x%x\n",
				ndx, unset_ndx);
		return -ENOENT;
	}

	return 0;
}

@@ -1446,8 +1451,8 @@ static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd,
	pr_debug("releasing all resources for fb%d pid=%d\n", mfd->index, pid);

	mutex_lock(&mdp5_data->ov_lock);
	mutex_lock(&mfd->lock);
	list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
	mutex_lock(&mdp5_data->list_lock);
	list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
		if (release_all || (pipe->pid == pid)) {
			unset_ndx |= pipe->ndx;
			cnt++;
@@ -1463,7 +1468,7 @@ static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd,
	pr_debug("release_all=%d mfd->ref_cnt=%d unset_ndx=0x%x cnt=%d\n",
		release_all, mfd->ref_cnt, unset_ndx, cnt);

	mutex_unlock(&mfd->lock);
	mutex_unlock(&mdp5_data->list_lock);

	if (unset_ndx) {
		pr_debug("%d pipes need cleanup (%x)\n", cnt, unset_ndx);
@@ -3096,9 +3101,9 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
	if (mixer)
		mixer->cursor_enabled = 0;

	mutex_lock(&mfd->lock);
	mutex_lock(&mdp5_data->list_lock);
	need_cleanup = !list_empty(&mdp5_data->pipes_cleanup);
	mutex_unlock(&mfd->lock);
	mutex_unlock(&mdp5_data->list_lock);

	if (need_cleanup) {
		pr_debug("cleaning up pipes on fb%d\n", mfd->index);
@@ -3452,6 +3457,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
	INIT_LIST_HEAD(&mdp5_data->pipes_used);
	INIT_LIST_HEAD(&mdp5_data->pipes_cleanup);
	INIT_LIST_HEAD(&mdp5_data->rot_proc_list);
	mutex_init(&mdp5_data->list_lock);
	mutex_init(&mdp5_data->ov_lock);
	mdp5_data->hw_refresh = true;
	mdp5_data->overlay_play_enable = true;
+6 −6
Original line number Diff line number Diff line
@@ -1686,18 +1686,18 @@ int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)

	/* TODO: have some sort of reader/writer lock to prevent unclocked
	 * access while display power is toggled */
	if (!ctl->mfd->panel_power_on) {
	mutex_lock(&ctl->lock);
	if (!ctl->power_on) {
		ret = -EPERM;
		goto error;
	}
	mutex_lock(&ctl->mfd->lock);
	ret = mdss_mdp_pp_setup_locked(ctl);
	mutex_unlock(&ctl->mfd->lock);
error:
	mutex_unlock(&ctl->lock);

	return ret;
}

/* call only when holding and mfd->lock */
int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
{
	struct mdss_data_type *mdata = ctl->mdata;
@@ -4768,10 +4768,10 @@ static void pp_ad_calc_worker(struct work_struct *work)
		ctl->remove_vsync_handler(ctl, &ad->handle);
	}
	mutex_unlock(&ad->lock);
	mutex_lock(&mfd->lock);
	/* dspp3 doesn't have ad attached to it so following is safe */
	mutex_lock(&ctl->lock);
	ctl->flush_bits |= BIT(13 + ad->num);
	mutex_unlock(&mfd->lock);
	mutex_unlock(&ctl->lock);

	/* Trigger update notify to wake up those waiting for display updates */
	mdss_fb_update_notify_update(bl_mfd);