diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index cbae1267d7..810e1261b4 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -3889,6 +3889,17 @@ int dsi_panel_set_lp1(struct dsi_panel *panel) if (!panel->panel_initialized) goto exit; + /* + * Consider LP1->LP2->LP1. + * If the panel is already in LP mode, do not need to + * set the regulator. + * IBB and AB power mode would be set at the same time + * in PMIC driver, so we only call ibb setting that is enough. + */ + if (dsi_panel_is_type_oled(panel) && + panel->power_mode != SDE_MODE_DPMS_LP2) + dsi_pwr_panel_regulator_mode_set(&panel->power_info, + "ibb", REGULATOR_MODE_IDLE); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_LP1); if (rc) DSI_ERR("[%s] failed to send DSI_CMD_SET_LP1 cmd, rc=%d\n", @@ -3933,6 +3944,13 @@ int dsi_panel_set_nolp(struct dsi_panel *panel) if (!panel->panel_initialized) goto exit; + /* + * Consider about LP1->LP2->NOLP. + */ + if (dsi_panel_is_type_oled(panel) && + (panel->power_mode == SDE_MODE_DPMS_LP2)) + dsi_pwr_panel_regulator_mode_set(&panel->power_info, + "ibb", REGULATOR_MODE_NORMAL); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_NOLP); if (rc) DSI_ERR("[%s] failed to send DSI_CMD_SET_NOLP cmd, rc=%d\n", @@ -4333,6 +4351,15 @@ int dsi_panel_disable(struct dsi_panel *panel) /* Avoid sending panel off commands when ESD recovery is underway */ if (!atomic_read(&panel->esd_recovery_pending)) { + /* + * Need to set IBB/AB regulator mode to STANDBY, + * if panel is going off from AOD mode. + */ + if (dsi_panel_is_type_oled(panel) && + (panel->power_mode == SDE_MODE_DPMS_LP1 || + panel->power_mode == SDE_MODE_DPMS_LP2)) + dsi_pwr_panel_regulator_mode_set(&panel->power_info, + "ibb", REGULATOR_MODE_STANDBY); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_OFF); if (rc) { /* @@ -4347,6 +4374,7 @@ int dsi_panel_disable(struct dsi_panel *panel) } } panel->panel_initialized = false; + panel->power_mode = SDE_MODE_DPMS_OFF; mutex_unlock(&panel->panel_lock); return rc; diff --git a/msm/dsi/dsi_pwr.c b/msm/dsi/dsi_pwr.c index ed1d532578..4a57242d90 100644 --- a/msm/dsi/dsi_pwr.c +++ b/msm/dsi/dsi_pwr.c @@ -378,3 +378,51 @@ int dsi_pwr_enable_regulator(struct dsi_regulator_info *regs, bool enable) return rc; } + +/* + * dsi_pwr_panel_regulator_mode_set() + * set the AB/IBB regulator mode for OLED panel + * AOD mode entry and exit + * @regs: Pointer to set of regulators to enable or disable. + * @reg_name: Name of panel power we want to set. + * @retulator_mode: Regulator mode values, like: + * REGULATOR_MODE_INVALID + * REGULATOR_MODE_FAST + * REGULATOR_MODE_NORMAL + * REGULATOR_MODE_IDLE + * REGULATOR_MODE_STANDBY + * + * return: error code in case of failure or 0 for success. + */ +int dsi_pwr_panel_regulator_mode_set(struct dsi_regulator_info *regs, + const char *reg_name, + int regulator_mode) +{ + int i = 0, rc = 0; + struct dsi_vreg *vreg; + + if (regs->count == 0) + return -EINVAL; + + if (!regs->vregs) + return -EINVAL; + + for (i = 0; i < regs->count; i++) { + vreg = ®s->vregs[i]; + if (!strcmp(vreg->vreg_name, reg_name)) { + rc = regulator_set_mode(vreg->vreg, + regulator_mode); + if (rc) + DSI_ERR("Regulator %s set mode %d failed\n", + vreg->vreg_name, rc); + break; + } + } + + if (i >= regs->count) { + DSI_ERR("Regulator %s was not found\n", reg_name); + return -EINVAL; + } + + return rc; +} diff --git a/msm/dsi/dsi_pwr.h b/msm/dsi/dsi_pwr.h index 019dd84987..fd9ef2c18d 100644 --- a/msm/dsi/dsi_pwr.h +++ b/msm/dsi/dsi_pwr.h @@ -85,4 +85,22 @@ int dsi_pwr_get_dt_vreg_data(struct device *dev, * return: error code in case of failure or 0 for success. */ int dsi_pwr_enable_regulator(struct dsi_regulator_info *regs, bool enable); + +/** + * dsi_pwr_panel_regulator_mode_set() + * set regulator mode for OLED panel + * @regs: Pointer to set of regulators to enable or disable. + * @reg_name: Panel regulator name + * @regulator_mode: Regulator mode values, like: + * REGULATOR_MODE_INVALID + * REGULATOR_MODE_FAST + * REGULATOR_MODE_NORMAL + * REGULATOR_MODE_IDLE + * REGULATOR_MODE_STANDBY + * + * return: error code in case of failure or 0 for success. + */ +int dsi_pwr_panel_regulator_mode_set(struct dsi_regulator_info *regs, + const char *reg_name, + int regulator_mode); #endif /* _DSI_PWR_H_ */