diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index 4fc66c3c28c0..7647c1faedbc 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_host.c +++ b/drivers/video/fbdev/msm/mdss_dsi_host.c @@ -960,8 +960,11 @@ static void mdss_dsi_mode_setup(struct mdss_panel_data *pdata) height = pdata->panel_info.yres; if (pdata->panel_info.type == MIPI_VIDEO_PANEL) { - dummy_xres = pdata->panel_info.lcdc.xres_pad; - dummy_yres = pdata->panel_info.lcdc.yres_pad; + dummy_xres = mult_frac((pdata->panel_info.lcdc.border_left + + pdata->panel_info.lcdc.border_right), + dst_bpp, pdata->panel_info.bpp); + dummy_yres = pdata->panel_info.lcdc.border_top + + pdata->panel_info.lcdc.border_bottom; } vsync_period = vspw + vbp + height + dummy_yres + vfp; diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 23c2fa6ed91c..e35e252ba329 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -1405,15 +1405,23 @@ static int mdss_panel_parse_dt(struct device_node *np, "qcom,mdss-pan-physical-height-dimension", &tmp); pinfo->physical_height = (!rc ? tmp : 0); rc = of_property_read_u32(np, "qcom,mdss-dsi-h-left-border", &tmp); - pinfo->lcdc.xres_pad = (!rc ? tmp : 0); + pinfo->lcdc.border_left = (!rc ? tmp : 0); rc = of_property_read_u32(np, "qcom,mdss-dsi-h-right-border", &tmp); if (!rc) - pinfo->lcdc.xres_pad += tmp; + pinfo->lcdc.border_right = tmp; + + pinfo->lcdc.xres_pad = (pinfo->lcdc.border_left + + pinfo->lcdc.border_right); + rc = of_property_read_u32(np, "qcom,mdss-dsi-v-top-border", &tmp); - pinfo->lcdc.yres_pad = (!rc ? tmp : 0); + pinfo->lcdc.border_top = (!rc ? tmp : 0); rc = of_property_read_u32(np, "qcom,mdss-dsi-v-bottom-border", &tmp); if (!rc) - pinfo->lcdc.yres_pad += tmp; + pinfo->lcdc.border_bottom = tmp; + + pinfo->lcdc.yres_pad = (pinfo->lcdc.border_top + + pinfo->lcdc.border_bottom); + rc = of_property_read_u32(np, "qcom,mdss-dsi-bpp", &tmp); if (rc) { pr_err("%s:%d, bpp not specified\n", __func__, __LINE__); diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index a87660e56549..107de7ac181d 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -209,6 +209,8 @@ struct mdss_mdp_ctl { u16 width; u16 height; + u16 border_x_off; + u16 border_y_off; u32 dst_format; bool is_secure; @@ -724,7 +726,18 @@ static inline bool mdss_mdp_ctl_is_power_on_lp(struct mdss_mdp_ctl *ctl) static inline u32 left_lm_w_from_mfd(struct msm_fb_data_type *mfd) { struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd); - return (ctl && ctl->mixer_left) ? ctl->mixer_left->width : 0; + struct mdss_panel_info *pinfo = mfd->panel_info; + int width = 0; + + if (ctl && ctl->mixer_left) { + width = ctl->mixer_left->width; + width -= (pinfo->lcdc.border_left + pinfo->lcdc.border_right); + pr_debug("ctl=%d mw=%d l=%d r=%d w=%d\n", + ctl->num, ctl->mixer_left->width, + pinfo->lcdc.border_left, pinfo->lcdc.border_right, + width); + } + return width; } static inline bool mdss_mdp_is_tile_format(struct mdss_mdp_format_params *fmt) diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index cfdb60362b4d..25d3639ae08c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -452,6 +452,24 @@ exit: return; } +static inline u32 get_panel_yres(struct mdss_panel_info *pinfo) +{ + u32 yres; + + yres = pinfo->yres + pinfo->lcdc.border_top + + pinfo->lcdc.border_bottom; + return yres; +} + +static inline u32 get_panel_xres(struct mdss_panel_info *pinfo) +{ + u32 xres; + + xres = pinfo->xres + pinfo->lcdc.border_left + + pinfo->lcdc.border_right; + return xres; +} + /** * mdss_mdp_perf_calc_pipe() - calculate performance numbers required by pipe * @pipe: Source pipe struct containing updated pipe params @@ -510,7 +528,7 @@ int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe, fps = mdss_panel_get_framerate(pinfo); v_total = mdss_panel_get_vtotal(pinfo); } - xres = pinfo->xres; + xres = get_panel_xres(pinfo); is_fbc = pinfo->fbc.enabled; h_total = mdss_panel_get_htotal(pinfo, false); } else { @@ -1785,6 +1803,8 @@ static inline int mdss_mdp_set_split_ctl(struct mdss_mdp_ctl *ctl, struct mdss_mdp_ctl *split_ctl) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + struct mdss_panel_info *pinfo; + if (!ctl || !split_ctl || !mdata) return -ENODEV; @@ -1792,6 +1812,11 @@ static inline int mdss_mdp_set_split_ctl(struct mdss_mdp_ctl *ctl, /* setup split ctl mixer as right mixer of original ctl so that * original ctl can work the same way as dual pipe solution */ ctl->mixer_right = split_ctl->mixer_left; + pinfo = &ctl->panel_data->panel_info; + + /* add x offset from left ctl's border */ + split_ctl->border_x_off += (pinfo->lcdc.border_left + + pinfo->lcdc.border_right); return 0; } @@ -1862,9 +1887,9 @@ static inline u32 get_panel_width(struct mdss_mdp_ctl *ctl) { u32 width; - width = ctl->panel_data->panel_info.xres; - width += (ctl->panel_data->next && is_split_dst(ctl->mfd)) ? - ctl->panel_data->next->panel_info.xres : 0; + width = get_panel_xres(&ctl->panel_data->panel_info); + if (ctl->panel_data->next && is_split_dst(ctl->mfd)) + width += get_panel_xres(&ctl->panel_data->next->panel_info); return width; } @@ -1875,16 +1900,20 @@ int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl) u32 width, height; int split_fb; u32 max_mixer_width; + struct mdss_panel_info *pinfo; if (!ctl || !ctl->panel_data) { pr_err("invalid ctl handle\n"); return -ENODEV; } + pinfo = &ctl->panel_data->panel_info; + split_ctl = mdss_mdp_get_split_ctl(ctl); width = get_panel_width(ctl); - height = ctl->panel_data->panel_info.yres; + height = get_panel_yres(pinfo); + max_mixer_width = ctl->mdata->max_mixer_width; split_fb = (ctl->mfd->split_fb_left && @@ -1918,10 +1947,13 @@ int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl) } } - if (split_fb) + if (split_fb) { width = ctl->mfd->split_fb_left; - else if (width > max_mixer_width) + width += (pinfo->lcdc.border_left + + pinfo->lcdc.border_right); + } else if (width > max_mixer_width) { width /= 2; + } ctl->mixer_left->width = width; ctl->mixer_left->height = height; @@ -2020,6 +2052,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, struct mdss_mdp_ctl *ctl; struct mdss_data_type *mdata = mfd_to_mdata(mfd); struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); + struct mdss_panel_info *pinfo; if (pdata->panel_info.type == WRITEBACK_PANEL) offset = mdss_mdp_get_wb_ctl_support(mdata, false); @@ -2032,10 +2065,13 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, return ERR_PTR(-ENOMEM); } + pinfo = &pdata->panel_info; ctl->mfd = mfd; ctl->panel_data = pdata; ctl->is_video_mode = false; ctl->perf_release_ctl_bw = false; + ctl->border_x_off = pinfo->lcdc.border_left; + ctl->border_y_off = pinfo->lcdc.border_top; switch (pdata->panel_info.type) { case EDP_PANEL: @@ -2154,8 +2190,9 @@ int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl, return -ENODEV; } - sctl->width = pdata->panel_info.xres; - sctl->height = pdata->panel_info.yres; + sctl->width = get_panel_xres(&pdata->panel_info); + sctl->height = get_panel_yres(&pdata->panel_info); + sctl->roi = (struct mdss_rect){0, 0, sctl->width, sctl->height}; ctl->mixer_left = mdss_mdp_mixer_alloc(ctl, MDSS_MDP_MIXER_TYPE_INTF, diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 98519c45e763..bae2cab0a485 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -1236,15 +1236,21 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, dst_bpp = pinfo->fbc.enabled ? (pinfo->fbc.target_bpp) : (pinfo->bpp); - itp.width = mult_frac((pinfo->xres + pinfo->lcdc.xres_pad), - dst_bpp, pinfo->bpp); - itp.height = pinfo->yres + pinfo->lcdc.yres_pad; + itp.width = mult_frac((pinfo->xres + pinfo->lcdc.border_left + + pinfo->lcdc.border_right), dst_bpp, pinfo->bpp); + itp.height = pinfo->yres + pinfo->lcdc.border_top + + pinfo->lcdc.border_bottom; itp.border_clr = pinfo->lcdc.border_clr; itp.underflow_clr = pinfo->lcdc.underflow_clr; itp.hsync_skew = pinfo->lcdc.hsync_skew; - itp.xres = mult_frac(pinfo->xres, dst_bpp, pinfo->bpp); - itp.yres = pinfo->yres; + /* tg active area is not work, hence yres should equal to height */ + itp.xres = mult_frac((pinfo->xres + pinfo->lcdc.border_left + + pinfo->lcdc.border_right), dst_bpp, pinfo->bpp); + + itp.yres = pinfo->yres + pinfo->lcdc.border_top + + pinfo->lcdc.border_bottom; + itp.h_back_porch = pinfo->lcdc.h_back_porch; itp.h_front_porch = pinfo->lcdc.h_front_porch; itp.v_back_porch = pinfo->lcdc.v_back_porch; diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index fb12551674d7..c1a2e29b221a 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -806,6 +806,11 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, pipe->dst.w = req->dst_rect.w; pipe->dst.h = req->dst_rect.h; + if (mixer->ctl) { + pipe->dst.x += mixer->ctl->border_x_off; + pipe->dst.y += mixer->ctl->border_y_off; + } + if (mfd->panel_orientation & MDP_FLIP_LR) pipe->dst.x = pipe->mixer_left->width - pipe->dst.x - pipe->dst.w; diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 6994ffbcc4f0..98921bdd5ad0 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -216,6 +216,10 @@ struct lcd_panel_info { u32 border_clr; u32 underflow_clr; u32 hsync_skew; + u32 border_top; + u32 border_bottom; + u32 border_left; + u32 border_right; /* Pad width */ u32 xres_pad; /* Pad height */ @@ -517,7 +521,9 @@ static inline int mdss_panel_get_vtotal(struct mdss_panel_info *pinfo) { return pinfo->yres + pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch + - pinfo->lcdc.v_pulse_width; + pinfo->lcdc.v_pulse_width+ + pinfo->lcdc.border_top + + pinfo->lcdc.border_bottom; } /* @@ -533,10 +539,11 @@ static inline int mdss_panel_get_vtotal(struct mdss_panel_info *pinfo) static inline int mdss_panel_get_htotal(struct mdss_panel_info *pinfo, bool consider_fbc) { - int adj_xres = pinfo->xres; + int adj_xres = pinfo->xres + pinfo->lcdc.border_left + + pinfo->lcdc.border_right; if (consider_fbc && pinfo->fbc.enabled) - adj_xres = mult_frac(pinfo->xres, + adj_xres = mult_frac(adj_xres, pinfo->fbc.target_bpp, pinfo->bpp); return adj_xres + pinfo->lcdc.h_back_porch + diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index 09794b87cb93..d1239afd7827 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -633,9 +633,6 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info, if (ctrl_pdata->refresh_clk_rate || (frame_rate != panel_info->mipi.frame_rate) || (!panel_info->clk_rate)) { - h_period += panel_info->lcdc.xres_pad; - v_period += panel_info->lcdc.yres_pad; - if (lanes > 0) { panel_info->clk_rate = ((h_period * v_period *