msm: mdss: modify how pingpong-split is used for a given panel

In the current implementation, driver makes a decision to use
pingpong-split data path if HW supports pingpong-split and connected
panel is a dual-DSI. However, in the high tier targets like msm8996 it
is possible to use dual-dsi panels in multiple modes, i.e with single
layer mixer + pingpong-split or dual layer mixer. So the correct place to
define if pingpong-split will be used or not is with panel configuration
not with the MDP driver.

In order to support this, MDP device node will continue using its
property qcom,has-pingpong-split to tell driver that underlying HW
supports pingpong-split. Introduce a new panel property,
qcom,split-mode, which will be used to decide if pingpong-split
for a given panel should be used or not.

Change-Id: I210e7f2a8b03d5c8a161241120c7d3c7081fa971
Signed-off-by: Ujwal Patel <ujwalp@codeaurora.org>
Signed-off-by: Shivaraj Shetty <shivaraj@codeaurora.org>
This commit is contained in:
Shivaraj Shetty 2015-09-16 12:00:25 +05:30 committed by David Keitel
parent cc0963f525
commit c4b4c0a31c
9 changed files with 60 additions and 35 deletions

View file

@ -419,20 +419,22 @@ Optional properites:
mixers to reduce power.
Ex: Normally 1080x1920 display uses single DSI and thus one layer
mixer. But if we use two layer mixers then mux the output of
those mixers two into single stream and route it to single DSI
those two mixers into single stream and route it to single DSI
then we can lower the clock requirements of MDP. To use this
configuration we need two fill this array with <540 540>.
This property should not be used if underlying display is using
two DSI panels such a way that each carrying half the display.
Both values doesn't have to be same, but recommended, however sum of
both values has to be equal to the panel-width.
By default two mixer streams are merged using 2D mux, however if
2 DSC encoders are used then merge is performed within compression
engine.
- qcom,split-mode: String property indicating which split mode MDP should use. Valid
entries are "pingpong-split" and "dualctl-split".
This property is mutually exclusive with qcom,lm-split.
- qcom,mdss-dsc-encoders: An integer value indicating how many DSC encoders should be used
to drive data stream to DSI.
Default value is 1 and max value is 2.
2 encoder should be used only if qcom,mdss-lm-split is used.
2 encoder should be used only if qcom,mdss-lm-split or
qcom,split-mode with pingpong-split is used.
- qcom,mdss-dsc-slice-height: An integer value indicates the dsc slice height.
- qcom,mdss-dsc-slice-width: An integer value indicates the dsc slice width.
Multiple of slice width should be equal to panel-width.
@ -690,5 +692,12 @@ Example:
qcom,mdss-dsc-config-by-manufacture-cmd;
};
dsi_sim_vid_config2: config2 {
qcom,split-mode = "dualctl-split";
};
dsi_sim_vid_config3: config3 {
qcom,split-mode = "pingpong-split";
};
};
};

View file

@ -373,10 +373,6 @@ Optional properties:
clients.
- qcom,mdss-dram-channels: This represents the number of channels in the
Bus memory controller.
- qcom,mdss-ppb-off: Array of offset addresses of ping pong buffer control registers.
The offsets are calculated from the "mdp_phys" base address
specified. The number of offsets should match the
number of ping pong buffers available in the hardware.
- qcom,regs-dump-mdp: This array represents the registers offsets that
will be dumped from the mdp when the debug logging
is enabled; each entry in the table is an start and
@ -484,6 +480,16 @@ Fudge Factors: Fudge factors are used to boost demand for
configuration, second element for robust.
- qcom,mdss-has-pingpong-split: Boolean property to indicate if destination
split feature is available or not in the target.
- qcom,mdss-slave-pingpong-off: Offset address for the extra TE block which needs
to be programmed when pingpong split feature is enabled.
Offset is calculated from the "mdp_phys"
register value. Mandatory when qcom,mdss-has-pingpong-split
is enabled.
- qcom,mdss-ppb-off: Array of offset addresses of ping pong buffer control registers.
The offsets are calculated from the "mdp_phys" base address
specified. The number of offsets should match the
number of ping pong buffers available in the hardware.
Mandatory when qcom,mdss-has-pingpong-split is enabled.
- qcom,mdss-cdm-off: Array of offset addresses for the available
chroma down modules that can convert RGB data
to YUV before sending it to the interface
@ -500,11 +506,6 @@ Fudge Factors: Fudge factors are used to boost demand for
- qcom,max-pipe-width: This value specifies the maximum MDP SSPP width
the device supports. If not specified, a default value
of 2048 will be applied.
- qcom,mdss-slave-pingpong-off: Offset address for the extra TE block which needs
to be programmed when pingpong split feature is enabled.
Offset is calculated from the "mdp_phys"
register value. Mandatory when qcom,mdss-has-pingpong-split
is enabled.
Optional subnodes:
- mdss_fb: Child nodes representing the frame buffer virtual devices.

View file

@ -1475,7 +1475,7 @@ end:
return rc;
}
static int mdss_dsi_parse_compression_params(struct device_node *np,
static int mdss_dsi_parse_topology_config(struct device_node *np,
struct dsi_panel_timing *pt, struct mdss_panel_data *panel_data)
{
int rc = 0;
@ -1483,11 +1483,13 @@ static int mdss_dsi_parse_compression_params(struct device_node *np,
const char *data;
struct mdss_panel_timing *timing = &pt->timing;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
struct mdss_panel_info *pinfo;
struct device_node *cfg_np;
ctrl_pdata = container_of(panel_data, struct mdss_dsi_ctrl_pdata,
panel_data);
cfg_np = ctrl_pdata->panel_data.cfg_np;
pinfo = &ctrl_pdata->panel_data.panel_info;
if (!cfg_np && of_find_property(np, "qcom,config-select", NULL)) {
cfg_np = of_parse_phandle(np, "qcom,config-select", 0);
@ -1507,9 +1509,22 @@ static int mdss_dsi_parse_compression_params(struct device_node *np,
goto end;
}
}
pr_info("%s: cfg_node name %s lm_split:%dx%d\n", __func__,
cfg_np->name,
timing->lm_widths[0], timing->lm_widths[1]);
rc = of_property_read_string(cfg_np, "qcom,split-mode", &data);
if (!rc && !strcmp(data, "pingpong-split"))
pinfo->use_pingpong_split = true;
if (((timing->lm_widths[0]) || (timing->lm_widths[1])) &&
pinfo->use_pingpong_split) {
pr_err("%s: pingpong_split cannot be used when lm-split[%d,%d] is specified\n",
__func__,
timing->lm_widths[0], timing->lm_widths[1]);
return -EINVAL;
}
pr_info("%s: cfg_node name %s lm_split:%dx%d pp_split:%s\n",
__func__, cfg_np->name,
timing->lm_widths[0], timing->lm_widths[1],
pinfo->use_pingpong_split ? "yes" : "no");
}
if ((timing->lm_widths[0] == 0) && (timing->lm_widths[1] == 0))
@ -2237,8 +2252,7 @@ static int mdss_dsi_panel_config_res_properties(struct device_node *np,
"qcom,mdss-dsi-timing-switch-command",
"qcom,mdss-dsi-timing-switch-command-state");
rc = mdss_dsi_parse_compression_params(np, pt,
panel_data);
rc = mdss_dsi_parse_topology_config(np, pt, panel_data);
if (rc) {
pr_err("%s: parsing compression params failed. rc:%d\n",
__func__, rc);

View file

@ -1065,15 +1065,14 @@ static int mdss_fb_probe(struct platform_device *pdev)
if (pdata->panel_info.is_split_display) {
struct mdss_panel_data *pnext = pdata->next;
/*
* currently pingpong-split is not a choice from device tree
* and it is handled in overlay_init. Fix this.
*/
mfd->split_fb_left = pdata->panel_info.lm_widths[0];
if (pnext)
mfd->split_fb_right = pnext->panel_info.lm_widths[0];
mfd->split_mode = MDP_DUAL_LM_DUAL_DISPLAY;
if (pdata->panel_info.use_pingpong_split)
mfd->split_mode = MDP_PINGPONG_SPLIT;
else
mfd->split_mode = MDP_DUAL_LM_DUAL_DISPLAY;
} else if ((pdata->panel_info.lm_widths[0] != 0) &&
(pdata->panel_info.lm_widths[1] != 0)) {
mfd->split_fb_left = pdata->panel_info.lm_widths[0];

View file

@ -381,9 +381,7 @@ static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)
/* Function returns true for either any kind of dual display */
static inline bool is_panel_split(struct msm_fb_data_type *mfd)
{
return mfd &&
(mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY ||
mfd->split_mode == MDP_PINGPONG_SPLIT);
return mfd && mfd->panel_info && mfd->panel_info->is_split_display;
}
/* Function returns true, if Layer Mixer split is Set */
static inline bool is_split_lm(struct msm_fb_data_type *mfd)

View file

@ -2039,10 +2039,6 @@ static int mdss_mdp_parse_dt(struct platform_device *pdev)
return rc;
}
rc = mdss_mdp_parse_dt_ppb_off(pdev);
if (rc)
pr_debug("Info in device tree: ppb offset not configured\n");
rc = mdss_mdp_parse_dt_cdm(pdev);
if (rc)
pr_debug("CDM offset not found in device tree\n");
@ -3259,6 +3255,11 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
}
mdata->slave_pingpong_base = mdata->mdss_io.base +
slave_pingpong_off;
rc = mdss_mdp_parse_dt_ppb_off(pdev);
if (rc) {
pr_err("Error in device tree: ppb offset not configured\n");
return rc;
}
}
/*

View file

@ -2826,6 +2826,12 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
else
offset = MDSS_MDP_CTL0;
if (is_pingpong_split(mfd) && !mdata->has_pingpong_split) {
pr_err("Error: pp_split cannot be enabled on fb%d if HW doesn't support it\n",
mfd->index);
return ERR_PTR(-EINVAL);
}
ctl = mdss_mdp_ctl_alloc(mdata, offset);
if (!ctl) {
pr_err("unable to allocate ctl\n");

View file

@ -4992,10 +4992,6 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
mfd->mdp.private1 = mdp5_data;
mfd->wait_for_kickoff = true;
if (is_panel_split(mfd) && mdp5_data->mdata->has_pingpong_split) {
mfd->split_fb_left = mfd->split_fb_right = 0;
mfd->split_mode = MDP_PINGPONG_SPLIT;
}
rc = mdss_mdp_overlay_fb_parse_dt(mfd);
if (rc)

View file

@ -582,6 +582,7 @@ struct mdss_panel_info {
bool dynamic_switch_pending;
bool is_lpm_mode;
bool is_split_display; /* two DSIs in one display, pp split or not */
bool use_pingpong_split;
/*
* index[0] = left layer mixer, value of 0 not valid