msm: mdss: add support for DSI ULPS state during suspend

For some video mode panels, there is a requirement to go to ULPS
state during suspend. Add support for this feature. Also the DSI
CTRL power module needs to be kept enabled during suspend. This
is needed for the DSI PHY to maintain ULPS state. Add changes to
take care of this also.

Change-Id: I9547725719ef94d31cea81f66896b9cbe47b74e1
Signed-off-by: Padmanabhan Komanduru <pkomandu@codeaurora.org>
This commit is contained in:
Padmanabhan Komanduru 2014-09-18 16:13:58 +05:30 committed by David Keitel
parent a5d404445a
commit 4a921c5496
5 changed files with 53 additions and 15 deletions

View file

@ -320,6 +320,7 @@ Optional properties:
- qcom,mdss-dsi-rx-eot-ignore: Boolean used to enable ignoring end of transmission packets.
- qcom,mdss-dsi-tx-eot-append: Boolean used to enable appending end of transmission packets.
- qcom,ulps-enabled: Boolean to enable support for Ultra Low Power State (ULPS) mode.
- qcom,suspend-ulps-enabled: Boolean to enable support for ULPS mode for panels during suspend state.
- qcom,panel-roi-alignment: Specifies the panel ROI alignment restrictions on its
left, top, width, height alignments and minimum width and
height values
@ -470,6 +471,7 @@ Example:
mdss-dsi-rx-eot-ignore;
mdss-dsi-tx-eot-append;
qcom,ulps-enabled;
qcom,suspend-ulps-enabled;
qcom,panel-roi-alignment = <4 4 2 2 20 20>;
qcom,esd-check-enabled;
qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08];

View file

@ -480,11 +480,13 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state)
if (pdata->panel_info.type == MIPI_CMD_PANEL)
mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
/* disable DSI controller */
mdss_dsi_controller_cfg(0, pdata);
if (!pdata->panel_info.ulps_suspend_enabled) {
/* disable DSI controller */
mdss_dsi_controller_cfg(0, pdata);
/* disable DSI phy */
mdss_dsi_phy_disable(ctrl_pdata);
/* disable DSI phy */
mdss_dsi_phy_disable(ctrl_pdata);
}
mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
@ -1834,6 +1836,23 @@ int dsi_panel_device_register(struct device_node *pan_node,
ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN;
/*
* If ULPS during suspend is enabled, add an extra vote for the
* DSI CTRL power module. This keeps the regulator always enabled.
* This is needed for the DSI PHY to maintain ULPS state during
* suspend also.
*/
if (pinfo->ulps_suspend_enabled) {
rc = msm_dss_enable_vreg(
ctrl_pdata->power_data[DSI_CTRL_PM].vreg_config,
ctrl_pdata->power_data[DSI_CTRL_PM].num_vreg, 1);
if (rc) {
pr_err("%s: failed to enable vregs for DSI_CTRL_PM\n",
__func__);
return rc;
}
}
if (pinfo->cont_splash_enabled) {
rc = mdss_dsi_panel_power_ctrl(&(ctrl_pdata->panel_data),
MDSS_PANEL_POWER_ON);

View file

@ -1084,6 +1084,11 @@ static int mdss_dsi_parse_panel_features(struct device_node *np,
pinfo->esd_check_enabled = of_property_read_bool(np,
"qcom,esd-check-enabled");
pinfo->ulps_suspend_enabled = of_property_read_bool(np,
"qcom,suspend-ulps-enabled");
pr_info("%s: ulps during suspend feature %s", __func__,
(pinfo->ulps_suspend_enabled ? "enabled" : "disabled"));
pinfo->mipi.dynamic_switch_enabled = of_property_read_bool(np,
"qcom,dynamic-mode-switch-enabled");

View file

@ -365,6 +365,7 @@ struct mdss_panel_info {
int pwm_period;
bool dynamic_fps;
bool ulps_feature_enabled;
bool ulps_suspend_enabled;
bool panel_ack_disabled;
bool esd_check_enabled;
char dfps_update;

View file

@ -394,7 +394,8 @@ int mdss_dsi_clk_init(struct platform_device *pdev,
}
if ((ctrl->panel_data.panel_info.type == MIPI_CMD_PANEL) ||
ctrl->panel_data.panel_info.mipi.dynamic_switch_enabled) {
ctrl->panel_data.panel_info.mipi.dynamic_switch_enabled ||
ctrl->panel_data.panel_info.ulps_suspend_enabled) {
ctrl->mmss_misc_ahb_clk = clk_get(dev, "core_mmss_clk");
if (IS_ERR(ctrl->mmss_misc_ahb_clk)) {
ctrl->mmss_misc_ahb_clk = NULL;
@ -958,7 +959,8 @@ static int mdss_dsi_ulps_config(struct mdss_dsi_ctrl_pdata *ctrl,
pinfo = &pdata->panel_info;
mipi = &pinfo->mipi;
if (!mdss_dsi_ulps_feature_enabled(pdata)) {
if (!mdss_dsi_ulps_feature_enabled(pdata) &&
!pinfo->ulps_suspend_enabled) {
pr_debug("%s: ULPS feature not supported. enable=%d\n",
__func__, enable);
return -ENOTSUPP;
@ -1219,11 +1221,13 @@ static int mdss_dsi_core_power_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
}
/*
* Phy software reset should not be done for idle screen power
* collapse use-case. Issue a phy software reset only when
* unblanking the panel.
* Phy software reset should not be done for:
* 1.) Idle screen power collapse use-case. Issue a phy software
* reset only when unblanking the panel in this case.
* 2.) When ULPS during suspend is enabled.
*/
if (pdata->panel_info.blank_state == MDSS_PANEL_BLANK_BLANK)
if (pdata->panel_info.blank_state == MDSS_PANEL_BLANK_BLANK &&
!pdata->panel_info.ulps_suspend_enabled)
mdss_dsi_phy_sw_reset(ctrl);
/*
@ -1266,8 +1270,12 @@ static int mdss_dsi_core_power_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
goto error_ulps;
}
} else {
/* Enable DSI clamps only if entering idle power collapse */
if (pdata->panel_info.blank_state != MDSS_PANEL_BLANK_BLANK) {
/*
* Enable DSI clamps only if entering idle power collapse or
* when ULPS during suspend is enabled.
*/
if ((pdata->panel_info.blank_state != MDSS_PANEL_BLANK_BLANK) ||
pdata->panel_info.ulps_suspend_enabled) {
rc = mdss_dsi_clamp_ctrl(ctrl, 1);
if (rc)
pr_err("%s: Failed to enable dsi clamps. rc=%d\n",
@ -1380,13 +1388,16 @@ static int mdss_dsi_clk_ctrl_sub(struct mdss_dsi_ctrl_pdata *ctrl,
if (clk_type & DSI_LINK_CLKS) {
/*
* If ULPS feature is enabled, enter ULPS first.
* No need to enable ULPS when turning off clocks
* If ULPS during suspend is not enabled, no need
* to enable ULPS when turning off the clocks
* while blanking the panel.
*/
if ((mdss_dsi_ulps_feature_enabled(pdata)) &&
if (((mdss_dsi_ulps_feature_enabled(pdata)) &&
(pdata->panel_info.blank_state !=
MDSS_PANEL_BLANK_BLANK))
MDSS_PANEL_BLANK_BLANK)) ||
(pdata->panel_info.ulps_suspend_enabled))
mdss_dsi_ulps_config(ctrl, 1);
mdss_dsi_link_clk_stop(ctrl);
}
if (clk_type & DSI_BUS_CLKS) {