Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 61668dc36db47c1fc40a97fe6dc61fc09006fc4b Mon Sep 17 00:00:00 2001
- From: Aravind Venkateswaran <aravindh@codeaurora.org>
- Date: Fri, 15 Aug 2014 17:04:35 -0700
- Subject: [PATCH 1/3] msm: mdss: add support for different panel power states
- Currently a panel either be in a powered on state or a powered off
- state. However, it is possible for panels to be configured in an
- intermediate low-power state where the panel is always kept on. In
- order to support such use-cases, it is necessary to add the concept
- of panel power states in MDSS so that each software layer can
- independently maintain it's state and manage transitions between them.
- This change just refactors the driver with only two existing power
- states - panel on and panel off.
- [GabrieleM: Adapt code for Motorola msm8226 sources]
- Change-Id: I49d1fda506761546c5e22d9106c5177e75053a81
- Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org>
- (cherry picked from commit 543feb0d3107a4e69bb9df7cc8a17d86be57875e)
- ---
- drivers/video/msm/mdss/dsi_host_v2.c | 2 +-
- drivers/video/msm/mdss/dsi_status_v2.c | 2 +-
- drivers/video/msm/mdss/dsi_v2.c | 4 +-
- drivers/video/msm/mdss/mdp3_ctrl.c | 2 +-
- drivers/video/msm/mdss/mdss_dsi.c | 187 +++++++++++++++--------
- drivers/video/msm/mdss/mdss_dsi_panel.c | 18 ++-
- drivers/video/msm/mdss/mdss_dsi_status.c | 4 +-
- drivers/video/msm/mdss/mdss_fb.c | 60 ++++----
- drivers/video/msm/mdss/mdss_fb.h | 9 +-
- drivers/video/msm/mdss/mdss_mdp.h | 11 +-
- drivers/video/msm/mdss/mdss_mdp_ctl.c | 86 ++++++-----
- drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 69 ++++-----
- drivers/video/msm/mdss/mdss_mdp_intf_video.c | 2 +-
- drivers/video/msm/mdss/mdss_mdp_intf_writeback.c | 3 +-
- drivers/video/msm/mdss/mdss_mdp_overlay.c | 40 ++---
- drivers/video/msm/mdss/mdss_mdp_pp.c | 4 +-
- drivers/video/msm/mdss/mdss_mdp_wb.c | 2 +-
- drivers/video/msm/mdss/mdss_panel.h | 27 +++-
- 18 files changed, 316 insertions(+), 216 deletions(-)
- diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
- index 7f341e9..c2239e7 100644
- --- a/drivers/video/msm/mdss/dsi_host_v2.c
- +++ b/drivers/video/msm/mdss/dsi_host_v2.c
- @@ -1251,7 +1251,7 @@ static int msm_dsi_cont_on(struct mdss_panel_data *pdata)
- mutex_unlock(&ctrl_pdata->mutex);
- return ret;
- }
- - pinfo->panel_power_on = 1;
- + pinfo->panel_power_on = MDSS_PANEL_POWER_ON;
- ret = mdss_dsi_panel_reset(pdata, 1);
- if (ret) {
- pr_err("%s: Panel reset failed\n", __func__);
- diff --git a/drivers/video/msm/mdss/dsi_status_v2.c b/drivers/video/msm/mdss/dsi_status_v2.c
- index e71b42d..decdc9f 100644
- --- a/drivers/video/msm/mdss/dsi_status_v2.c
- +++ b/drivers/video/msm/mdss/dsi_status_v2.c
- @@ -96,7 +96,7 @@ void check_dsi_ctrl_status(struct work_struct *work)
- mutex_unlock(&mdp3_session->lock);
- - if ((pdsi_status->mfd->panel_power_on)) {
- + if (pdsi_status->mfd->panel_power_state == MDSS_PANEL_POWER_ON) {
- if (ret > 0) {
- schedule_delayed_work(&pdsi_status->check_status,
- msecs_to_jiffies(pdsi_status->check_interval));
- diff --git a/drivers/video/msm/mdss/dsi_v2.c b/drivers/video/msm/mdss/dsi_v2.c
- index ff99b11..29fd2dd 100644
- --- a/drivers/video/msm/mdss/dsi_v2.c
- +++ b/drivers/video/msm/mdss/dsi_v2.c
- @@ -65,7 +65,7 @@ static int dsi_panel_handler(struct mdss_panel_data *pdata, int enable)
- panel_data);
- if (enable) {
- - pdata->panel_info.panel_power_on = 1;
- + pdata->panel_info.panel_power_on = MDSS_PANEL_POWER_ON;
- if (ctrl_pdata->on)
- ctrl_pdata->on(pdata);
- else {
- @@ -84,7 +84,7 @@ static int dsi_panel_handler(struct mdss_panel_data *pdata, int enable)
- __func__);
- rc = -EINVAL;
- }
- - pdata->panel_info.panel_power_on = 0;
- + pdata->panel_info.panel_power_on = MDSS_PANEL_POWER_OFF;
- }
- return rc;
- }
- diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
- index a2a71b1..820e54f 100644
- --- a/drivers/video/msm/mdss/mdp3_ctrl.c
- +++ b/drivers/video/msm/mdss/mdp3_ctrl.c
- @@ -962,7 +962,7 @@ static int mdp3_overlay_play(struct msm_fb_data_type *mfd,
- mutex_lock(&mdp3_session->lock);
- - if (mfd->panel_power_on)
- + if (mdss_fb_is_panel_power_on(mfd))
- rc = mdp3_overlay_queue_buffer(mfd, req);
- else
- rc = -EPERM;
- diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
- index 1824c68..7db6d09 100644
- --- a/drivers/video/msm/mdss/mdss_dsi.c
- +++ b/drivers/video/msm/mdss/mdss_dsi.c
- @@ -69,7 +69,7 @@ static int mdss_dsi_regulator_init(struct platform_device *pdev)
- ctrl_pdata->power_data.num_vreg, 1);
- }
- -static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata, int enable)
- +static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata)
- {
- int ret;
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
- @@ -77,32 +77,85 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata, int enable)
- if (pdata == NULL) {
- pr_err("%s: Invalid input data\n", __func__);
- ret = -EINVAL;
- - goto error;
- + goto end;
- }
- ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
- panel_data);
- - pr_debug("%s: enable=%d\n", __func__, enable);
- - if (enable) {
- - ret = msm_dss_enable_vreg(
- - ctrl_pdata->power_data.vreg_config,
- - ctrl_pdata->power_data.num_vreg, 1);
- - if (ret) {
- - pr_err("%s:Failed to enable vregs.rc=%d\n",
- - __func__, ret);
- - goto error;
- - }
- - } else {
- - ret = msm_dss_enable_vreg(
- - ctrl_pdata->power_data.vreg_config,
- - ctrl_pdata->power_data.num_vreg, 0);
- - if (ret) {
- - pr_err("%s: Failed to disable vregs.rc=%d\n",
- - __func__, ret);
- - }
- + ret = msm_dss_enable_vreg(
- + ctrl_pdata->power_data.vreg_config,
- + ctrl_pdata->power_data.num_vreg, 0);
- + if (ret) {
- + pr_err("%s: Failed to disable vregs.rc=%d\n",
- + __func__, ret);
- }
- -error:
- +end:
- + return ret;
- +}
- +
- +static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata)
- +{
- + int ret;
- + struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
- +
- + if (pdata == NULL) {
- + pr_err("%s: Invalid input data\n", __func__);
- + ret = -EINVAL;
- + goto end;
- + }
- +
- + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
- + panel_data);
- +
- + ret = msm_dss_enable_vreg(
- + ctrl_pdata->power_data.vreg_config,
- + ctrl_pdata->power_data.num_vreg, 1);
- + if (ret) {
- + pr_err("%s:Failed to enable vregs.rc=%d\n",
- + __func__, ret);
- + goto end;
- + }
- +end:
- + return ret;
- +}
- +
- +static int mdss_dsi_panel_power_ctrl(struct mdss_panel_data *pdata,
- + int power_state)
- +{
- + int ret;
- + struct mdss_panel_info *pinfo;
- +
- + if (pdata == NULL) {
- + pr_err("%s: Invalid input data\n", __func__);
- + return -EINVAL;
- + }
- +
- + pinfo = &pdata->panel_info;
- + pr_debug("%s: cur_power_state=%d req_power_state=%d\n", __func__,
- + pinfo->panel_power_state, power_state);
- +
- + if (pinfo->panel_power_state == power_state) {
- + pr_debug("%s: no change needed\n", __func__);
- + return 0;
- + }
- +
- + switch (power_state) {
- + case MDSS_PANEL_POWER_OFF:
- + ret = mdss_dsi_panel_power_off(pdata);
- + break;
- + case MDSS_PANEL_POWER_ON:
- + ret = mdss_dsi_panel_power_on(pdata);
- + break;
- + default:
- + pr_err("%s: unknown panel power state requested (%d)\n",
- + __func__, power_state);
- + ret = -EINVAL;
- + }
- +
- + if (!ret)
- + pinfo->panel_power_state = power_state;
- +
- return ret;
- }
- @@ -304,7 +357,7 @@ static int mdss_dsi_get_panel_cfg(char *panel_cfg)
- static int mdss_dsi_ulps_config_sub(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
- int enable, int partial);
- -static int mdss_dsi_off(struct mdss_panel_data *pdata)
- +static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state)
- {
- int ret = 0;
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
- @@ -316,19 +369,12 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata)
- return -EINVAL;
- }
- - if (!pdata->panel_info.panel_power_on) {
- - pr_warn("%s:%d Panel already off.\n", __func__, __LINE__);
- - return -EPERM;
- - }
- -
- - pdata->panel_info.panel_power_on = 0;
- -
- ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
- panel_data);
- panel_info = &ctrl_pdata->panel_data.panel_info;
- - pr_info("%s+: ctrl=%p ndx=%d\n", __func__,
- - ctrl_pdata, ctrl_pdata->ndx);
- + pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n",
- + __func__, ctrl_pdata, ctrl_pdata->ndx, power_state);
- if (ctrl_pdata->partial_mode_enabled
- && !pdata->panel_info.panel_dead) {
- @@ -339,6 +385,12 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata)
- && pdata->panel_info.panel_dead)
- pr_warn("%s: Panel is dead, shut down DSI\n", __func__);
- + if (power_state == panel_info->panel_power_state) {
- + pr_debug("%s: No change in power state %d -> %d\n", __func__,
- + panel_info->panel_power_state, power_state);
- + goto end;
- + }
- +
- if (pdata->panel_info.type == MIPI_CMD_PANEL)
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
- @@ -350,18 +402,12 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata)
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
- - ret = mdss_dsi_panel_power_on(pdata, 0);
- - if (ret) {
- + ret = mdss_dsi_panel_power_ctrl(pdata, power_state);
- + if (ret)
- pr_err("%s: Panel power off failed\n", __func__);
- - return ret;
- - }
- }
- - if (panel_info->dynamic_fps
- - && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE)
- - && (panel_info->new_fps != panel_info->mipi.frame_rate))
- - panel_info->mipi.frame_rate = panel_info->new_fps;
- -
- +end:
- pr_info("%s-:\n", __func__);
- return ret;
- @@ -487,7 +533,7 @@ static int mdss_dsi_ulps_config_sub(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
- if (enable && !ctrl_pdata->ulps) {
- /* No need to configure ULPS mode when entering suspend state */
- - if (!partial && !pdata->panel_info.panel_power_on) {
- + if (!partial && pdata->panel_info.panel_power_state == MDSS_PANEL_POWER_OFF) {
- pr_err("%s: panel off. returning\n", __func__);
- goto error;
- }
- @@ -651,22 +697,19 @@ int mdss_dsi_on(struct mdss_panel_data *pdata)
- struct mipi_panel_info *mipi;
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
- struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- + int cur_power_state;
- if (pdata == NULL) {
- pr_err("%s: Invalid input data\n", __func__);
- return -EINVAL;
- }
- - if (pdata->panel_info.panel_power_on) {
- - pr_warn("%s:%d Panel already on.\n", __func__, __LINE__);
- - return 0;
- - }
- -
- ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
- panel_data);
- - pr_info("%s+: ctrl=%p ndx=%d\n",
- - __func__, ctrl_pdata, ctrl_pdata->ndx);
- + cur_power_state = pdata->panel_info.panel_power_state;
- + pr_debug("%s+: ctrl=%p ndx=%d cur_power_state=%d\n", __func__,
- + ctrl_pdata, ctrl_pdata->ndx, cur_power_state);
- pinfo = &pdata->panel_info;
- mipi = &pdata->panel_info.mipi;
- @@ -675,14 +718,19 @@ int mdss_dsi_on(struct mdss_panel_data *pdata)
- && !pdata->panel_info.panel_dead) {
- mdss_dsi_ulps_config_sub(ctrl_pdata, 0, 1);
- mdata->ulps = false;
- - pdata->panel_info.panel_power_on = 1;
- + pdata->panel_info.panel_power_state = MDSS_PANEL_POWER_ON;
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
- } else {
- if (ctrl_pdata->partial_mode_enabled
- && pdata->panel_info.panel_dead)
- pr_warn("%s: Panel is dead, bring up DSI\n", __func__);
- - ret = mdss_dsi_panel_power_on(pdata, 1);
- + if (MDSS_PANEL_POWER_ON == pinfo->panel_power_state) {
- + pr_debug("%s: panel already on\n", __func__);
- + goto end;
- + }
- +
- + ret = mdss_dsi_panel_power_ctrl(pdata, MDSS_PANEL_POWER_ON);
- if (ret) {
- pr_err("%s:Panel power on failed. rc=%d\n", __func__, ret);
- return ret;
- @@ -692,16 +740,15 @@ int mdss_dsi_on(struct mdss_panel_data *pdata)
- if (ret) {
- pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__,
- ret);
- - ret = mdss_dsi_panel_power_on(pdata, 0);
- + ret = mdss_dsi_panel_power_on(pdata);
- if (ret) {
- pr_err("%s: Panel reset failed. rc=%d\n",
- __func__, ret);
- return ret;
- }
- - pdata->panel_info.panel_power_on = 0;
- + pdata->panel_info.panel_power_state = MDSS_PANEL_POWER_OFF;
- return ret;
- }
- - pdata->panel_info.panel_power_on = 1;
- mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base));
- mdss_dsi_phy_init(pdata);
- @@ -735,6 +782,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata)
- if (pdata->panel_info.type == MIPI_CMD_PANEL)
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
- +end:
- pr_info("%s-:\n", __func__);
- return 0;
- }
- @@ -745,8 +793,6 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
- struct mipi_panel_info *mipi;
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
- - pr_debug("%s+:\n", __func__);
- -
- if (pdata == NULL) {
- pr_err("%s: Invalid input data\n", __func__);
- return -EINVAL;
- @@ -756,6 +802,9 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
- panel_data);
- mipi = &pdata->panel_info.mipi;
- + pr_debug("%s+: ctrl=%p ndx=%d cur_blank_state=%d\n", __func__,
- + ctrl_pdata, ctrl_pdata->ndx, pdata->panel_info.blank_state);
- +
- if (!(ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT)) {
- ret = ctrl_pdata->on(pdata);
- if (ret) {
- @@ -778,14 +827,12 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
- return ret;
- }
- -static int mdss_dsi_blank(struct mdss_panel_data *pdata)
- +static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state)
- {
- int ret = 0;
- struct mipi_panel_info *mipi;
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
- - pr_debug("%s+:\n", __func__);
- -
- if (pdata == NULL) {
- pr_err("%s: Invalid input data\n", __func__);
- return -EINVAL;
- @@ -795,6 +842,9 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata)
- panel_data);
- mipi = &pdata->panel_info.mipi;
- + pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n",
- + __func__, ctrl_pdata, ctrl_pdata->ndx, power_state);
- +
- if (pdata->panel_info.type == MIPI_VIDEO_PANEL &&
- ctrl_pdata->off_cmds.link_state == DSI_LP_MODE) {
- mdss_dsi_sw_reset(pdata);
- @@ -1000,6 +1050,7 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
- {
- int rc = 0;
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
- + int power_state;
- if (pdata == NULL) {
- pr_err("%s: Invalid input data\n", __func__);
- @@ -1024,18 +1075,20 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
- pdata->panel_info.cont_splash_esd_rdy = true;
- break;
- case MDSS_EVENT_BLANK:
- + power_state = (int) (unsigned long) arg;
- if (ctrl_pdata->off_cmds.link_state == DSI_HS_MODE)
- - rc = mdss_dsi_blank(pdata);
- + rc = mdss_dsi_blank(pdata, power_state);
- break;
- case MDSS_EVENT_PANEL_OFF:
- + power_state = (int) (unsigned long) arg;
- ctrl_pdata->ctrl_state &= ~CTRL_STATE_MDP_ACTIVE;
- if (ctrl_pdata->off_cmds.link_state == DSI_LP_MODE)
- - rc = mdss_dsi_blank(pdata);
- - rc = mdss_dsi_off(pdata);
- + rc = mdss_dsi_blank(pdata, power_state);
- + rc = mdss_dsi_off(pdata, power_state);
- break;
- case MDSS_EVENT_CONT_SPLASH_FINISH:
- if (ctrl_pdata->off_cmds.link_state == DSI_LP_MODE)
- - rc = mdss_dsi_blank(pdata);
- + rc = mdss_dsi_blank(pdata, MDSS_PANEL_POWER_OFF);
- ctrl_pdata->ctrl_state &= ~CTRL_STATE_MDP_ACTIVE;
- rc = mdss_dsi_cont_splash_on(pdata);
- break;
- @@ -1219,7 +1272,7 @@ int mdss_dsi_ioctl_handler(struct mdss_panel_data *pdata, u32 cmd, void *arg)
- int old_tx_mode;
- int mode = DSI_MODE_BIT_LP;
- - if (!pdata->panel_info.panel_power_on) {
- + if (!mdss_panel_is_panel_power_on(pdata)) {
- pr_err("%s: Panel is off\n", __func__);
- return -EPERM;
- }
- @@ -1713,8 +1766,6 @@ int dsi_panel_device_register(struct device_node *pan_node,
- ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN;
- if (pinfo->cont_splash_enabled) {
- - pinfo->panel_power_on = 1;
- -
- /*
- * This call intends to call to gpio_request for display's
- * reset gpio, because with cont_splash_enabled, there is
- @@ -1729,17 +1780,19 @@ int dsi_panel_device_register(struct device_node *pan_node,
- return rc;
- }
- - rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1);
- + rc = mdss_dsi_panel_power_ctrl(&(ctrl_pdata->panel_data),
- + MDSS_PANEL_POWER_ON);
- if (rc) {
- pr_err("%s: Panel power on failed\n", __func__);
- return rc;
- }
- + pinfo->blank_state = MDSS_PANEL_BLANK_UNBLANK;
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
- ctrl_pdata->ctrl_state |=
- (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE);
- } else {
- - pinfo->panel_power_on = 0;
- + pinfo->panel_power_state = MDSS_PANEL_POWER_OFF;
- }
- rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data));
- diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
- index 9e93671..da915f7 100644
- --- a/drivers/video/msm/mdss/mdss_dsi_panel.c
- +++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
- @@ -594,7 +594,8 @@ int mdss_panel_check_status(struct mdss_dsi_ctrl_pdata *ctrl)
- static int esd_trigger_cnt;
- #endif
- - if (!ctrl->panel_data.panel_info.panel_power_on) {
- + if (ctrl->panel_data.panel_info.panel_power_state !=
- + MDSS_PANEL_POWER_ON) {
- ret = 1;
- goto end;
- }
- @@ -772,21 +773,22 @@ static int mdss_dsi_quickdraw_check_panel_state(struct mdss_panel_data *pdata,
- static int mdss_dsi_panel_on(struct mdss_panel_data *pdata)
- {
- - struct mipi_panel_info *mipi;
- struct mdss_dsi_ctrl_pdata *ctrl = NULL;
- struct msm_fb_data_type *mfd;
- u8 pwr_mode = 0;
- char *dropbox_issue = NULL;
- static int dropbox_count;
- + struct mdss_panel_info *pinfo;
- if (pdata == NULL) {
- pr_err("%s: Invalid input data\n", __func__);
- return -EINVAL;
- }
- + pinfo = &pdata->panel_info;
- +
- ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata,
- panel_data);
- - mipi = &pdata->panel_info.mipi;
- mfd = pdata->mfd;
- pr_info("%s+: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx);
- @@ -865,6 +867,8 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata)
- pdata->panel_info.cabc_mode = CABC_UI_MODE;
- end:
- + pinfo->blank_state = MDSS_PANEL_BLANK_UNBLANK;
- +
- if (dropbox_issue != NULL) {
- char dropbox_entry[256];
- @@ -885,23 +889,23 @@ end:
- static int mdss_dsi_panel_off(struct mdss_panel_data *pdata)
- {
- - struct mipi_panel_info *mipi;
- struct mdss_dsi_ctrl_pdata *ctrl = NULL;
- struct msm_fb_data_type *mfd;
- + struct mdss_panel_info *pinfo;
- if (pdata == NULL) {
- pr_err("%s: Invalid input data\n", __func__);
- return -EINVAL;
- }
- + pinfo = &pdata->panel_info;
- +
- ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata,
- panel_data);
- mfd = pdata->mfd;
- pr_info("%s+: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx);
- - mipi = &pdata->panel_info.mipi;
- -
- if (!mfd->quickdraw_in_progress)
- mmi_panel_notify(MMI_PANEL_EVENT_PRE_DISPLAY_OFF, NULL);
- @@ -935,6 +939,8 @@ disable_regs:
- if (pdata->panel_info.dynamic_cabc_enabled)
- pdata->panel_info.cabc_mode = CABC_OFF_MODE;
- + pinfo->blank_state = MDSS_PANEL_BLANK_BLANK;
- +
- pr_info("%s-:\n", __func__);
- return 0;
- diff --git a/drivers/video/msm/mdss/mdss_dsi_status.c b/drivers/video/msm/mdss/mdss_dsi_status.c
- index 56d0f68..ea24eac 100644
- --- a/drivers/video/msm/mdss/mdss_dsi_status.c
- +++ b/drivers/video/msm/mdss/mdss_dsi_status.c
- @@ -92,7 +92,7 @@ static void check_dsi_ctrl_status(struct work_struct *work)
- return;
- }
- - if (!pdsi_status->mfd->panel_power_on) {
- + if (pdsi_status->mfd->panel_power_state == MDSS_PANEL_POWER_OFF) {
- pr_err("%s: panel off\n", __func__);
- return;
- }
- @@ -123,7 +123,7 @@ static void check_dsi_ctrl_status(struct work_struct *work)
- mutex_unlock(&ctl->offlock);
- #endif
- - if ((pdsi_status->mfd->panel_power_on)) {
- + if (pdsi_status->mfd->panel_power_state == MDSS_PANEL_POWER_ON) {
- if (ret > 0) {
- schedule_delayed_work(&pdsi_status->check_status,
- msecs_to_jiffies(interval));
- diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
- index c06d507..fa41c68 100644
- --- a/drivers/video/msm/mdss/mdss_fb.c
- +++ b/drivers/video/msm/mdss/mdss_fb.c
- @@ -144,7 +144,7 @@ static int mdss_fb_notify_update(struct msm_fb_data_type *mfd,
- &mfd->no_update.comp, 4 * HZ);
- to_user = (unsigned int)mfd->no_update.value;
- } else {
- - if (mfd->panel_power_on) {
- + if (mdss_fb_is_panel_power_on(mfd)) {
- INIT_COMPLETION(mfd->power_off_comp);
- ret = wait_for_completion_interruptible_timeout(
- &mfd->power_off_comp, 1 * HZ);
- @@ -376,10 +376,10 @@ static ssize_t mdss_mdp_show_blank_event(struct device *dev,
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
- int ret;
- - pr_debug("fb%d panel_power_on = %d\n", mfd->index,
- - mfd->quickdraw_in_progress ? 0 : mfd->panel_power_on);
- + pr_debug("fb%d panel_power_state = %d\n", mfd->index,
- + mfd->panel_power_state);
- ret = scnprintf(buf, PAGE_SIZE, "panel_power_on = %d\n",
- - mfd->quickdraw_in_progress ? 0 : mfd->panel_power_on);
- + mfd->quickdraw_in_progress ? 0 : mfd->panel_power_state);
- return ret;
- }
- @@ -767,7 +767,7 @@ static int mdss_fb_suspend_sub(struct msm_fb_data_type *mfd)
- }
- mfd->suspend.op_enable = mfd->op_enable;
- - mfd->suspend.panel_power_on = mfd->panel_power_on;
- + mfd->suspend.panel_power_state = mfd->panel_power_state;
- if (mfd->op_enable) {
- ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, mfd->fbi,
- @@ -804,7 +804,7 @@ static int mdss_fb_resume_sub(struct msm_fb_data_type *mfd)
- /* resume state var recover */
- mfd->op_enable = mfd->suspend.op_enable;
- - if (mfd->suspend.panel_power_on) {
- + if (mfd->suspend.panel_power_state == MDSS_PANEL_POWER_ON) {
- ret = mdss_fb_blank_sub(FB_BLANK_UNBLANK, mfd->fbi,
- mfd->op_enable);
- if (ret)
- @@ -931,7 +931,7 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl)
- int (*update_ad_input)(struct msm_fb_data_type *mfd);
- u32 temp = bkl_lvl;
- - if (((!mfd->panel_power_on && mfd->dcm_state != DCM_ENTER)
- + if (((!mdss_fb_is_panel_power_on(mfd) && mfd->dcm_state != DCM_ENTER)
- || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) {
- mfd->unset_bl_level = bkl_lvl;
- return;
- @@ -992,8 +992,9 @@ int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable)
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- struct mdss_panel_data *pdata;
- int ret = 0;
- + int cur_power_state, req_power_state = MDSS_PANEL_POWER_OFF;
- - if (!op_enable && !mfd->quickdraw_in_progress)
- + if (!mfd || (!op_enable && !mfd->quickdraw_in_progress))
- return -EPERM;
- if (mfd->dcm_state == DCM_ENTER)
- @@ -1001,13 +1002,16 @@ int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable)
- pdata = dev_get_platdata(&mfd->pdev->dev);
- + cur_power_state = mfd->panel_power_state;
- switch (blank_mode) {
- case FB_BLANK_UNBLANK:
- - if (!mfd->panel_power_on && mfd->mdp.on_fnc) {
- + pr_debug("unblank called. cur pwr state=%d\n", cur_power_state);
- + if ((cur_power_state != MDSS_PANEL_POWER_ON) &&
- + mfd->mdp.on_fnc) {
- int panel_dead = mfd->panel_info->panel_dead;
- ret = mfd->mdp.on_fnc(mfd);
- if (ret == 0) {
- - mfd->panel_power_on = true;
- + mfd->panel_power_state = MDSS_PANEL_POWER_ON;
- if (panel_dead &&
- mfd->panel_info->bklt_ctrl == BL_DCS_CMD &&
- pdata) {
- @@ -1036,9 +1040,10 @@ int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable)
- case FB_BLANK_NORMAL:
- case FB_BLANK_POWERDOWN:
- default:
- - if (mfd->panel_power_on && mfd->mdp.off_fnc) {
- - int curr_pwr_state;
- -
- + pr_debug("blank powerdown called. cur mode=%d, req mode=%d\n",
- + cur_power_state, req_power_state);
- + if (mdss_fb_is_panel_power_on(mfd) && mfd->mdp.off_fnc) {
- + cur_power_state = mfd->panel_power_state;
- mutex_lock(&mfd->update.lock);
- mfd->update.type = NOTIFY_TYPE_SUSPEND;
- mfd->update.is_suspend = 1;
- @@ -1049,9 +1054,8 @@ int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable)
- complete(&mfd->no_update.comp);
- mfd->op_enable = false;
- - curr_pwr_state = mfd->panel_power_on;
- - mfd->panel_power_on = false;
- mfd->bl_updated = 0;
- + mfd->panel_power_state = req_power_state;
- if (mfd->shutdown_pending &&
- mfd->panel_info->bl_shutdown_delay)
- @@ -1062,7 +1066,7 @@ int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable)
- ret = mfd->mdp.off_fnc(mfd);
- if (ret)
- - mfd->panel_power_on = curr_pwr_state;
- + mfd->panel_power_state = cur_power_state;
- else
- mdss_fb_release_fences(mfd);
- mfd->op_enable = true;
- @@ -1088,9 +1092,9 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info)
- mdss_fb_pan_idle(mfd);
- if (mfd->op_enable == 0) {
- if (blank_mode == FB_BLANK_UNBLANK)
- - mfd->suspend.panel_power_on = true;
- + mfd->suspend.panel_power_state = MDSS_PANEL_POWER_ON;
- else
- - mfd->suspend.panel_power_on = false;
- + mfd->suspend.panel_power_state = MDSS_PANEL_POWER_OFF;
- return 0;
- }
- ret = mdss_fb_blank_sub(blank_mode, info, mfd->op_enable);
- @@ -1543,7 +1547,7 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd)
- fbi->pseudo_palette = mdss_fb_pseudo_palette;
- mfd->ref_cnt = 0;
- - mfd->panel_power_on = false;
- + mfd->panel_power_state = MDSS_PANEL_POWER_OFF;
- mfd->dcm_state = DCM_UNINIT;
- mdss_fb_parse_dt(mfd);
- @@ -1993,7 +1997,7 @@ int mdss_fb_pan_display_ex(struct fb_info *info,
- int ret = 0;
- if (!mfd || (!mfd->op_enable && !mfd->quickdraw_in_progress) ||
- - (!mfd->panel_power_on))
- + (!mdss_fb_is_panel_power_on(mfd)))
- return -EPERM;
- if (var->xoffset > (info->var.xres_virtual - info->var.xres))
- @@ -2044,7 +2048,7 @@ static int mdss_fb_pan_display_sub(struct fb_var_screeninfo *var,
- {
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- - if ((!mfd->op_enable) || (!mfd->panel_power_on))
- + if ((!mfd->op_enable) || (!mdss_fb_is_panel_power_on(mfd)))
- return -EPERM;
- if (var->xoffset > (info->var.xres_virtual - info->var.xres))
- @@ -2345,10 +2349,10 @@ int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state)
- switch (req_state) {
- case DCM_UNBLANK:
- if (mfd->dcm_state == DCM_UNINIT &&
- - !mfd->panel_power_on && mfd->mdp.on_fnc) {
- + !mdss_fb_is_panel_power_on(mfd) && mfd->mdp.on_fnc) {
- ret = mfd->mdp.on_fnc(mfd);
- if (ret == 0) {
- - mfd->panel_power_on = true;
- + mfd->panel_power_state = MDSS_PANEL_POWER_ON;
- mfd->dcm_state = DCM_UNBLANK;
- }
- }
- @@ -2359,24 +2363,24 @@ int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state)
- * Keep unblank path available for only
- * DCM operation
- */
- - mfd->panel_power_on = false;
- + mfd->panel_power_state = MDSS_PANEL_POWER_OFF;
- mfd->dcm_state = DCM_ENTER;
- }
- break;
- case DCM_EXIT:
- if (mfd->dcm_state == DCM_ENTER) {
- /* Release the unblank path for exit */
- - mfd->panel_power_on = true;
- + mfd->panel_power_state = MDSS_PANEL_POWER_ON;
- mfd->dcm_state = DCM_EXIT;
- }
- break;
- case DCM_BLANK:
- if ((mfd->dcm_state == DCM_EXIT ||
- mfd->dcm_state == DCM_UNBLANK) &&
- - mfd->panel_power_on && mfd->mdp.off_fnc) {
- + mdss_fb_is_panel_power_on(mfd) && mfd->mdp.off_fnc) {
- ret = mfd->mdp.off_fnc(mfd);
- if (ret == 0) {
- - mfd->panel_power_on = false;
- + mfd->panel_power_state = MDSS_PANEL_POWER_OFF;
- mfd->dcm_state = DCM_UNINIT;
- }
- }
- @@ -2658,7 +2662,7 @@ static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
- ret = copy_from_user(&buf_sync, argp, sizeof(buf_sync));
- if (ret)
- return ret;
- - if ((!mfd->op_enable) || (!mfd->panel_power_on))
- + if ((!mfd->op_enable) || (!mdss_fb_is_panel_power_on(mfd)))
- return -EPERM;
- if (mfd->mdp.get_sync_fnc)
- sync_pt_data = mfd->mdp.get_sync_fnc(mfd, &buf_sync);
- diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
- index 4256891..f1595af 100644
- --- a/drivers/video/msm/mdss/mdss_fb.h
- +++ b/drivers/video/msm/mdss/mdss_fb.h
- @@ -76,7 +76,7 @@ enum mdp_splash_event {
- struct disp_info_type_suspend {
- int op_enable;
- - int panel_power_on;
- + int panel_power_state;
- };
- struct disp_info_notify {
- @@ -178,7 +178,7 @@ struct msm_fb_data_type {
- int panel_reconfig;
- u32 dst_format;
- - int panel_power_on;
- + int panel_power_state;
- struct disp_info_type_suspend suspend;
- struct ion_handle *ihdl;
- @@ -264,6 +264,11 @@ static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)
- }
- }
- +static inline bool mdss_fb_is_panel_power_on(struct msm_fb_data_type *mfd)
- +{
- + return (mfd->panel_power_state != MDSS_PANEL_POWER_OFF);
- +}
- +
- int mdss_fb_get_phys_info(unsigned long *start, unsigned long *len, int fb_num);
- void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl);
- void mdss_fb_update_backlight(struct msm_fb_data_type *mfd);
- diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
- index 30b683f..d199e65 100644
- --- a/drivers/video/msm/mdss/mdss_mdp.h
- +++ b/drivers/video/msm/mdss/mdss_mdp.h
- @@ -166,7 +166,7 @@ struct mdss_mdp_ctl {
- char __iomem *base;
- char __iomem *wb_base;
- u32 ref_cnt;
- - int power_on;
- + int power_state;
- u32 intf_num;
- u32 intf_type;
- @@ -207,7 +207,7 @@ struct mdss_mdp_ctl {
- u8 roi_changed;
- int (*start_fnc) (struct mdss_mdp_ctl *ctl);
- - int (*stop_fnc) (struct mdss_mdp_ctl *ctl);
- + int (*stop_fnc) (struct mdss_mdp_ctl *ctl, int panel_power_state);
- int (*prepare_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
- int (*display_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
- int (*wait_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
- @@ -485,6 +485,11 @@ static inline u32 mdss_mdp_pingpong_read(struct mdss_mdp_mixer *mixer, u32 reg)
- return readl_relaxed(mixer->pingpong_base + reg);
- }
- +static inline bool mdss_mdp_ctl_is_power_on(struct mdss_mdp_ctl *ctl)
- +{
- + return (ctl->power_state != MDSS_PANEL_POWER_OFF);
- +}
- +
- irqreturn_t mdss_mdp_isr(int irq, void *ptr);
- int mdss_iommu_attach(struct mdss_data_type *mdata);
- int mdss_iommu_dettach(struct mdss_data_type *mdata);
- @@ -539,7 +544,7 @@ int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl,
- struct mdss_panel_data *pdata);
- int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl);
- int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff);
- -int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl);
- +int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl, int panel_power_mode);
- int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg);
- int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
- struct mdss_mdp_pipe **left_plist, int left_cnt,
- diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
- index 9a038e3..c892173 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
- @@ -562,7 +562,7 @@ static u32 mdss_mdp_get_vbp_factor_max(struct mdss_mdp_ctl *ctl)
- struct mdss_mdp_ctl *ctl = mdata->ctl_off + i;
- u32 vbp_fac;
- - if (ctl->power_on) {
- + if (mdss_mdp_ctl_is_power_on(ctl)) {
- vbp_fac = mdss_mdp_get_vbp_factor(ctl);
- vbp_max = max(vbp_max, vbp_fac);
- }
- @@ -787,7 +787,7 @@ static inline void mdss_mdp_ctl_perf_update_bus(struct mdss_mdp_ctl *ctl)
- for (i = 0; i < mdata->nctl; i++) {
- struct mdss_mdp_ctl *ctl;
- ctl = mdata->ctl_off + i;
- - if (ctl->power_on) {
- + if (mdss_mdp_ctl_is_power_on(ctl)) {
- bw_sum_of_intfs += ctl->cur_perf.bw_ctl;
- pr_debug("c=%d bw=%llu\n", ctl->num,
- ctl->cur_perf.bw_ctl);
- @@ -826,8 +826,7 @@ void mdss_mdp_ctl_perf_release_bw(struct mdss_mdp_ctl *ctl)
- */
- for (i = 0; i < mdata->nctl; i++) {
- struct mdss_mdp_ctl *ctl = mdata->ctl_off + i;
- -
- - if (ctl->power_on && ctl->is_video_mode)
- + if (mdss_mdp_ctl_is_power_on(ctl) && ctl->is_video_mode)
- goto exit;
- }
- @@ -868,7 +867,7 @@ static void mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl,
- */
- is_bw_released = !mdss_mdp_ctl_perf_get_transaction_status(ctl);
- - if (ctl->power_on) {
- + if (mdss_mdp_ctl_is_power_on(ctl)) {
- if (is_bw_released || params_changed)
- mdss_mdp_perf_calc_ctl(ctl, new);
- /*
- @@ -908,7 +907,7 @@ static void mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl,
- for (i = 0; i < mdata->nctl; i++) {
- struct mdss_mdp_ctl *ctl;
- ctl = mdata->ctl_off + i;
- - if (ctl->power_on)
- + if (mdss_mdp_ctl_is_power_on(ctl))
- clk_rate = max(ctl->cur_perf.mdp_clk_rate,
- clk_rate);
- }
- @@ -974,7 +973,7 @@ static int mdss_mdp_ctl_free(struct mdss_mdp_ctl *ctl)
- ctl->intf_num = MDSS_MDP_NO_INTF;
- ctl->intf_type = MDSS_MDP_NO_INTF;
- ctl->is_secure = false;
- - ctl->power_on = false;
- + ctl->power_state = MDSS_PANEL_POWER_OFF;
- ctl->start_fnc = NULL;
- ctl->stop_fnc = NULL;
- ctl->prepare_fnc = NULL;
- @@ -1123,7 +1122,7 @@ struct mdss_mdp_mixer *mdss_mdp_wb_mixer_alloc(int rotator)
- ctl->mixer_left = mixer;
- ctl->start_fnc = mdss_mdp_writeback_start;
- - ctl->power_on = true;
- + ctl->power_state = MDSS_PANEL_POWER_ON;
- ctl->wb_type = (rotator ? MDSS_MDP_WB_CTL_TYPE_BLOCK :
- MDSS_MDP_WB_CTL_TYPE_LINE);
- mixer->ctl = ctl;
- @@ -1156,7 +1155,7 @@ int mdss_mdp_wb_mixer_destroy(struct mdss_mdp_mixer *mixer)
- pr_debug("destroy ctl=%d mixer=%d\n", ctl->num, mixer->num);
- if (ctl->stop_fnc)
- - ctl->stop_fnc(ctl);
- + ctl->stop_fnc(ctl, MDSS_PANEL_POWER_OFF);
- mdss_mdp_ctl_free(ctl);
- @@ -1699,11 +1698,13 @@ static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff)
- int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff)
- {
- - struct mdss_mdp_ctl *sctl;
- + struct mdss_mdp_ctl *sctl = mdss_mdp_get_split_ctl(ctl);
- struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- int ret = 0;
- - if (ctl->power_on) {
- + pr_debug("ctl_num=%d, power_state=%d\n", ctl->num, ctl->power_state);
- +
- + if (mdss_mdp_ctl_is_power_on(ctl)) {
- pr_debug("%d: panel already on!\n", __LINE__);
- return 0;
- }
- @@ -1716,14 +1717,14 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff)
- mutex_lock(&ctl->lock);
- + memset(&ctl->cur_perf, 0, sizeof(ctl->cur_perf));
- +
- /*
- * keep power_on false during handoff to avoid unexpected
- * operations to overlay.
- */
- if (!handoff)
- - ctl->power_on = true;
- -
- - memset(&ctl->cur_perf, 0, sizeof(ctl->cur_perf));
- + ctl->power_state = MDSS_PANEL_POWER_ON;
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- @@ -1753,29 +1754,29 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff)
- }
- mdss_mdp_hist_intr_setup(&mdata->hist_intr, MDSS_IRQ_RESUME);
- - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- error:
- + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- mutex_unlock(&ctl->lock);
- return ret;
- }
- -int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl)
- +int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl, int power_state)
- {
- struct mdss_mdp_ctl *sctl;
- int ret = 0;
- struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- u32 off;
- - if (!ctl->power_on) {
- + pr_debug("ctl_num=%d, power_state=%d\n", ctl->num, ctl->power_state);
- +
- + if (!mdss_mdp_ctl_is_power_on(ctl)) {
- pr_debug("%s %d already off!\n", __func__, __LINE__);
- return 0;
- }
- sctl = mdss_mdp_get_split_ctl(ctl);
- - pr_debug("ctl_num=%d\n", ctl->num);
- -
- mutex_lock(&ctl->lock);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- @@ -1783,38 +1784,41 @@ int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl)
- mdss_mdp_hist_intr_setup(&mdata->hist_intr, MDSS_IRQ_SUSPEND);
- if (ctl->stop_fnc)
- - ret = ctl->stop_fnc(ctl);
- + ret = ctl->stop_fnc(ctl, power_state);
- else
- pr_warn("no stop func for ctl=%d\n", ctl->num);
- if (sctl && sctl->stop_fnc) {
- - ret = sctl->stop_fnc(sctl);
- + ret = sctl->stop_fnc(sctl, power_state);
- mdss_mdp_ctl_split_display_enable(0, ctl, sctl);
- }
- -
- if (ret) {
- pr_warn("error powering off intf ctl=%d\n", ctl->num);
- - } else {
- - mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, 0);
- - if (sctl)
- - mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_TOP, 0);
- + goto end;
- + }
- - if (ctl->mixer_left) {
- - off = __mdss_mdp_ctl_get_mixer_off(ctl->mixer_left);
- - mdss_mdp_ctl_write(ctl, off, 0);
- - }
- + mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, 0);
- + if (sctl)
- + mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_TOP, 0);
- - if (ctl->mixer_right) {
- - off = __mdss_mdp_ctl_get_mixer_off(ctl->mixer_right);
- - mdss_mdp_ctl_write(ctl, off, 0);
- - }
- + if (ctl->mixer_left) {
- + off = __mdss_mdp_ctl_get_mixer_off(ctl->mixer_left);
- + mdss_mdp_ctl_write(ctl, off, 0);
- + }
- - ctl->power_on = false;
- - ctl->play_cnt = 0;
- - mdss_mdp_ctl_perf_update(ctl, 0);
- + if (ctl->mixer_right) {
- + off = __mdss_mdp_ctl_get_mixer_off(ctl->mixer_right);
- + mdss_mdp_ctl_write(ctl, off, 0);
- }
- + ctl->play_cnt = 0;
- + mdss_mdp_ctl_perf_update(ctl, 0);
- +
- +end:
- + if (!ret)
- + ctl->power_state = power_state;
- +
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- mutex_unlock(&ctl->lock);
- @@ -2400,7 +2404,7 @@ int mdss_mdp_display_wait4comp(struct mdss_mdp_ctl *ctl)
- if (ret)
- return ret;
- - if (!ctl->power_on) {
- + if (!mdss_mdp_ctl_is_power_on(ctl)) {
- mutex_unlock(&ctl->lock);
- return 0;
- }
- @@ -2423,7 +2427,7 @@ int mdss_mdp_display_wait4pingpong(struct mdss_mdp_ctl *ctl)
- if (ret)
- return ret;
- - if (!ctl->power_on) {
- + if (!mdss_mdp_ctl_is_power_on(ctl)) {
- mutex_unlock(&ctl->lock);
- return 0;
- }
- @@ -2451,7 +2455,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
- mutex_lock(&ctl->lock);
- pr_debug("commit ctl=%d play_cnt=%d\n", ctl->num, ctl->play_cnt);
- - if (!ctl->power_on) {
- + if (!mdss_mdp_ctl_is_power_on(ctl)) {
- mutex_unlock(&ctl->lock);
- return 0;
- }
- @@ -2556,7 +2560,7 @@ int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id)
- mdata = mdss_mdp_get_mdata();
- for (i = 0; i < mdata->nctl; i++) {
- ctl = mdata->ctl_off + i;
- - if ((ctl->power_on) && (ctl->mfd) &&
- + if ((mdss_mdp_ctl_is_power_on(ctl)) && (ctl->mfd) &&
- (ctl->mfd->index == fb_num)) {
- if (ctl->mixer_left) {
- mixer_id[mixer_cnt] = ctl->mixer_left->num;
- diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- index 11aad01..a4b76f0 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- @@ -40,7 +40,7 @@ struct mdss_mdp_cmd_ctx {
- struct completion pp_comp;
- struct completion stop_comp;
- struct list_head vsync_handlers;
- - int panel_on;
- + int panel_power_state;
- int koff_cnt;
- int clk_enabled;
- int vsync_enabled;
- @@ -64,6 +64,11 @@ struct mdss_mdp_cmd_ctx {
- struct mdss_mdp_cmd_ctx mdss_mdp_cmd_ctx_list[MAX_SESSIONS];
- +static bool __mdss_mdp_cmd_panel_power_on(struct mdss_mdp_cmd_ctx *ctx)
- +{
- + return (ctx->panel_power_state == MDSS_PANEL_POWER_ON);
- +}
- +
- static inline u32 mdss_mdp_cmd_line_count(struct mdss_mdp_ctl *ctl)
- {
- struct mdss_mdp_mixer *mixer;
- @@ -251,7 +256,7 @@ static inline void mdss_mdp_cmd_clk_off(struct mdss_mdp_cmd_ctx *ctx)
- mdss_mdp_ctl_intf_event
- (ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)0);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- - if (ctx->panel_on &&
- + if (!__mdss_mdp_cmd_panel_power_on(ctx) &&
- ctx->ctl->panel_data->panel_info.ulps_feature_enabled)
- schedule_delayed_work(&ctx->ulps_work, ULPS_ENTER_TIME);
- }
- @@ -406,7 +411,7 @@ static void __mdss_mdp_cmd_ulps_work(struct work_struct *work)
- }
- mutex_unlock(&ctx->clk_mtx);
- - if (!ctx->panel_on) {
- + if (!__mdss_mdp_cmd_panel_power_on(ctx)) {
- pr_err("Panel is off. skipping ULPS configuration\n");
- return;
- }
- @@ -569,11 +574,11 @@ int mdss_mdp_cmd_panel_on_locked(struct mdss_mdp_ctl *ctl)
- }
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- - if (ctx->panel_on == 0) {
- + if (!__mdss_mdp_cmd_panel_power_on(ctx)) {
- rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL);
- WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc);
- - ctx->panel_on++;
- + ctx->panel_power_state = MDSS_PANEL_POWER_ON;
- rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL);
- WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc);
- @@ -627,10 +632,9 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
- return 0;
- }
- -int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
- +int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state)
- {
- struct mdss_mdp_cmd_ctx *ctx;
- - struct mdss_panel_info *pinfo;
- unsigned long flags;
- struct mdss_mdp_vsync_handler *tmp, *handle;
- int need_wait = 0;
- @@ -660,22 +664,13 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
- ctx->rdptr_enabled = 0;
- goto skip_wait;
- }
- - if (wait_for_completion_timeout(&ctx->stop_comp, STOP_TIMEOUT)
- - <= 0) {
- + if (wait_for_completion_timeout(&ctx->stop_comp,
- + STOP_TIMEOUT) <= 0) {
- WARN(1, "stop cmd time out\n");
- -
- - if (IS_ERR_OR_NULL(ctl->panel_data)) {
- - pr_err("no panel data\n");
- - } else {
- - pinfo = &ctl->panel_data->panel_info;
- -
- - if (pinfo->panel_dead) {
- - mdss_mdp_irq_disable
- - (MDSS_MDP_IRQ_PING_PONG_RD_PTR,
- - ctx->pp_num);
- - ctx->rdptr_enabled = 0;
- - }
- - }
- + mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
- + ctx->pp_num);
- + ctx->rdptr_enabled = 0;
- + ctx->koff_cnt = 0;
- }
- }
- skip_wait:
- @@ -689,27 +684,21 @@ skip_wait:
- MDSS_EVENT_REGISTER_RECOVERY_HANDLER,
- NULL);
- - turn_off_panel = ctx->panel_on;
- - ctx->panel_on = 0;
- + turn_off_panel = ctx->panel_power_state;
- mdss_mdp_cmd_clk_off(ctx);
- flush_work(&ctx->pp_done_work);
- + ctx->panel_power_state = panel_power_state;
- - mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num,
- - NULL, NULL);
- - mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
- - NULL, NULL);
- -
- - memset(ctx, 0, sizeof(*ctx));
- - ctl->priv_data = NULL;
- -
- - if (turn_off_panel) {
- + if (turn_off_panel != MDSS_PANEL_POWER_OFF) {
- mutex_lock(&ctl->offlock);
- - ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_BLANK, NULL);
- + ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_BLANK,
- + (void *) (long int) panel_power_state);
- WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret);
- - ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF, NULL);
- + ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF,
- + (void *) (long int) panel_power_state);
- WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret);
- mutex_unlock(&ctl->offlock);
- }
- @@ -721,6 +710,14 @@ skip_wait:
- ctl->remove_vsync_handler = NULL;
- ctl->panel_on_locked = NULL;
- + mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num,
- + NULL, NULL);
- + mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
- + NULL, NULL);
- +
- + memset(ctx, 0, sizeof(*ctx));
- + ctl->priv_data = NULL;
- +
- pr_debug("%s:-\n", __func__);
- return 0;
- @@ -731,7 +728,7 @@ void mdss_mdp_cmd_dump_ctx(struct mdss_mdp_ctl *ctl)
- struct mdss_mdp_cmd_ctx *ctx = ctl->priv_data;
- MDSS_TIMEOUT_LOG("pp_num=%u\n", ctx->pp_num);
- - MDSS_TIMEOUT_LOG("panel_on=%d\n", ctx->panel_on);
- + MDSS_TIMEOUT_LOG("panel_on=%d\n", !__mdss_mdp_cmd_panel_power_on(ctx));
- MDSS_TIMEOUT_LOG("koff_cnt=%d\n", ctx->koff_cnt);
- MDSS_TIMEOUT_LOG("clk_enabled=%d\n", ctx->clk_enabled);
- MDSS_TIMEOUT_LOG("vsync_enabled=%d\n", ctx->vsync_enabled);
- diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
- index 6dfcace..d890646 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
- @@ -296,7 +296,7 @@ static int mdss_mdp_video_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
- return 0;
- }
- -static int mdss_mdp_video_stop(struct mdss_mdp_ctl *ctl)
- +static int mdss_mdp_video_stop(struct mdss_mdp_ctl *ctl, int panel_power_state)
- {
- struct mdss_mdp_video_ctx *ctx;
- struct mdss_mdp_vsync_handler *tmp, *handle;
- diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
- index ff55c57..2bdc27d 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
- @@ -348,7 +348,8 @@ exit:
- return ret;
- }
- -static int mdss_mdp_writeback_stop(struct mdss_mdp_ctl *ctl)
- +static int mdss_mdp_writeback_stop(struct mdss_mdp_ctl *ctl,
- + int panel_power_state)
- {
- struct mdss_mdp_writeback_ctx *ctx;
- struct mdss_mdp_vsync_handler *t, *handle;
- diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
- index 0f6204d..9f046d1 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
- @@ -667,7 +667,7 @@ int mdss_mdp_overlay_set(struct msm_fb_data_type *mfd,
- if (ret)
- return ret;
- - if (!mfd->panel_power_on) {
- + if (!mdss_fb_is_panel_power_on(mfd)) {
- mutex_unlock(&mdp5_data->ov_lock);
- return -EPERM;
- }
- @@ -861,7 +861,7 @@ static int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
- struct mdss_data_type *mdata = mfd_to_mdata(mfd);
- struct mdss_mdp_ctl *ctl = mdp5_data->ctl;
- - if (ctl->power_on) {
- + if (mdss_mdp_ctl_is_power_on(ctl)) {
- if (mdp5_data->mdata->ulps) {
- mdss_mdp_footswitch_ctrl_ulps(1, &mfd->pdev->dev);
- mdss_mdp_ctl_restore(ctl);
- @@ -1188,7 +1188,7 @@ int mdss_mdp_overlay_unset(struct msm_fb_data_type *mfd, int ndx)
- goto done;
- }
- - if (!mfd->panel_power_on) {
- + if (!mdss_fb_is_panel_power_on(mfd)) {
- ret = -EPERM;
- goto done;
- }
- @@ -1330,7 +1330,7 @@ int mdss_mdp_overlay_play(struct msm_fb_data_type *mfd,
- if (ret)
- return ret;
- - if (!mfd->panel_power_on) {
- + if (!mdss_fb_is_panel_power_on(mfd)) {
- ret = -EPERM;
- goto done;
- }
- @@ -1497,7 +1497,7 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd,
- if (mutex_lock_interruptible(&mdp5_data->ov_lock))
- return;
- - if (!mfd->panel_power_on) {
- + if (!mdss_fb_is_panel_power_on(mfd)) {
- mutex_unlock(&mdp5_data->ov_lock);
- return;
- }
- @@ -1630,7 +1630,7 @@ int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en)
- if (!ctl->add_vsync_handler || !ctl->remove_vsync_handler)
- return -EOPNOTSUPP;
- if (!ctl->panel_data->panel_info.cont_splash_enabled
- - && !ctl->power_on) {
- + && !mdss_mdp_ctl_is_power_on(ctl)) {
- pr_debug("fb%d vsync pending first update en=%d\n",
- mfd->index, en);
- return -EPERM;
- @@ -1657,7 +1657,7 @@ static ssize_t dynamic_fps_sysfs_rda_dfps(struct device *dev,
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- - if (!mdp5_data->ctl || !mdp5_data->ctl->power_on)
- + if (!mdp5_data->ctl || !mdss_mdp_ctl_is_power_on(mdp5_data->ctl))
- return 0;
- pdata = dev_get_platdata(&mfd->pdev->dev);
- @@ -1689,7 +1689,7 @@ static ssize_t dynamic_fps_sysfs_wta_dfps(struct device *dev,
- return rc;
- }
- - if (!mdp5_data->ctl || !mdp5_data->ctl->power_on)
- + if (!mdp5_data->ctl || !mdss_mdp_ctl_is_power_on(mdp5_data->ctl))
- return 0;
- pdata = dev_get_platdata(&mfd->pdev->dev);
- @@ -1778,7 +1778,7 @@ static ssize_t cabc_mode_store(struct device *dev,
- }
- mutex_lock(&ctl->offlock);
- - if (!mfd->panel_power_on) {
- + if (!mdss_fb_is_panel_power_on(mfd)) {
- pr_warn("panel is powered off\n");
- ret = -EPERM;
- goto unlock;
- @@ -1878,7 +1878,7 @@ static ssize_t te_enable_store(struct device *dev,
- goto end;
- }
- - if (!mfd->panel_power_on) {
- + if (!mdss_fb_is_panel_power_on(mfd)) {
- pr_warning("panel is not powered\n");
- r = -EPERM;
- goto end;
- @@ -1980,7 +1980,7 @@ static ssize_t hbm_store(struct device *dev,
- }
- mutex_lock(&ctl->offlock);
- - if (!mfd->panel_power_on) {
- + if (!mdss_fb_is_panel_power_on(mfd)) {
- pr_warning("panel is not powered\n");
- r = -EPERM;
- goto unlock;
- @@ -2027,7 +2027,7 @@ static ssize_t mdss_mdp_vsync_show_event(struct device *dev,
- if (!mdp5_data->ctl ||
- (!mdp5_data->ctl->panel_data->panel_info.cont_splash_enabled
- - && !mdp5_data->ctl->power_on))
- + && !mdss_mdp_ctl_is_power_on(mdp5_data->ctl)))
- return -EAGAIN;
- vsync_ticks = ktime_to_ns(mdp5_data->vsync_time);
- @@ -2389,7 +2389,7 @@ static int mdss_mdp_histo_ioctl(struct msm_fb_data_type *mfd, u32 cmd,
- switch (cmd) {
- case MSMFB_HISTOGRAM_START:
- - if (!mfd->panel_power_on)
- + if (!mdss_fb_is_panel_power_on(mfd))
- return -EPERM;
- pp_bus_handle = mdss_mdp_get_mdata()->pp_bus_hdl;
- @@ -2425,7 +2425,7 @@ static int mdss_mdp_histo_ioctl(struct msm_fb_data_type *mfd, u32 cmd,
- break;
- case MSMFB_HISTOGRAM:
- - if (!mfd->panel_power_on)
- + if (!mdss_fb_is_panel_power_on(mfd))
- return -EPERM;
- ret = copy_from_user(&hist, argp, sizeof(hist));
- @@ -2459,7 +2459,7 @@ static int mdss_fb_set_metadata(struct msm_fb_data_type *mfd,
- ret = -EINVAL;
- break;
- case metadata_op_crc:
- - if (!mfd->panel_power_on)
- + if (!mdss_fb_is_panel_power_on(mfd))
- return -EPERM;
- ret = mdss_misr_set(mdata, &metadata->data.misr_request, ctl);
- break;
- @@ -2514,7 +2514,7 @@ static int mdss_fb_get_metadata(struct msm_fb_data_type *mfd,
- ret = mdss_fb_get_hw_caps(mfd, &metadata->data.caps);
- break;
- case metadata_op_crc:
- - if (!mfd->panel_power_on)
- + if (!mdss_fb_is_panel_power_on(mfd))
- return -EPERM;
- ret = mdss_misr_get(mdata, &metadata->data.misr_request, ctl);
- break;
- @@ -2549,7 +2549,7 @@ static int __handle_overlay_prepare(struct msm_fb_data_type *mfd,
- if (ret)
- return ret;
- - if (!mfd->panel_power_on) {
- + if (!mdss_fb_is_panel_power_on(mfd)) {
- mutex_unlock(&mdp5_data->ov_lock);
- return -EPERM;
- }
- @@ -2937,7 +2937,7 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
- return -ENODEV;
- }
- - if (!mdp5_data->ctl->power_on)
- + if (!mdss_mdp_ctl_is_power_on(mdp5_data->ctl))
- return 0;
- mdss_mdp_overlay_free_fb_pipe(mfd);
- @@ -2973,7 +2973,7 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
- __vsync_retire_signal(mfd, mdp5_data->retire_cnt);
- }
- - rc = mdss_mdp_ctl_stop(mdp5_data->ctl);
- + rc = mdss_mdp_ctl_stop(mdp5_data->ctl, mfd->panel_power_state);
- if (rc == 0) {
- __mdss_mdp_overlay_free_list_purge(mfd);
- mdss_mdp_ctl_notifier_unregister(mdp5_data->ctl,
- @@ -3262,7 +3262,7 @@ __vsync_retire_get_fence(struct msm_sync_pt_data *sync_pt_data)
- if (!ctl->add_vsync_handler)
- return ERR_PTR(-EOPNOTSUPP);
- - if (!ctl->power_on) {
- + if (!mdss_mdp_ctl_is_power_on(ctl)) {
- pr_debug("fb%d vsync pending first update\n", mfd->index);
- return ERR_PTR(-EPERM);
- }
- diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
- index 4b89a37..23b2f33 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_pp.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
- @@ -1551,7 +1551,7 @@ int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
- /* TODO: have some sort of reader/writer lock to prevent unclocked
- * access while display power is toggled */
- - if (!ctl->mfd->panel_power_on) {
- + if (!mdss_mdp_ctl_is_power_on(ctl)) {
- ret = -EPERM;
- goto error;
- }
- @@ -3699,7 +3699,7 @@ static struct msm_fb_data_type *mdss_get_mfd_from_index(int index)
- for (i = 0; i < mdata->nctl; i++) {
- ctl = mdata->ctl_off + i;
- - if ((ctl->power_on) && (ctl->mfd)
- + if ((mdss_mdp_ctl_is_power_on(ctl)) && (ctl->mfd)
- && (ctl->mfd->index == index))
- out = ctl->mfd;
- }
- diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
- index c021ba5..529d4e0 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_wb.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
- @@ -555,7 +555,7 @@ int mdss_mdp_wb_kickoff(struct msm_fb_data_type *mfd)
- int ret = 0;
- struct mdss_mdp_writeback_arg wb_args;
- - if (!ctl->power_on)
- + if (!mdss_mdp_ctl_is_power_on(ctl))
- return 0;
- memset(&wb_args, 0, sizeof(wb_args));
- diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
- index 76be0cb..db1821c 100644
- --- a/drivers/video/msm/mdss/mdss_panel.h
- +++ b/drivers/video/msm/mdss/mdss_panel.h
- @@ -75,6 +75,16 @@ enum {
- };
- enum {
- + MDSS_PANEL_POWER_OFF = 0,
- + MDSS_PANEL_POWER_ON,
- +};
- +
- +enum {
- + MDSS_PANEL_BLANK_BLANK = 0,
- + MDSS_PANEL_BLANK_UNBLANK,
- +};
- +
- +enum {
- MODE_GPIO_NOT_VALID = 0,
- MODE_GPIO_HIGH,
- MODE_GPIO_LOW,
- @@ -342,7 +352,8 @@ struct mdss_panel_info {
- u32 no_solid_fill;
- u32 partial_update_enabled;
- struct ion_handle *splash_ihdl;
- - u32 panel_power_on;
- + int panel_power_state;
- + int blank_state;
- bool hs_cmds_post_init;
- bool hbm_feature_enabled;
- bool hbm_state;
- @@ -473,6 +484,20 @@ static inline int mdss_panel_get_htotal(struct mdss_panel_info *pinfo)
- pinfo->lcdc.h_pulse_width;
- }
- +/**
- + * mdss_panel_is_panel_power_on: - checks if a panel is on
- + * @pdata: pointer to the panel struct associated to the panel
- + *
- + * A panel is considered to be on as long as it can accept any commands
- + * or data. Sometimes it is posible to program the panel to be in a low
- + * power state. This function returns false only if panel has explicitly
- + * been turned off.
- + */
- +static inline bool mdss_panel_is_panel_power_on(struct mdss_panel_data *pdata)
- +{
- + return (pdata->panel_info.panel_power_state != MDSS_PANEL_POWER_OFF);
- +}
- +
- int mdss_register_panel(struct platform_device *pdev,
- struct mdss_panel_data *pdata);
- void mdss_dsi_lock_panel_mutex(void);
- --
- 2.6.1
- From 815e21e6d17d7e6f3303ed333d544060dc4a5284 Mon Sep 17 00:00:00 2001
- From: Aravind Venkateswaran <aravindh@codeaurora.org>
- Date: Tue, 29 Jul 2014 00:11:45 -0700
- Subject: [PATCH 2/3] msm: mdss: add support for display always on mode
- Add a new panel power state to represent a panel low power mode. Add a
- new sysfs node to control when to configure the panel into this new
- mode.
- [GabrieleM: Adapt code for Motorola msm8226 sources]
- Change-Id: I7df8bf63470bec893c6b7481678f00ce76b6875c
- Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org>
- (cherry picked from commit d5a864dce942e675246d6b8414bdd16add748ac7)
- ---
- drivers/video/msm/mdss/mdss_dsi.c | 39 ++++++++++++++++++++
- drivers/video/msm/mdss/mdss_dsi.h | 1 +
- drivers/video/msm/mdss/mdss_dsi_panel.c | 29 +++++++++++++++
- drivers/video/msm/mdss/mdss_fb.c | 58 ++++++++++++++++++++++++++++--
- drivers/video/msm/mdss/mdss_fb.h | 2 ++
- drivers/video/msm/mdss/mdss_mdp_ctl.c | 10 ++++--
- drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 35 ++++++++++++++++++
- drivers/video/msm/mdss/mdss_mdp_overlay.c | 39 +++++++++++++-------
- drivers/video/msm/mdss/mdss_panel.h | 2 ++
- 9 files changed, 199 insertions(+), 16 deletions(-)
- diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
- index 7db6d09..50f55ab 100644
- --- a/drivers/video/msm/mdss/mdss_dsi.c
- +++ b/drivers/video/msm/mdss/mdss_dsi.c
- @@ -120,6 +120,12 @@ end:
- return ret;
- }
- +static int mdss_dsi_panel_power_doze(struct mdss_panel_data *pdata, int enable)
- +{
- + /* Panel power control when entering/exiting doze mode */
- + return 0;
- +}
- +
- static int mdss_dsi_panel_power_ctrl(struct mdss_panel_data *pdata,
- int power_state)
- {
- @@ -146,6 +152,13 @@ static int mdss_dsi_panel_power_ctrl(struct mdss_panel_data *pdata,
- break;
- case MDSS_PANEL_POWER_ON:
- ret = mdss_dsi_panel_power_on(pdata);
- + if (pinfo->panel_power_state == MDSS_PANEL_POWER_DOZE)
- + ret = mdss_dsi_panel_power_doze(pdata, false);
- + else
- + ret = mdss_dsi_panel_power_on(pdata);
- + break;
- + case MDSS_PANEL_POWER_DOZE:
- + ret = mdss_dsi_panel_power_doze(pdata, true);
- break;
- default:
- pr_err("%s: unknown panel power state requested (%d)\n",
- @@ -391,6 +404,11 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state)
- goto end;
- }
- + if (power_state != MDSS_PANEL_POWER_OFF) {
- + pr_debug("%s: dsi_off with panel always on\n", __func__);
- + goto panel_power_ctrl;
- + }
- +
- if (pdata->panel_info.type == MIPI_CMD_PANEL)
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
- @@ -402,6 +420,7 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state)
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
- +panel_power_ctrl:
- ret = mdss_dsi_panel_power_ctrl(pdata, power_state);
- if (ret)
- pr_err("%s: Panel power off failed\n", __func__);
- @@ -753,6 +772,12 @@ int mdss_dsi_on(struct mdss_panel_data *pdata)
- mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base));
- mdss_dsi_phy_init(pdata);
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 0);
- +
- + if (cur_power_state != MDSS_PANEL_POWER_OFF) {
- + pr_debug("%s: dsi_on from panel low power state\n", __func__);
- + goto end;
- + }
- +
- mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
- __mdss_dsi_ctrl_setup(pdata);
- @@ -805,6 +830,13 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
- pr_debug("%s+: ctrl=%p ndx=%d cur_blank_state=%d\n", __func__,
- ctrl_pdata, ctrl_pdata->ndx, pdata->panel_info.blank_state);
- + if (pdata->panel_info.blank_state == MDSS_PANEL_BLANK_LOW_POWER) {
- + pr_debug("%s: dsi_unblank with panel always on\n", __func__);
- + if (ctrl_pdata->low_power_config)
- + ret = ctrl_pdata->low_power_config(pdata, false);
- + return ret;
- + }
- +
- if (!(ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT)) {
- ret = ctrl_pdata->on(pdata);
- if (ret) {
- @@ -845,6 +877,13 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state)
- pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n",
- __func__, ctrl_pdata, ctrl_pdata->ndx, power_state);
- + if (power_state == MDSS_PANEL_POWER_DOZE) {
- + pr_debug("%s: low power state requested\n", __func__);
- + if (ctrl_pdata->low_power_config)
- + ret = ctrl_pdata->low_power_config(pdata, true);
- + return ret;
- + }
- +
- if (pdata->panel_info.type == MIPI_VIDEO_PANEL &&
- ctrl_pdata->off_cmds.link_state == DSI_LP_MODE) {
- mdss_dsi_sw_reset(pdata);
- diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
- index f3f31db..897bf90 100644
- --- a/drivers/video/msm/mdss/mdss_dsi.h
- +++ b/drivers/video/msm/mdss/mdss_dsi.h
- @@ -263,6 +263,7 @@ struct mdss_dsi_ctrl_pdata {
- int ndx; /* panel_num */
- int (*on) (struct mdss_panel_data *pdata);
- int (*off) (struct mdss_panel_data *pdata);
- + int (*low_power_config) (struct mdss_panel_data *pdata, int enable);
- int (*partial_update_fnc) (struct mdss_panel_data *pdata);
- int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
- int (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp,
- diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
- index da915f7..1f8e8e4 100644
- --- a/drivers/video/msm/mdss/mdss_dsi_panel.c
- +++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
- @@ -946,6 +946,34 @@ disable_regs:
- return 0;
- }
- +static int mdss_dsi_panel_low_power_config(struct mdss_panel_data *pdata,
- + int enable)
- +{
- + struct mdss_dsi_ctrl_pdata *ctrl = NULL;
- + struct mdss_panel_info *pinfo;
- +
- + if (pdata == NULL) {
- + pr_err("%s: Invalid input data\n", __func__);
- + return -EINVAL;
- + }
- +
- + pinfo = &pdata->panel_info;
- + ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata,
- + panel_data);
- +
- + pr_debug("%s: ctrl=%p ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx,
- + enable);
- +
- + /* Any panel specific low power commands/config */
- + if (enable)
- + pinfo->blank_state = MDSS_PANEL_BLANK_LOW_POWER;
- + else
- + pinfo->blank_state = MDSS_PANEL_BLANK_UNBLANK;
- +
- + pr_debug("%s:-\n", __func__);
- + return 0;
- +}
- +
- static void mdss_dsi_parse_lane_swap(struct device_node *np, char *dlane_swap)
- {
- const char *data;
- @@ -2159,6 +2187,7 @@ int mdss_dsi_panel_init(struct device_node *node,
- ctrl_pdata->on = mdss_dsi_panel_on;
- ctrl_pdata->off = mdss_dsi_panel_off;
- + ctrl_pdata->low_power_config = mdss_dsi_panel_low_power_config;
- ctrl_pdata->panel_data.set_backlight = mdss_dsi_panel_bl_ctrl;
- ctrl_pdata->cont_splash_on = mdss_dsi_panel_cont_splash_on;
- ctrl_pdata->check_status_disabled =
- diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
- index fa41c68..69000585 100644
- --- a/drivers/video/msm/mdss/mdss_fb.c
- +++ b/drivers/video/msm/mdss/mdss_fb.c
- @@ -440,6 +440,38 @@ static ssize_t mdss_fb_get_idle_notify(struct device *dev,
- return ret;
- }
- +static ssize_t mdss_fb_set_doze_mode(struct device *dev,
- + struct device_attribute *attr, const char *buf, size_t count)
- +{
- + struct fb_info *fbi = dev_get_drvdata(dev);
- + struct msm_fb_data_type *mfd = fbi->par;
- + int rc = 0;
- + int doze_mode = 0;
- +
- + rc = kstrtoint(buf, 10, &doze_mode);
- + if (rc) {
- + pr_err("kstrtoint failed. rc=%d\n", rc);
- + return rc;
- + }
- +
- + pr_debug("Always-on mode %s\n", doze_mode ? "enabled" : "disabled");
- + if (mfd->panel_info->type != MIPI_CMD_PANEL)
- + pr_err("Always on mode only supported for cmd mode panel\n");
- + else
- + mfd->doze_mode = doze_mode;
- +
- + return count;
- +}
- +
- +static ssize_t mdss_fb_get_doze_mode(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + struct fb_info *fbi = dev_get_drvdata(dev);
- + struct msm_fb_data_type *mfd = fbi->par;
- +
- + return scnprintf(buf, PAGE_SIZE, "%d\n", mfd->doze_mode);
- +}
- +
- static DEVICE_ATTR(msm_fb_type, S_IRUGO, mdss_fb_get_type, NULL);
- static DEVICE_ATTR(msm_fb_split, S_IRUGO, mdss_fb_get_split, NULL);
- static DEVICE_ATTR(show_blank_event, S_IRUGO, mdss_mdp_show_blank_event, NULL);
- @@ -447,6 +479,8 @@ static DEVICE_ATTR(idle_time, S_IRUGO | S_IWUSR | S_IWGRP,
- mdss_fb_get_idle_time, mdss_fb_set_idle_time);
- static DEVICE_ATTR(idle_notify, S_IRUGO, mdss_fb_get_idle_notify, NULL);
- static DEVICE_ATTR(rgb, S_IRUGO | S_IWUSR | S_IWGRP, mdss_get_rgb, mdss_set_rgb);
- +static DEVICE_ATTR(always_on, S_IRUGO | S_IWUSR | S_IWGRP,
- + mdss_fb_get_doze_mode, mdss_fb_set_doze_mode);
- static struct attribute *mdss_fb_attrs[] = {
- &dev_attr_msm_fb_type.attr,
- @@ -455,6 +489,7 @@ static struct attribute *mdss_fb_attrs[] = {
- &dev_attr_idle_time.attr,
- &dev_attr_idle_notify.attr,
- &dev_attr_rgb.attr,
- + &dev_attr_always_on.attr,
- NULL,
- };
- @@ -770,8 +805,15 @@ static int mdss_fb_suspend_sub(struct msm_fb_data_type *mfd)
- mfd->suspend.panel_power_state = mfd->panel_power_state;
- if (mfd->op_enable) {
- - ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, mfd->fbi,
- - mfd->suspend.op_enable);
- + /*
- + * Ideally, display should have been blanked by now.
- + * If not, then blank the display based on whether always-on
- + * feature is enabled or not
- + */
- + int unblank_flag = mfd->doze_mode ? FB_BLANK_VSYNC_SUSPEND :
- + FB_BLANK_POWERDOWN;
- + ret = mdss_fb_blank_sub(unblank_flag, mfd->fbi,
- + mfd->suspend.op_enable);
- if (ret) {
- pr_warn("can't turn off display!\n");
- return ret;
- @@ -931,6 +973,13 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl)
- int (*update_ad_input)(struct msm_fb_data_type *mfd);
- u32 temp = bkl_lvl;
- + /* todo: temporary workaround to support doze mode */
- + if ((bkl_lvl == 0) && (mfd->doze_mode)) {
- + pr_debug("keeping backlight on with always-on displays\n");
- + mfd->unset_bl_level = 0;
- + return;
- + }
- +
- if (((!mdss_fb_is_panel_power_on(mfd) && mfd->dcm_state != DCM_ENTER)
- || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) {
- mfd->unset_bl_level = bkl_lvl;
- @@ -1036,6 +1085,8 @@ int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable)
- break;
- case FB_BLANK_VSYNC_SUSPEND:
- + req_power_state = MDSS_PANEL_POWER_DOZE;
- + pr_debug("Doze power mode requested\n");
- case FB_BLANK_HSYNC_SUSPEND:
- case FB_BLANK_NORMAL:
- case FB_BLANK_POWERDOWN:
- @@ -1093,6 +1144,8 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info)
- if (mfd->op_enable == 0) {
- if (blank_mode == FB_BLANK_UNBLANK)
- mfd->suspend.panel_power_state = MDSS_PANEL_POWER_ON;
- + else if (blank_mode == FB_BLANK_VSYNC_SUSPEND)
- + mfd->suspend.panel_power_state = MDSS_PANEL_POWER_DOZE;
- else
- mfd->suspend.panel_power_state = MDSS_PANEL_POWER_OFF;
- return 0;
- @@ -2346,6 +2399,7 @@ int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state)
- return ret;
- }
- + /* todo: this needs to be checked */
- switch (req_state) {
- case DCM_UNBLANK:
- if (mfd->dcm_state == DCM_UNINIT &&
- diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
- index f1595af..78d5fd8 100644
- --- a/drivers/video/msm/mdss/mdss_fb.h
- +++ b/drivers/video/msm/mdss/mdss_fb.h
- @@ -235,6 +235,8 @@ struct msm_fb_data_type {
- bool quickdraw_in_progress;
- u32 quickdraw_panel_state;
- bool quickdraw_reset_panel;
- +
- + int doze_mode;
- };
- struct sys_panelinfo {
- diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
- index c892173..12dd0c5 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
- @@ -1704,7 +1704,7 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff)
- pr_debug("ctl_num=%d, power_state=%d\n", ctl->num, ctl->power_state);
- - if (mdss_mdp_ctl_is_power_on(ctl)) {
- + if (ctl->power_state == MDSS_PANEL_POWER_ON) {
- pr_debug("%d: panel already on!\n", __LINE__);
- return 0;
- }
- @@ -1717,7 +1717,8 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff)
- mutex_lock(&ctl->lock);
- - memset(&ctl->cur_perf, 0, sizeof(ctl->cur_perf));
- + if (ctl->power_state == MDSS_PANEL_POWER_OFF)
- + memset(&ctl->cur_perf, 0, sizeof(ctl->cur_perf));
- /*
- * keep power_on false during handoff to avoid unexpected
- @@ -1798,6 +1799,11 @@ int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl, int power_state)
- goto end;
- }
- + if (power_state != MDSS_PANEL_POWER_OFF) {
- + pr_debug("panel is not off, leaving ctl power on\n");
- + goto end;
- + }
- +
- mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, 0);
- if (sctl)
- mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_TOP, 0);
- diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- index a4b76f0..61c749c 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- @@ -632,6 +632,17 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
- return 0;
- }
- +int mdss_mdp_cmd_restore(struct mdss_mdp_ctl *ctl)
- +{
- + pr_debug("%s: called for ctl%d\n", __func__, ctl->num);
- + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- + if (mdss_mdp_cmd_tearcheck_setup(ctl, true))
- + pr_warn("%s: tearcheck setup failed\n", __func__);
- + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- +
- + return 0;
- +}
- +
- int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state)
- {
- struct mdss_mdp_cmd_ctx *ctx;
- @@ -710,6 +721,11 @@ skip_wait:
- ctl->remove_vsync_handler = NULL;
- ctl->panel_on_locked = NULL;
- + if (panel_power_state != MDSS_PANEL_POWER_OFF) {
- + pr_debug("%s: cmd_off with panel always on\n", __func__);
- + goto end;
- + }
- +
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num,
- NULL, NULL);
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
- @@ -718,6 +734,7 @@ skip_wait:
- memset(ctx, 0, sizeof(*ctx));
- ctl->priv_data = NULL;
- +end:
- pr_debug("%s:-\n", __func__);
- return 0;
- @@ -743,6 +760,24 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl)
- pr_debug("%s:+\n", __func__);
- + if (!ctl)
- + return -EINVAL;
- +
- + ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
- + if (ctx && (ctx->panel_power_state != MDSS_PANEL_POWER_OFF)) {
- + pr_debug("%s: cmd_start with panel always on\n",
- + __func__);
- + /*
- + * It is possible that the resume was called from the panel
- + * always on state without MDSS every power-collapsed (such
- + * as a case with any other interfaces connected). In such
- + * cases, we need to explictly call the restore function to
- + * enable tearcheck logic.
- + */
- + mdss_mdp_cmd_restore(ctl);
- + return 0;
- + }
- +
- mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT);
- if (!mixer) {
- pr_err("mixer not setup correctly\n");
- diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
- index 9f046d1..44dc8e1 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
- @@ -2883,6 +2883,12 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
- mdp5_data->ctl = ctl;
- }
- + if (mdss_fb_is_panel_power_on(mfd)) {
- + pr_debug("panel was never turned off\n");
- + rc = mdss_mdp_ctl_start(mdp5_data->ctl, false);
- + goto panel_on;
- + }
- +
- if (!mfd->panel_info->cont_splash_enabled &&
- (mfd->panel_info->type != DTV_PANEL)) {
- rc = mdss_mdp_overlay_start(mfd);
- @@ -2907,6 +2913,7 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
- return rc;
- }
- +panel_on:
- if (IS_ERR_VALUE(rc)) {
- pr_err("Failed to turn on fb%d\n", mfd->index);
- mdss_mdp_overlay_off(mfd);
- @@ -2940,6 +2947,11 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
- if (!mdss_mdp_ctl_is_power_on(mdp5_data->ctl))
- return 0;
- + if (mfd->panel_power_state != MDSS_PANEL_POWER_OFF) {
- + pr_debug("panel not turned off. keeping overlay on\n");
- + goto ctl_stop;
- + }
- +
- mdss_mdp_overlay_free_fb_pipe(mfd);
- mixer = mdss_mdp_mixer_get(mdp5_data->ctl, MDSS_MDP_MIXER_MUX_LEFT);
- @@ -2973,22 +2985,25 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
- __vsync_retire_signal(mfd, mdp5_data->retire_cnt);
- }
- +ctl_stop:
- rc = mdss_mdp_ctl_stop(mdp5_data->ctl, mfd->panel_power_state);
- if (rc == 0) {
- - __mdss_mdp_overlay_free_list_purge(mfd);
- - mdss_mdp_ctl_notifier_unregister(mdp5_data->ctl,
- - &mfd->mdp_sync_pt_data.notifier);
- -
- - if (!mfd->ref_cnt) {
- - mdp5_data->borderfill_enable = false;
- - mdss_mdp_ctl_destroy(mdp5_data->ctl);
- - mdp5_data->ctl = NULL;
- - }
- + if (mfd->panel_power_state == MDSS_PANEL_POWER_OFF) {
- + __mdss_mdp_overlay_free_list_purge(mfd);
- + mdss_mdp_ctl_notifier_unregister(mdp5_data->ctl,
- + &mfd->mdp_sync_pt_data.notifier);
- +
- + if (!mfd->ref_cnt) {
- + mdp5_data->borderfill_enable = false;
- + mdss_mdp_ctl_destroy(mdp5_data->ctl);
- + mdp5_data->ctl = NULL;
- + }
- - if (atomic_dec_return(&ov_active_panels) == 0)
- - mdss_mdp_rotator_release_all();
- + if (atomic_dec_return(&ov_active_panels) == 0)
- + mdss_mdp_rotator_release_all();
- - mdss_mdp_footswitch_ctrl(mdata, false);
- + mdss_mdp_footswitch_ctrl(mdata, false);
- + }
- }
- return rc;
- diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
- index db1821c..ea4378c 100644
- --- a/drivers/video/msm/mdss/mdss_panel.h
- +++ b/drivers/video/msm/mdss/mdss_panel.h
- @@ -77,11 +77,13 @@ enum {
- enum {
- MDSS_PANEL_POWER_OFF = 0,
- MDSS_PANEL_POWER_ON,
- + MDSS_PANEL_POWER_DOZE,
- };
- enum {
- MDSS_PANEL_BLANK_BLANK = 0,
- MDSS_PANEL_BLANK_UNBLANK,
- + MDSS_PANEL_BLANK_LOW_POWER,
- };
- enum {
- --
- 2.6.1
- From 2041a68828f1b87b2c8cccac8087dff07f5d614e Mon Sep 17 00:00:00 2001
- From: Aravind Venkateswaran <aravindh@codeaurora.org>
- Date: Fri, 15 Aug 2014 17:04:35 -0700
- Subject: [PATCH 3/3] msm: mdss: support transition from suspend to doze mode
- If a transition from full suspend to doze mode is requested, first
- unblank the panel and then enter the doze mode.
- [GabrieleM: Adapt code for Motorola msm8226 sources]
- Change-Id: I8c4e55bc320aeed948bc725cba78460a234d1193
- Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org>
- ---
- drivers/video/msm/mdss/mdss_fb.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
- diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
- index 69000585..a048ef5 100644
- --- a/drivers/video/msm/mdss/mdss_fb.c
- +++ b/drivers/video/msm/mdss/mdss_fb.c
- @@ -1093,6 +1093,17 @@ int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, int op_enable)
- default:
- pr_debug("blank powerdown called. cur mode=%d, req mode=%d\n",
- cur_power_state, req_power_state);
- + /*
- + * If doze mode is requested when panel is already off,
- + * then first unblank the panel before entering doze mode
- + */
- + if ((MDSS_PANEL_POWER_DOZE == req_power_state) &&
- + !mdss_fb_is_panel_power_on(mfd) && mfd->mdp.on_fnc) {
- + pr_debug("off --> doze. switch to on first\n");
- + ret = mfd->mdp.on_fnc(mfd);
- + if (ret == 0)
- + mfd->panel_power_state = MDSS_PANEL_POWER_ON;
- + }
- if (mdss_fb_is_panel_power_on(mfd) && mfd->mdp.off_fnc) {
- cur_power_state = mfd->panel_power_state;
- mutex_lock(&mfd->update.lock);
- --
- 2.6.1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement