Loading drivers/video/msm/mdss/mdss_mdp.h +1 −0 Original line number Diff line number Diff line Loading @@ -237,6 +237,7 @@ struct mdss_mdp_ctl { int power_state; u32 intf_num; u32 slave_intf_num; /* ping-pong split */ u32 intf_type; u32 opmode; Loading drivers/video/msm/mdss/mdss_mdp_ctl.c +71 −23 Original line number Diff line number Diff line Loading @@ -2380,10 +2380,10 @@ static void mdss_mdp_ctl_split_display_enable(int enable, } } static void mdss_mdp_ctl_dst_split_display_enable(int enable, static void mdss_mdp_ctl_pp_split_display_enable(bool enable, struct mdss_mdp_ctl *ctl) { u32 config = 0, cntl = 0; u32 cfg = 0, cntl = 0; if (ctl->mdata->nppb == 0) { pr_err("No PPB to enable PP split\n"); Loading @@ -2393,14 +2393,12 @@ static void mdss_mdp_ctl_dst_split_display_enable(int enable, mdss_mdp_ctl_split_display_enable(enable, ctl, NULL); if (enable) { /* Set slave intf */ config = ((ctl->intf_num + 1) - MDSS_MDP_INTF0) << 20; config |= BIT(16); /* Set horizontal split*/ cfg = ctl->slave_intf_num << 20; /* Set slave intf */ cfg |= BIT(16); /* Set horizontal split */ cntl = BIT(5); /* enable dst split */ } writel_relaxed(config, ctl->mdata->mdp_base + ctl->mdata->ppb[0].cfg_off); writel_relaxed(cfg, ctl->mdata->mdp_base + ctl->mdata->ppb[0].cfg_off); writel_relaxed(cntl, ctl->mdata->mdp_base + ctl->mdata->ppb[0].ctl_off); } Loading Loading @@ -2608,7 +2606,8 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff) mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, out); mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_PACK_3D, 0); } else if (is_pingpong_split(ctl->mfd)) { mdss_mdp_ctl_dst_split_display_enable(1, ctl); ctl->slave_intf_num = (ctl->intf_num + 1); mdss_mdp_ctl_pp_split_display_enable(true, ctl); } } Loading Loading @@ -3549,9 +3548,6 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, ATRACE_END("mixer_programming"); } ctl->roi_bkup.w = ctl->roi.w; ctl->roi_bkup.h = ctl->roi.h; /* * With partial frame update, enable split display bit only * when validity of ROI's on both the DSI's are identical Loading @@ -3574,17 +3570,6 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, mdss_mdp_xlog_mixer_reg(ctl); if (ctl->panel_data && ctl->panel_data->panel_info.partial_update_enabled) { /* * update roi of panel_info which will be * used by dsi to set col_page addr of panel */ ctl->panel_data->panel_info.roi = ctl->roi; if (sctl && sctl->panel_data) sctl->panel_data->panel_info.roi = sctl->roi; } ATRACE_BEGIN("frame_ready"); mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_CFG_DONE); if (commit_cb) Loading @@ -3597,6 +3582,69 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, if (ctl->ops.wait_pingpong && !mdata->serialize_wait4pp) mdss_mdp_display_wait4pingpong(ctl, false); /* * if serialize_wait4pp is false then roi_bkup used in wait4pingpong * will be of previous frame as expected. */ ctl->roi_bkup.w = ctl->roi.w; ctl->roi_bkup.h = ctl->roi.h; /* * update roi of panel_info which will be * used by dsi to set col_page addr of panel. */ if (ctl->panel_data && ctl->panel_data->panel_info.partial_update_enabled) { if (is_pingpong_split(ctl->mfd)) { bool pp_split = false; struct mdss_rect l_roi, r_roi, temp = {0}; u32 opmode = mdss_mdp_ctl_read(ctl, MDSS_MDP_REG_CTL_TOP) & ~0xF0; /* clear OUT_SEL */ /* * with pp split enabled, it is a requirement that both * panels share equal load, so split-point is center. */ u32 left_panel_w = left_lm_w_from_mfd(ctl->mfd) / 2; mdss_rect_split(&ctl->roi, &l_roi, &r_roi, left_panel_w); /* * If update is only on left panel then we still send * zeroed out right panel ROIs to DSI driver. Based on * zeroed ROI, DSI driver identifies which panel is not * transmitting. */ ctl->panel_data->panel_info.roi = l_roi; ctl->panel_data->next->panel_info.roi = r_roi; /* based on the roi, update ctl topology */ if (!mdss_rect_cmp(&temp, &l_roi) && !mdss_rect_cmp(&temp, &r_roi)) { /* left + right */ opmode |= (ctl->intf_num << 4); pp_split = true; } else if (mdss_rect_cmp(&temp, &l_roi)) { /* right only */ opmode |= (ctl->slave_intf_num << 4); pp_split = false; } else { /* left only */ opmode |= (ctl->intf_num << 4); pp_split = false; } mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, opmode); mdss_mdp_ctl_pp_split_display_enable(pp_split, ctl); } else { ctl->panel_data->panel_info.roi = ctl->roi; if (sctl && sctl->panel_data) sctl->panel_data->panel_info.roi = sctl->roi; } } if (commit_cb) commit_cb->commit_cb_fnc(MDP_COMMIT_STAGE_READY_FOR_KICKOFF, commit_cb->data); Loading drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +3 −5 Original line number Diff line number Diff line Loading @@ -607,9 +607,6 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) pdata = ctl->panel_data; ctl->roi_bkup.w = ctl->width; ctl->roi_bkup.h = ctl->height; MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled, ctx->rdptr_enabled, ctl->roi_bkup.w, ctl->roi_bkup.h); Loading Loading @@ -1278,7 +1275,8 @@ end: static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_cmd_ctx *ctx, int pp_num, int pingpong_split_slave) { int pingpong_split_slave) { int ret = 0; ctx->ctl = ctl; Loading drivers/video/msm/mdss/mdss_mdp_overlay.c +32 −7 Original line number Diff line number Diff line Loading @@ -1567,9 +1567,24 @@ static int mdss_mdp_commit_cb(enum mdp_commit_stage_type commit_stage, return ret; } static bool __validate_roi(struct mdss_mdp_pipe *pipe, /** * __is_roi_valid() - Check if ctl roi is valid for a given pipe. * @pipe: pipe to check against. * @ctl_roi: roi of the ctl path. * * Validate ctl roi against pipe's destination rectangle by checking following * conditions. If any of these conditions are met then return failure, * success otherwise. * * 1. Pipe has scaling and pipe's destination is intersecting with ctl roi. * 2. Pipe's destination and ctl roi overlap, meaning pipe's output is * intersecting or within ctl roi. In such cases, pipe should not be * part of used list and should have been omitted by user-land program. */ static bool __is_roi_valid(struct mdss_mdp_pipe *pipe, struct mdss_rect *ctl_roi) { /* condition #1 above */ if (pipe->scale.enable_pxl_ext || (pipe->src.w != pipe->dst.w) || (pipe->src.h != pipe->dst.h)) { Loading @@ -1578,10 +1593,14 @@ static bool __validate_roi(struct mdss_mdp_pipe *pipe, mdss_mdp_intersect_rect(&res, &pipe->dst, ctl_roi); if (!mdss_rect_cmp(&res, &pipe->dst)) return true; return false; } /* condition #2 above */ if (mdss_rect_overlap_check(&pipe->dst, ctl_roi)) return false; return true; } void mdss_pend_mode_switch(struct msm_fb_data_type *mfd, bool pend_switch) Loading Loading @@ -1735,9 +1754,9 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, if (data && ctl->panel_data->panel_info.partial_update_enabled) { struct mdss_rect ctl_roi; struct mdp_rect *in_roi; skip_partial_update = false; list_for_each_entry(pipe, &mdp5_data->pipes_used, list) { in_roi = pipe->mixer_left->is_right_mixer ? &data->r_roi : &data->l_roi; Loading @@ -1746,10 +1765,14 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, ctl_roi.w = in_roi->w; ctl_roi.h = in_roi->h; if (__validate_roi(pipe, &ctl_roi)) { if (!__is_roi_valid(pipe, &ctl_roi)) { skip_partial_update = true; pr_err("error. invalid config with partial update for pipe%d\n", pr_debug("error. invalid config with partial update for pipe%d\n", pipe->num); pr_debug("ctl_roi: %d,%d,%d,%d pipe->dst: %d,%d,%d,%d\n", ctl_roi.x, ctl_roi.y, ctl_roi.w, ctl_roi.h, pipe->dst.x, pipe->dst.y, pipe->dst.w, pipe->dst.h); break; } } Loading @@ -1758,6 +1781,8 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, if (!skip_partial_update) { mdss_mdp_set_roi(ctl, data); } else { memset(&temp_data, 0, sizeof(temp_data)); temp_data.l_roi = (struct mdp_rect){0, 0, ctl->mixer_left->width, ctl->mixer_left->height}; if (ctl->mixer_right) { Loading Loading @@ -3511,7 +3536,7 @@ static int mdss_mdp_histo_ioctl(struct msm_fb_data_type *mfd, u32 cmd, if (mfd->panel_info->partial_update_enabled && mdp5_data->dyn_pu_state && (cmd != MSMFB_HISTOGRAM_STOP)) { pr_err("Partial update feature is enabled.\n"); pr_debug("Partial update feature is enabled.\n"); return -EPERM; } Loading drivers/video/msm/mdss/mdss_panel.h +66 −0 Original line number Diff line number Diff line Loading @@ -536,6 +536,72 @@ static inline int mdss_rect_cmp(struct mdss_rect *rect1, rect1->w == rect2->w && rect1->h == rect2->h); } /* * mdss_rect_overlap_check() - compare two rects and check if they overlap * @rect1 - rect value to compare * @rect2 - rect value to compare * * Returns true if rects overlap, false otherwise. */ static inline bool mdss_rect_overlap_check(struct mdss_rect *rect1, struct mdss_rect *rect2) { u32 rect1_left = rect1->x, rect1_right = rect1->x + rect1->w; u32 rect1_top = rect1->y, rect1_bottom = rect1->y + rect1->h; u32 rect2_left = rect2->x, rect2_right = rect2->x + rect2->w; u32 rect2_top = rect2->y, rect2_bottom = rect2->y + rect2->h; if ((rect1_right <= rect2_left) || (rect1_left >= rect2_right) || (rect1_bottom <= rect2_top) || (rect1_top >= rect2_bottom)) return true; return false; } /* * mdss_rect_split() - split roi into two with regards to split-point. * @in_roi - input roi, non-split * @l_roi - left roi after split * @r_roi - right roi after split * * Split input ROI into left and right ROIs with respect to split-point. This * is useful during partial update with ping-pong split enabled, where user-land * program is aware of only one frame-buffer but physically there are two * distinct panels which requires their own ROIs. */ static inline void mdss_rect_split(struct mdss_rect *in_roi, struct mdss_rect *l_roi, struct mdss_rect *r_roi, u32 splitpoint) { memset(l_roi, 0x0, sizeof(*l_roi)); memset(r_roi, 0x0, sizeof(*r_roi)); /* left update needed */ if (in_roi->x < splitpoint) { *l_roi = *in_roi; if (l_roi->x + l_roi->w >= splitpoint) l_roi->w = splitpoint - in_roi->x; } /* right update needed */ if ((in_roi->x + in_roi->w) > splitpoint) { *r_roi = *in_roi; if (in_roi->x < splitpoint) { r_roi->x = 0; r_roi->w = in_roi->x + in_roi->w - splitpoint; } else { r_roi->x = in_roi->x - splitpoint; } } pr_debug("left: %d,%d,%d,%d right: %d,%d,%d,%d\n", l_roi->x, l_roi->y, l_roi->w, l_roi->h, r_roi->x, r_roi->y, r_roi->w, r_roi->h); } /* * mdss_panel_get_vtotal() - return panel vertical height * @pinfo: Pointer to panel info containing all panel information Loading Loading
drivers/video/msm/mdss/mdss_mdp.h +1 −0 Original line number Diff line number Diff line Loading @@ -237,6 +237,7 @@ struct mdss_mdp_ctl { int power_state; u32 intf_num; u32 slave_intf_num; /* ping-pong split */ u32 intf_type; u32 opmode; Loading
drivers/video/msm/mdss/mdss_mdp_ctl.c +71 −23 Original line number Diff line number Diff line Loading @@ -2380,10 +2380,10 @@ static void mdss_mdp_ctl_split_display_enable(int enable, } } static void mdss_mdp_ctl_dst_split_display_enable(int enable, static void mdss_mdp_ctl_pp_split_display_enable(bool enable, struct mdss_mdp_ctl *ctl) { u32 config = 0, cntl = 0; u32 cfg = 0, cntl = 0; if (ctl->mdata->nppb == 0) { pr_err("No PPB to enable PP split\n"); Loading @@ -2393,14 +2393,12 @@ static void mdss_mdp_ctl_dst_split_display_enable(int enable, mdss_mdp_ctl_split_display_enable(enable, ctl, NULL); if (enable) { /* Set slave intf */ config = ((ctl->intf_num + 1) - MDSS_MDP_INTF0) << 20; config |= BIT(16); /* Set horizontal split*/ cfg = ctl->slave_intf_num << 20; /* Set slave intf */ cfg |= BIT(16); /* Set horizontal split */ cntl = BIT(5); /* enable dst split */ } writel_relaxed(config, ctl->mdata->mdp_base + ctl->mdata->ppb[0].cfg_off); writel_relaxed(cfg, ctl->mdata->mdp_base + ctl->mdata->ppb[0].cfg_off); writel_relaxed(cntl, ctl->mdata->mdp_base + ctl->mdata->ppb[0].ctl_off); } Loading Loading @@ -2608,7 +2606,8 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff) mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, out); mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_PACK_3D, 0); } else if (is_pingpong_split(ctl->mfd)) { mdss_mdp_ctl_dst_split_display_enable(1, ctl); ctl->slave_intf_num = (ctl->intf_num + 1); mdss_mdp_ctl_pp_split_display_enable(true, ctl); } } Loading Loading @@ -3549,9 +3548,6 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, ATRACE_END("mixer_programming"); } ctl->roi_bkup.w = ctl->roi.w; ctl->roi_bkup.h = ctl->roi.h; /* * With partial frame update, enable split display bit only * when validity of ROI's on both the DSI's are identical Loading @@ -3574,17 +3570,6 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, mdss_mdp_xlog_mixer_reg(ctl); if (ctl->panel_data && ctl->panel_data->panel_info.partial_update_enabled) { /* * update roi of panel_info which will be * used by dsi to set col_page addr of panel */ ctl->panel_data->panel_info.roi = ctl->roi; if (sctl && sctl->panel_data) sctl->panel_data->panel_info.roi = sctl->roi; } ATRACE_BEGIN("frame_ready"); mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_CFG_DONE); if (commit_cb) Loading @@ -3597,6 +3582,69 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, if (ctl->ops.wait_pingpong && !mdata->serialize_wait4pp) mdss_mdp_display_wait4pingpong(ctl, false); /* * if serialize_wait4pp is false then roi_bkup used in wait4pingpong * will be of previous frame as expected. */ ctl->roi_bkup.w = ctl->roi.w; ctl->roi_bkup.h = ctl->roi.h; /* * update roi of panel_info which will be * used by dsi to set col_page addr of panel. */ if (ctl->panel_data && ctl->panel_data->panel_info.partial_update_enabled) { if (is_pingpong_split(ctl->mfd)) { bool pp_split = false; struct mdss_rect l_roi, r_roi, temp = {0}; u32 opmode = mdss_mdp_ctl_read(ctl, MDSS_MDP_REG_CTL_TOP) & ~0xF0; /* clear OUT_SEL */ /* * with pp split enabled, it is a requirement that both * panels share equal load, so split-point is center. */ u32 left_panel_w = left_lm_w_from_mfd(ctl->mfd) / 2; mdss_rect_split(&ctl->roi, &l_roi, &r_roi, left_panel_w); /* * If update is only on left panel then we still send * zeroed out right panel ROIs to DSI driver. Based on * zeroed ROI, DSI driver identifies which panel is not * transmitting. */ ctl->panel_data->panel_info.roi = l_roi; ctl->panel_data->next->panel_info.roi = r_roi; /* based on the roi, update ctl topology */ if (!mdss_rect_cmp(&temp, &l_roi) && !mdss_rect_cmp(&temp, &r_roi)) { /* left + right */ opmode |= (ctl->intf_num << 4); pp_split = true; } else if (mdss_rect_cmp(&temp, &l_roi)) { /* right only */ opmode |= (ctl->slave_intf_num << 4); pp_split = false; } else { /* left only */ opmode |= (ctl->intf_num << 4); pp_split = false; } mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, opmode); mdss_mdp_ctl_pp_split_display_enable(pp_split, ctl); } else { ctl->panel_data->panel_info.roi = ctl->roi; if (sctl && sctl->panel_data) sctl->panel_data->panel_info.roi = sctl->roi; } } if (commit_cb) commit_cb->commit_cb_fnc(MDP_COMMIT_STAGE_READY_FOR_KICKOFF, commit_cb->data); Loading
drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +3 −5 Original line number Diff line number Diff line Loading @@ -607,9 +607,6 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) pdata = ctl->panel_data; ctl->roi_bkup.w = ctl->width; ctl->roi_bkup.h = ctl->height; MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled, ctx->rdptr_enabled, ctl->roi_bkup.w, ctl->roi_bkup.h); Loading Loading @@ -1278,7 +1275,8 @@ end: static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_cmd_ctx *ctx, int pp_num, int pingpong_split_slave) { int pingpong_split_slave) { int ret = 0; ctx->ctl = ctl; Loading
drivers/video/msm/mdss/mdss_mdp_overlay.c +32 −7 Original line number Diff line number Diff line Loading @@ -1567,9 +1567,24 @@ static int mdss_mdp_commit_cb(enum mdp_commit_stage_type commit_stage, return ret; } static bool __validate_roi(struct mdss_mdp_pipe *pipe, /** * __is_roi_valid() - Check if ctl roi is valid for a given pipe. * @pipe: pipe to check against. * @ctl_roi: roi of the ctl path. * * Validate ctl roi against pipe's destination rectangle by checking following * conditions. If any of these conditions are met then return failure, * success otherwise. * * 1. Pipe has scaling and pipe's destination is intersecting with ctl roi. * 2. Pipe's destination and ctl roi overlap, meaning pipe's output is * intersecting or within ctl roi. In such cases, pipe should not be * part of used list and should have been omitted by user-land program. */ static bool __is_roi_valid(struct mdss_mdp_pipe *pipe, struct mdss_rect *ctl_roi) { /* condition #1 above */ if (pipe->scale.enable_pxl_ext || (pipe->src.w != pipe->dst.w) || (pipe->src.h != pipe->dst.h)) { Loading @@ -1578,10 +1593,14 @@ static bool __validate_roi(struct mdss_mdp_pipe *pipe, mdss_mdp_intersect_rect(&res, &pipe->dst, ctl_roi); if (!mdss_rect_cmp(&res, &pipe->dst)) return true; return false; } /* condition #2 above */ if (mdss_rect_overlap_check(&pipe->dst, ctl_roi)) return false; return true; } void mdss_pend_mode_switch(struct msm_fb_data_type *mfd, bool pend_switch) Loading Loading @@ -1735,9 +1754,9 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, if (data && ctl->panel_data->panel_info.partial_update_enabled) { struct mdss_rect ctl_roi; struct mdp_rect *in_roi; skip_partial_update = false; list_for_each_entry(pipe, &mdp5_data->pipes_used, list) { in_roi = pipe->mixer_left->is_right_mixer ? &data->r_roi : &data->l_roi; Loading @@ -1746,10 +1765,14 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, ctl_roi.w = in_roi->w; ctl_roi.h = in_roi->h; if (__validate_roi(pipe, &ctl_roi)) { if (!__is_roi_valid(pipe, &ctl_roi)) { skip_partial_update = true; pr_err("error. invalid config with partial update for pipe%d\n", pr_debug("error. invalid config with partial update for pipe%d\n", pipe->num); pr_debug("ctl_roi: %d,%d,%d,%d pipe->dst: %d,%d,%d,%d\n", ctl_roi.x, ctl_roi.y, ctl_roi.w, ctl_roi.h, pipe->dst.x, pipe->dst.y, pipe->dst.w, pipe->dst.h); break; } } Loading @@ -1758,6 +1781,8 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, if (!skip_partial_update) { mdss_mdp_set_roi(ctl, data); } else { memset(&temp_data, 0, sizeof(temp_data)); temp_data.l_roi = (struct mdp_rect){0, 0, ctl->mixer_left->width, ctl->mixer_left->height}; if (ctl->mixer_right) { Loading Loading @@ -3511,7 +3536,7 @@ static int mdss_mdp_histo_ioctl(struct msm_fb_data_type *mfd, u32 cmd, if (mfd->panel_info->partial_update_enabled && mdp5_data->dyn_pu_state && (cmd != MSMFB_HISTOGRAM_STOP)) { pr_err("Partial update feature is enabled.\n"); pr_debug("Partial update feature is enabled.\n"); return -EPERM; } Loading
drivers/video/msm/mdss/mdss_panel.h +66 −0 Original line number Diff line number Diff line Loading @@ -536,6 +536,72 @@ static inline int mdss_rect_cmp(struct mdss_rect *rect1, rect1->w == rect2->w && rect1->h == rect2->h); } /* * mdss_rect_overlap_check() - compare two rects and check if they overlap * @rect1 - rect value to compare * @rect2 - rect value to compare * * Returns true if rects overlap, false otherwise. */ static inline bool mdss_rect_overlap_check(struct mdss_rect *rect1, struct mdss_rect *rect2) { u32 rect1_left = rect1->x, rect1_right = rect1->x + rect1->w; u32 rect1_top = rect1->y, rect1_bottom = rect1->y + rect1->h; u32 rect2_left = rect2->x, rect2_right = rect2->x + rect2->w; u32 rect2_top = rect2->y, rect2_bottom = rect2->y + rect2->h; if ((rect1_right <= rect2_left) || (rect1_left >= rect2_right) || (rect1_bottom <= rect2_top) || (rect1_top >= rect2_bottom)) return true; return false; } /* * mdss_rect_split() - split roi into two with regards to split-point. * @in_roi - input roi, non-split * @l_roi - left roi after split * @r_roi - right roi after split * * Split input ROI into left and right ROIs with respect to split-point. This * is useful during partial update with ping-pong split enabled, where user-land * program is aware of only one frame-buffer but physically there are two * distinct panels which requires their own ROIs. */ static inline void mdss_rect_split(struct mdss_rect *in_roi, struct mdss_rect *l_roi, struct mdss_rect *r_roi, u32 splitpoint) { memset(l_roi, 0x0, sizeof(*l_roi)); memset(r_roi, 0x0, sizeof(*r_roi)); /* left update needed */ if (in_roi->x < splitpoint) { *l_roi = *in_roi; if (l_roi->x + l_roi->w >= splitpoint) l_roi->w = splitpoint - in_roi->x; } /* right update needed */ if ((in_roi->x + in_roi->w) > splitpoint) { *r_roi = *in_roi; if (in_roi->x < splitpoint) { r_roi->x = 0; r_roi->w = in_roi->x + in_roi->w - splitpoint; } else { r_roi->x = in_roi->x - splitpoint; } } pr_debug("left: %d,%d,%d,%d right: %d,%d,%d,%d\n", l_roi->x, l_roi->y, l_roi->w, l_roi->h, r_roi->x, r_roi->y, r_roi->w, r_roi->h); } /* * mdss_panel_get_vtotal() - return panel vertical height * @pinfo: Pointer to panel info containing all panel information Loading