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

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

Merge "fbdev: msm: use sync_file interface for fence"

parents 1bea31ab 2b6d004b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ ifeq ($(CONFIG_FB_MSM_MDSS_MDP3), y)
ccflags-y += -DTARGET_HW_MDSS_MDP3
endif
mdss-mdp-objs := mdss_mdp.o mdss_mdp_ctl.o mdss_mdp_pipe.o mdss_mdp_util.o dsi_status_6g.o
mdss-mdp-objs += mdss_mdp_pp.o mdss_mdp_pp_debug.o mdss_mdp_pp_cache_config.o
mdss-mdp-objs += mdss_mdp_pp.o mdss_mdp_pp_debug.o mdss_mdp_pp_cache_config.o mdss_sync.o
mdss-mdp-objs += mdss_mdp_intf_video.o
mdss-mdp-objs += mdss_mdp_intf_cmd.o
mdss-mdp-objs += mdss_mdp_intf_writeback.o
+38 −40
Original line number Diff line number Diff line
@@ -43,8 +43,6 @@
#include <linux/uaccess.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/sync.h>
#include <linux/sw_sync.h>
#include <linux/file.h>
#include <linux/kthread.h>
#include <linux/dma-buf.h>
@@ -55,6 +53,7 @@
#include "mdss_smmu.h"
#include "mdss_mdp.h"
#include "mdp3_ctrl.h"
#include "mdss_sync.h"

#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
#define MDSS_FB_NUM 3
@@ -1311,12 +1310,20 @@ static int mdss_fb_probe(struct platform_device *pdev)

	mfd->mdp_sync_pt_data.fence_name = "mdp-fence";
	if (mfd->mdp_sync_pt_data.timeline == NULL) {
		char timeline_name[16];
		char timeline_name[32];

		snprintf(timeline_name, sizeof(timeline_name),
			"mdss_fb_%d", mfd->index);
		 mfd->mdp_sync_pt_data.timeline =
				sw_sync_timeline_create(timeline_name);
				mdss_create_timeline(timeline_name);
		if (mfd->mdp_sync_pt_data.timeline == NULL) {
			pr_err("cannot create release fence time line\n");
			return -ENOMEM;
		}
		snprintf(timeline_name, sizeof(timeline_name),
			"mdss_fb_%d_retire", mfd->index);
		 mfd->mdp_sync_pt_data.timeline_retire =
				mdss_create_timeline(timeline_name);
		if (mfd->mdp_sync_pt_data.timeline == NULL) {
			pr_err("cannot create release fence time line\n");
			return -ENOMEM;
@@ -2871,7 +2878,7 @@ static void mdss_fb_power_setting_idle(struct msm_fb_data_type *mfd)
}

static void __mdss_fb_copy_fence(struct msm_sync_pt_data *sync_pt_data,
	struct sync_fence **fences, u32 *fence_cnt)
	struct mdss_fence **fences, u32 *fence_cnt)
{
	pr_debug("%s: wait for fences\n", sync_pt_data->fence_name);

@@ -2884,12 +2891,12 @@ static void __mdss_fb_copy_fence(struct msm_sync_pt_data *sync_pt_data,
	sync_pt_data->acq_fen_cnt = 0;
	if (*fence_cnt)
		memcpy(fences, sync_pt_data->acq_fen,
				*fence_cnt * sizeof(struct sync_fence *));
				*fence_cnt * sizeof(struct mdss_fence *));
	mutex_unlock(&sync_pt_data->sync_mutex);
}

static int __mdss_fb_wait_for_fence_sub(struct msm_sync_pt_data *sync_pt_data,
	struct sync_fence **fences, int fence_cnt)
	struct mdss_fence **fences, int fence_cnt)
{
	int i, ret = 0;
	unsigned long max_wait = msecs_to_jiffies(WAIT_MAX_FENCE_TIMEOUT);
@@ -2913,7 +2920,7 @@ static int __mdss_fb_wait_for_fence_sub(struct msm_sync_pt_data *sync_pt_data,
			wait_ms = min_t(long, WAIT_FENCE_FIRST_TIMEOUT,
					wait_ms);

		ret = sync_fence_wait(fences[i], wait_ms);
		ret = mdss_wait_sync_fence(fences[i], wait_ms);

		if (ret == -ETIME) {
			wait_jf = timeout - jiffies;
@@ -2925,31 +2932,31 @@ static int __mdss_fb_wait_for_fence_sub(struct msm_sync_pt_data *sync_pt_data,
						wait_ms);

			pr_warn("%s: sync_fence_wait timed out! ",
					fences[i]->name);
					mdss_get_sync_fence_name(fences[i]));
			pr_cont("Waiting %ld.%ld more seconds\n",
				(wait_ms/MSEC_PER_SEC), (wait_ms%MSEC_PER_SEC));
			MDSS_XLOG(sync_pt_data->timeline_value);
			MDSS_XLOG_TOUT_HANDLER("mdp");
			ret = sync_fence_wait(fences[i], wait_ms);
			ret = mdss_wait_sync_fence(fences[i], wait_ms);

			if (ret == -ETIME)
				break;
		}
		sync_fence_put(fences[i]);
		mdss_put_sync_fence(fences[i]);
	}

	if (ret < 0) {
		pr_err("%s: sync_fence_wait failed! ret = %x\n",
				sync_pt_data->fence_name, ret);
		for (; i < fence_cnt; i++)
			sync_fence_put(fences[i]);
			mdss_put_sync_fence(fences[i]);
	}
	return ret;
}

int mdss_fb_wait_for_fence(struct msm_sync_pt_data *sync_pt_data)
{
	struct sync_fence *fences[MDP_MAX_FENCE_FD];
	struct mdss_fence *fences[MDP_MAX_FENCE_FD];
	int fence_cnt = 0;

	__mdss_fb_copy_fence(sync_pt_data, fences, &fence_cnt);
@@ -2974,7 +2981,8 @@ void mdss_fb_signal_timeline(struct msm_sync_pt_data *sync_pt_data)
	mutex_lock(&sync_pt_data->sync_mutex);
	if (atomic_add_unless(&sync_pt_data->commit_cnt, -1, 0) &&
			sync_pt_data->timeline) {
		sw_sync_timeline_inc(sync_pt_data->timeline, 1);
		mdss_inc_timeline(sync_pt_data->timeline, 1);
		mdss_inc_timeline(sync_pt_data->timeline_retire, 1);
		MDSS_XLOG(sync_pt_data->timeline_value);
		sync_pt_data->timeline_value++;

@@ -3006,7 +3014,7 @@ static void mdss_fb_release_fences(struct msm_fb_data_type *mfd)
	if (sync_pt_data->timeline) {
		val = sync_pt_data->threshold +
			atomic_read(&sync_pt_data->commit_cnt);
		sw_sync_timeline_inc(sync_pt_data->timeline, val);
		mdss_inc_timeline(sync_pt_data->timeline, val);
		sync_pt_data->timeline_value += val;
		atomic_set(&sync_pt_data->commit_cnt, 0);
	}
@@ -4183,24 +4191,16 @@ static int mdss_fb_set_lut(struct fb_info *info, void __user *p)
 * Function returns a fence on the timeline given with the name provided.
 * The fence created will be signaled when the timeline is advanced.
 */
struct sync_fence *mdss_fb_sync_get_fence(struct sw_sync_timeline *timeline,
struct mdss_fence *mdss_fb_sync_get_fence(struct mdss_timeline *timeline,
		const char *fence_name, int val)
{
	struct sync_pt *sync_pt;
	struct sync_fence *fence;
	struct mdss_fence *fence;

	pr_debug("%s: buf sync fence timeline=%d\n", fence_name, val);

	sync_pt = sw_sync_pt_create(timeline, val);
	if (sync_pt == NULL) {
		pr_err("%s: cannot create sync point\n", fence_name);
		return NULL;
	}

	/* create fence */
	fence = sync_fence_create(fence_name, sync_pt);
	fence = mdss_get_sync_fence(timeline, fence_name, NULL, val);
	pr_debug("%s: buf sync fence timeline=%d\n",
		 mdss_get_sync_fence_name(fence), val);
	if (fence == NULL) {
		sync_pt_free(sync_pt);
		pr_err("%s: cannot create fence\n", fence_name);
		return NULL;
	}
@@ -4213,7 +4213,7 @@ static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,
{
	int i, ret = 0;
	int acq_fen_fd[MDP_MAX_FENCE_FD];
	struct sync_fence *fence, *rel_fence, *retire_fence;
	struct mdss_fence *fence, *rel_fence, *retire_fence;
	int rel_fen_fd;
	int retire_fen_fd;
	int val;
@@ -4237,7 +4237,7 @@ static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,

	mutex_lock(&sync_pt_data->sync_mutex);
	for (i = 0; i < buf_sync->acq_fen_fd_cnt; i++) {
		fence = sync_fence_fdget(acq_fen_fd[i]);
		fence = mdss_get_fd_sync_fence(acq_fen_fd[i]);
		if (fence == NULL) {
			pr_err("%s: null fence! i=%d fd=%d\n",
					sync_pt_data->fence_name, i,
@@ -4251,7 +4251,7 @@ static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,
	if (ret)
		goto buf_sync_err_1;

	val = sync_pt_data->timeline_value + sync_pt_data->threshold +
	val = sync_pt_data->threshold +
			atomic_read(&sync_pt_data->commit_cnt);

	MDSS_XLOG(sync_pt_data->timeline_value, val,
@@ -4270,7 +4270,7 @@ static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,
	}

	/* create fd */
	rel_fen_fd = get_unused_fd_flags(0);
	rel_fen_fd = mdss_get_sync_fence_fd(rel_fence);
	if (rel_fen_fd < 0) {
		pr_err("%s: get_unused_fd_flags failed error:0x%x\n",
				sync_pt_data->fence_name, rel_fen_fd);
@@ -4304,13 +4304,13 @@ static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,
		ret = retire_fence ? PTR_ERR(rel_fence) : -ENOMEM;
		goto buf_sync_err_3;
	}
	retire_fen_fd = get_unused_fd_flags(0);
	retire_fen_fd = mdss_get_sync_fence_fd(retire_fence);

	if (retire_fen_fd < 0) {
		pr_err("%s: get_unused_fd_flags failed for retire fence error:0x%x\n",
				sync_pt_data->fence_name, retire_fen_fd);
		ret = retire_fen_fd;
		sync_fence_put(retire_fence);
		mdss_put_sync_fence(retire_fence);
		goto buf_sync_err_3;
	}

@@ -4320,14 +4320,12 @@ static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,
		pr_err("%s: copy_to_user failed for retire fence\n",
				sync_pt_data->fence_name);
		put_unused_fd(retire_fen_fd);
		sync_fence_put(retire_fence);
		mdss_put_sync_fence(retire_fence);
		goto buf_sync_err_3;
	}

	sync_fence_install(retire_fence, retire_fen_fd);

skip_retire_fence:
	sync_fence_install(rel_fence, rel_fen_fd);
	mdss_get_sync_fence_fd(rel_fence);
	mutex_unlock(&sync_pt_data->sync_mutex);

	if (buf_sync->flags & MDP_BUF_SYNC_FLAG_WAIT)
@@ -4337,10 +4335,10 @@ static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,
buf_sync_err_3:
	put_unused_fd(rel_fen_fd);
buf_sync_err_2:
	sync_fence_put(rel_fence);
	mdss_put_sync_fence(rel_fence);
buf_sync_err_1:
	for (i = 0; i < sync_pt_data->acq_fen_cnt; i++)
		sync_fence_put(sync_pt_data->acq_fen[i]);
		mdss_put_sync_fence(sync_pt_data->acq_fen[i]);
	sync_pt_data->acq_fen_cnt = 0;
	mutex_unlock(&sync_pt_data->sync_mutex);
	return ret;
+6 −5
Original line number Diff line number Diff line
@@ -171,11 +171,12 @@ struct disp_info_notify {
struct msm_sync_pt_data {
	char *fence_name;
	u32 acq_fen_cnt;
	struct sync_fence *acq_fen[MDP_MAX_FENCE_FD];
	struct mdss_fence *acq_fen[MDP_MAX_FENCE_FD];
	u32 temp_fen_cnt;
	struct sync_fence *temp_fen[MDP_MAX_FENCE_FD];
	struct mdss_fence *temp_fen[MDP_MAX_FENCE_FD];

	struct sw_sync_timeline *timeline;
	struct mdss_timeline *timeline;
	struct mdss_timeline *timeline_retire;
	int timeline_value;
	u32 threshold;
	u32 retire_threshold;
@@ -186,7 +187,7 @@ struct msm_sync_pt_data {
	struct mutex sync_mutex;
	struct notifier_block notifier;

	struct sync_fence *(*get_retire_fence)
	struct mdss_fence *(*get_retire_fence)
		(struct msm_sync_pt_data *sync_pt_data);
};

@@ -452,7 +453,7 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl);
void mdss_fb_update_backlight(struct msm_fb_data_type *mfd);
int mdss_fb_wait_for_fence(struct msm_sync_pt_data *sync_pt_data);
void mdss_fb_signal_timeline(struct msm_sync_pt_data *sync_pt_data);
struct sync_fence *mdss_fb_sync_get_fence(struct sw_sync_timeline *timeline,
struct mdss_fence *mdss_fb_sync_get_fence(struct mdss_timeline *timeline,
				const char *fence_name, int val);
int mdss_fb_register_mdp_instance(struct msm_mdp_interface *mdp);
int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state);
+1 −1
Original line number Diff line number Diff line
@@ -1009,7 +1009,7 @@ struct mdss_overlay_private {
	u32 splash_mem_size;
	u32 sd_enabled;

	struct sw_sync_timeline *vsync_timeline;
	struct mdss_timeline *vsync_timeline;
	struct mdss_mdp_vsync_handler vsync_retire_handler;
	int retire_cnt;
	bool kickoff_released;
+27 −22
Original line number Diff line number Diff line
@@ -21,8 +21,6 @@
#include <linux/delay.h>
#include <linux/msm_mdp.h>
#include <linux/memblock.h>
#include <linux/sync.h>
#include <linux/sw_sync.h>
#include <linux/file.h>

#include <soc/qcom/event_timer.h>
@@ -31,6 +29,7 @@
#include "mdss_fb.h"
#include "mdss_mdp.h"
#include "mdss_mdp_wfd.h"
#include "mdss_sync.h"

#define CHECK_LAYER_BOUNDS(offset, size, max_size) \
	(((size) > (max_size)) || ((offset) > ((max_size) - (size))))
@@ -704,13 +703,13 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd,
	return ret;
}

static struct sync_fence *__create_fence(struct msm_fb_data_type *mfd,
static struct mdss_fence *__create_fence(struct msm_fb_data_type *mfd,
	struct msm_sync_pt_data *sync_pt_data, u32 fence_type,
	int *fence_fd, int value)
{
	struct mdss_overlay_private *mdp5_data;
	struct mdss_mdp_ctl *ctl;
	struct sync_fence *sync_fence = NULL;
	struct mdss_fence *sync_fence = NULL;
	char fence_name[32];

	mdp5_data = mfd_to_mdp5_data(mfd);
@@ -736,16 +735,23 @@ static struct sync_fence *__create_fence(struct msm_fb_data_type *mfd,
	if ((fence_type == MDSS_MDP_RETIRE_FENCE) &&
		(mfd->panel.type == MIPI_CMD_PANEL)) {
		if (mdp5_data->vsync_timeline) {
			value = mdp5_data->vsync_timeline->value + 1 +
				mdp5_data->retire_cnt++;
			value = 1 + mdp5_data->retire_cnt++;
			sync_fence = mdss_fb_sync_get_fence(
				mdp5_data->vsync_timeline, fence_name, value);
				mdp5_data->vsync_timeline, fence_name,
				value);
		} else {
			return ERR_PTR(-EPERM);
		}
	} else {
		sync_fence = mdss_fb_sync_get_fence(sync_pt_data->timeline,
		if (fence_type == MDSS_MDP_RETIRE_FENCE)
			sync_fence = mdss_fb_sync_get_fence(
						sync_pt_data->timeline_retire,
						fence_name, value);
		else
			sync_fence = mdss_fb_sync_get_fence(
						sync_pt_data->timeline,
						fence_name, value);

	}

	if (IS_ERR_OR_NULL(sync_fence)) {
@@ -754,14 +760,15 @@ static struct sync_fence *__create_fence(struct msm_fb_data_type *mfd,
	}

	/* get fence fd */
	*fence_fd = get_unused_fd_flags(0);
	*fence_fd = mdss_get_sync_fence_fd(sync_fence);
	if (*fence_fd < 0) {
		pr_err("%s: get_unused_fd_flags failed error:0x%x\n",
			fence_name, *fence_fd);
		sync_fence_put(sync_fence);
		mdss_put_sync_fence(sync_fence);
		sync_fence = NULL;
		goto end;
	}
	pr_debug("%s:val=%d\n", mdss_get_sync_fence_name(sync_fence), value);

end:
	return sync_fence;
@@ -777,7 +784,7 @@ static struct sync_fence *__create_fence(struct msm_fb_data_type *mfd,
static int __handle_buffer_fences(struct msm_fb_data_type *mfd,
	struct mdp_layer_commit_v1 *commit, struct mdp_input_layer *layer_list)
{
	struct sync_fence *fence, *release_fence, *retire_fence;
	struct mdss_fence *fence, *release_fence, *retire_fence;
	struct msm_sync_pt_data *sync_pt_data = NULL;
	struct mdp_input_layer *layer;
	int value;
@@ -803,7 +810,7 @@ static int __handle_buffer_fences(struct msm_fb_data_type *mfd,
		if (layer->buffer.fence < 0)
			continue;

		fence = sync_fence_fdget(layer->buffer.fence);
		fence = mdss_get_fd_sync_fence(layer->buffer.fence);
		if (!fence) {
			pr_err("%s: sync fence get failed! fd=%d\n",
				sync_pt_data->fence_name, layer->buffer.fence);
@@ -816,7 +823,7 @@ static int __handle_buffer_fences(struct msm_fb_data_type *mfd,
	if (ret)
		goto sync_fence_err;

	value = sync_pt_data->timeline_value + sync_pt_data->threshold +
	value = sync_pt_data->threshold +
			atomic_read(&sync_pt_data->commit_cnt);

	release_fence = __create_fence(mfd, sync_pt_data,
@@ -835,21 +842,18 @@ static int __handle_buffer_fences(struct msm_fb_data_type *mfd,
		goto retire_fence_err;
	}

	sync_fence_install(release_fence, commit->release_fence);
	sync_fence_install(retire_fence, commit->retire_fence);

	mutex_unlock(&sync_pt_data->sync_mutex);
	return ret;

retire_fence_err:
	put_unused_fd(commit->release_fence);
	sync_fence_put(release_fence);
	mdss_put_sync_fence(release_fence);
release_fence_err:
	commit->retire_fence = -1;
	commit->release_fence = -1;
sync_fence_err:
	for (i = 0; i < sync_pt_data->acq_fen_cnt; i++)
		sync_fence_put(sync_pt_data->acq_fen[i]);
		mdss_put_sync_fence(sync_pt_data->acq_fen[i]);
	sync_pt_data->acq_fen_cnt = 0;

	mutex_unlock(&sync_pt_data->sync_mutex);
@@ -2180,7 +2184,7 @@ int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd,
	struct mdss_mdp_wfd *wfd = NULL;
	struct mdp_output_layer *output_layer = NULL;
	struct mdss_mdp_wfd_data *data = NULL;
	struct sync_fence *fence = NULL;
	struct mdss_fence *fence = NULL;
	struct msm_sync_pt_data *sync_pt_data = NULL;

	if (!mfd || !commit)
@@ -2208,7 +2212,8 @@ int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd,
			return PTR_ERR(data);

		if (output_layer->buffer.fence >= 0) {
			fence = sync_fence_fdget(output_layer->buffer.fence);
			fence = mdss_get_fd_sync_fence(
						output_layer->buffer.fence);
			if (!fence) {
				pr_err("fail to get output buffer fence\n");
				rc = -EINVAL;
@@ -2249,7 +2254,7 @@ int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd,

input_layer_err:
	if (fence)
		sync_fence_put(fence);
		mdss_put_sync_fence(fence);
fence_get_err:
	if (data)
		mdss_mdp_wfd_remove_data(wfd, data);
Loading