msm: mdss: add support of border area

Add border_x_off and border_y_off to track the
left/right/top/bottom border parameters defined
at panel dtsi file. Adding border_x_off and
border_y_off to pipe's destination x and y so that
border can be formed during blending operation at
mixer.

Change-Id: I29673df30318c7d9064adae996da62823db3230d
Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
[mattw@codeaurora.org: resolved trivial context conflict]
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
This commit is contained in:
Kuogee Hsieh 2014-10-17 10:18:47 -07:00 committed by David Keitel
parent 3b9fec79f5
commit 3fcbdd4946
8 changed files with 103 additions and 27 deletions

View file

@ -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;

View file

@ -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__);

View file

@ -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)

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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 +

View file

@ -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 *