Skip to content

Commit a112362

Browse files
Adrian Salido-Morenotdmcyngn
authored andcommitted
msm: mdss: implement overlay prepare ioctl
Overlay prepare will allow a full frame with multiple overlays to be configured at once and perform frame level checks before being pushed to display. This function guarantees that if the call is successful, the frame can be displayed successfully on the screen when display commit is called. Change-Id: I276b6fe3e0a872a2e93170f3cea1002d3ce0dac9 Signed-off-by: Adrian Salido-Moreno <[email protected]> Signed-off-by: Anusha Koduru <[email protected]>
1 parent 73adbcd commit a112362

2 files changed

Lines changed: 115 additions & 1 deletion

File tree

drivers/video/msm/mdss/mdss_mdp_overlay.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,6 +2282,98 @@ static int mdss_fb_get_metadata(struct msm_fb_data_type *mfd,
22822282
return ret;
22832283
}
22842284

2285+
static int __handle_overlay_prepare(struct msm_fb_data_type *mfd,
2286+
struct mdp_overlay_list *ovlist,
2287+
struct mdp_overlay *overlays)
2288+
{
2289+
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
2290+
struct mdss_mdp_pipe *pipe;
2291+
struct mdp_overlay *req;
2292+
int ret = 0;
2293+
int i;
2294+
u32 new_reqs = 0;
2295+
2296+
ret = mutex_lock_interruptible(&mdp5_data->ov_lock);
2297+
if (ret)
2298+
return ret;
2299+
2300+
if (!mfd->panel_power_on) {
2301+
mutex_unlock(&mdp5_data->ov_lock);
2302+
return -EPERM;
2303+
}
2304+
2305+
pr_debug("prepare fb%d num_overlays=%d\n", mfd->index,
2306+
ovlist->num_overlays);
2307+
2308+
for (i = 0; i < ovlist->num_overlays; i++) {
2309+
req = overlays + i;
2310+
2311+
req->z_order += MDSS_MDP_STAGE_0;
2312+
ret = mdss_mdp_overlay_pipe_setup(mfd, req, &pipe);
2313+
req->z_order -= MDSS_MDP_STAGE_0;
2314+
2315+
if (IS_ERR_VALUE(ret))
2316+
goto validate_exit;
2317+
2318+
/* keep track of the new overlays to unset in case of errors */
2319+
if (pipe->play_cnt == 0)
2320+
new_reqs |= pipe->ndx;
2321+
}
2322+
2323+
validate_exit:
2324+
if (IS_ERR_VALUE(ret))
2325+
mdss_mdp_overlay_release(mfd, new_reqs);
2326+
mutex_unlock(&mdp5_data->ov_lock);
2327+
2328+
ovlist->processed_overlays = i;
2329+
2330+
return ret;
2331+
}
2332+
2333+
static int __handle_ioctl_overlay_prepare(struct msm_fb_data_type *mfd,
2334+
void __user *argp)
2335+
{
2336+
struct mdp_overlay_list ovlist;
2337+
struct mdp_overlay *overlays;
2338+
int i, ret;
2339+
2340+
if (copy_from_user(&ovlist, argp, sizeof(ovlist)))
2341+
return -EFAULT;
2342+
2343+
overlays = kmalloc(ovlist.num_overlays * sizeof(*overlays), GFP_KERNEL);
2344+
if (!overlays) {
2345+
pr_err("Unable to allocate memory for overlays\n");
2346+
return -ENOMEM;
2347+
}
2348+
2349+
for (i = 0; i < ovlist.num_overlays; i++) {
2350+
if (copy_from_user(overlays + i, ovlist.overlay_list[i],
2351+
sizeof(struct mdp_overlay))) {
2352+
ret = -EFAULT;
2353+
goto validate_exit;
2354+
}
2355+
}
2356+
2357+
ret = __handle_overlay_prepare(mfd, &ovlist, overlays);
2358+
if (!IS_ERR_VALUE(ret)) {
2359+
for (i = 0; i < ovlist.num_overlays; i++) {
2360+
if (copy_to_user(ovlist.overlay_list[i], overlays + i,
2361+
sizeof(struct mdp_overlay))) {
2362+
ret = -EFAULT;
2363+
goto validate_exit;
2364+
}
2365+
}
2366+
}
2367+
2368+
if (copy_to_user(argp, &ovlist, sizeof(ovlist)))
2369+
ret = -EFAULT;
2370+
2371+
validate_exit:
2372+
kfree(overlays);
2373+
2374+
return ret;
2375+
}
2376+
22852377
static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
22862378
u32 cmd, void __user *argp)
22872379
{
@@ -2422,6 +2514,9 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
24222514
if (!ret)
24232515
ret = copy_to_user(argp, &metadata, sizeof(metadata));
24242516
break;
2517+
case MSMFB_OVERLAY_PREPARE:
2518+
ret = __handle_ioctl_overlay_prepare(mfd, argp);
2519+
break;
24252520
default:
24262521
ID_PRINTK(ID_HDMI, "%s() default\n", __func__);
24272522
if (mfd->panel.type == WRITEBACK_PANEL)

include/linux/msm_mdp.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@
7979
#define MSMFB_WRITEBACK_SET_MIRRORING_HINT _IOW(MSMFB_IOCTL_MAGIC, 167, \
8080
unsigned int)
8181
#define MSMFB_ASYNC_BLIT _IOW(MSMFB_IOCTL_MAGIC, 168, unsigned int)
82-
82+
#define MSMFB_OVERLAY_PREPARE _IOWR(MSMFB_IOCTL_MAGIC, 169, \
83+
struct mdp_overlay_list)
8384
#define FB_TYPE_3D_PANEL 0x10101010
8485
#define MDP_IMGTYPE2_START 0x10000
8586
#define MSMFB_DRIVER_VERSION 0xF9E8D701
@@ -1016,6 +1017,24 @@ struct mdp_display_commit {
10161017
struct mdp_rect roi;
10171018
};
10181019

1020+
/**
1021+
* struct mdp_overlay_list - argument for ioctl MSMFB_OVERLAY_PREPARE
1022+
* @num_overlays: Number of overlay layers as part of the frame.
1023+
* @overlay_list: Pointer to a list of overlay structures identifying
1024+
* the layers as part of the frame
1025+
* @flags: Flags can be used to extend behavior.
1026+
* @processed_overlays: Output parameter indicating how many pipes were
1027+
* successful. If there are no errors this number should
1028+
* match num_overlays. Otherwise it will indicate the last
1029+
* successful index for overlay that couldn't be set.
1030+
*/
1031+
struct mdp_overlay_list {
1032+
uint32_t num_overlays;
1033+
struct mdp_overlay **overlay_list;
1034+
uint32_t flags;
1035+
uint32_t processed_overlays;
1036+
};
1037+
10191038
struct mdp_page_protection {
10201039
uint32_t page_protection;
10211040
};

0 commit comments

Comments
 (0)