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

Commit ce4e0b8a 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: implement overlay prepare ioctl"

parents c4075269 d4fa573d
Loading
Loading
Loading
Loading
+95 −0
Original line number Diff line number Diff line
@@ -2323,6 +2323,98 @@ static int mdss_fb_get_metadata(struct msm_fb_data_type *mfd,
	return ret;
}

static int __handle_overlay_prepare(struct msm_fb_data_type *mfd,
		struct mdp_overlay_list *ovlist,
		struct mdp_overlay *overlays)
{
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
	struct mdss_mdp_pipe *pipe;
	struct mdp_overlay *req;
	int ret = 0;
	int i;
	u32 new_reqs = 0;

	ret = mutex_lock_interruptible(&mdp5_data->ov_lock);
	if (ret)
		return ret;

	if (!mfd->panel_power_on) {
		mutex_unlock(&mdp5_data->ov_lock);
		return -EPERM;
	}

	pr_debug("prepare fb%d num_overlays=%d\n", mfd->index,
			ovlist->num_overlays);

	for (i = 0; i < ovlist->num_overlays; i++) {
		req = overlays + i;

		req->z_order += MDSS_MDP_STAGE_0;
		ret = mdss_mdp_overlay_pipe_setup(mfd, req, &pipe);
		req->z_order -= MDSS_MDP_STAGE_0;

		if (IS_ERR_VALUE(ret))
			goto validate_exit;

		/* keep track of the new overlays to unset in case of errors */
		if (pipe->play_cnt == 0)
			new_reqs |= pipe->ndx;
	}

validate_exit:
	if (IS_ERR_VALUE(ret))
		mdss_mdp_overlay_release(mfd, new_reqs);
	mutex_unlock(&mdp5_data->ov_lock);

	ovlist->processed_overlays = i;

	return ret;
}

static int __handle_ioctl_overlay_prepare(struct msm_fb_data_type *mfd,
		void __user *argp)
{
	struct mdp_overlay_list ovlist;
	struct mdp_overlay *overlays;
	int i, ret;

	if (copy_from_user(&ovlist, argp, sizeof(ovlist)))
		return -EFAULT;

	overlays = kmalloc(ovlist.num_overlays * sizeof(*overlays), GFP_KERNEL);
	if (!overlays) {
		pr_err("Unable to allocate memory for overlays\n");
		return -ENOMEM;
	}

	for (i = 0; i < ovlist.num_overlays; i++) {
		if (copy_from_user(overlays + i, ovlist.overlay_list[i],
				sizeof(struct mdp_overlay))) {
			ret = -EFAULT;
			goto validate_exit;
		}
	}

	ret = __handle_overlay_prepare(mfd, &ovlist, overlays);
	if (!IS_ERR_VALUE(ret)) {
		for (i = 0; i < ovlist.num_overlays; i++) {
			if (copy_to_user(ovlist.overlay_list[i], overlays + i,
					sizeof(struct mdp_overlay))) {
				ret = -EFAULT;
				goto validate_exit;
			}
		}
	}

	if (copy_to_user(argp, &ovlist, sizeof(ovlist)))
		ret = -EFAULT;

validate_exit:
	kfree(overlays);

	return ret;
}

static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
					  u32 cmd, void __user *argp)
{
@@ -2446,6 +2538,9 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
		if (!ret)
			ret = copy_to_user(argp, &metadata, sizeof(metadata));
		break;
	case MSMFB_OVERLAY_PREPARE:
		ret = __handle_ioctl_overlay_prepare(mfd, argp);
		break;
	default:
		if (mfd->panel.type == WRITEBACK_PANEL)
			ret = mdss_mdp_wb_ioctl_handler(mfd, cmd, argp);
+20 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@
#define MSMFB_WRITEBACK_SET_MIRRORING_HINT _IOW(MSMFB_IOCTL_MAGIC, 167, \
						unsigned int)
#define MSMFB_ASYNC_BLIT              _IOW(MSMFB_IOCTL_MAGIC, 168, unsigned int)
#define MSMFB_OVERLAY_PREPARE		_IOWR(MSMFB_IOCTL_MAGIC, 169, \
						struct mdp_overlay_list)

#define FB_TYPE_3D_PANEL 0x10101010
#define MDP_IMGTYPE2_START 0x10000
@@ -1023,6 +1025,24 @@ struct mdp_display_commit {
	struct mdp_rect roi;
};

/**
 * struct mdp_overlay_list - argument for ioctl MSMFB_OVERLAY_PREPARE
 * @num_overlays:	Number of overlay layers as part of the frame.
 * @overlay_list:	Pointer to a list of overlay structures identifying
 *			the layers as part of the frame
 * @flags:		Flags can be used to extend behavior.
 * @processed_overlays:	Output parameter indicating how many pipes were
 *			successful. If there are no errors this number should
 *			match num_overlays. Otherwise it will indicate the last
 *			successful index for overlay that couldn't be set.
 */
struct mdp_overlay_list {
	uint32_t num_overlays;
	struct mdp_overlay **overlay_list;
	uint32_t flags;
	uint32_t processed_overlays;
};

struct mdp_page_protection {
	uint32_t page_protection;
};