Loading drivers/video/msm/mdss/mdss_mdp_overlay.c +95 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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); Loading include/uapi/linux/msm_mdp.h +20 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; }; Loading Loading
drivers/video/msm/mdss/mdss_mdp_overlay.c +95 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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); Loading
include/uapi/linux/msm_mdp.h +20 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; }; Loading