Explorar el Código

disp: msm: config AB/IBB power when AOD mode enter/exit

ELVDD/ELVSS has a dip during AMODE panel AOD exit hand-off.
According to PMIC team's suggestion, need to config the AB/IBB power
to REGULATOR_MODE_IDLE/REGULATOR_MODE_NORMAL to fix dips.

Change-Id: Ia5cbd4d698de262e02a660f670865c03dda1e04a
Signed-off-by: Wenjun Zhang <[email protected]>
Signed-off-by: Yuan Zhao <[email protected]>
Yuan Zhao hace 6 años
padre
commit
2da9889075
Se han modificado 3 ficheros con 94 adiciones y 0 borrados
  1. 28 0
      msm/dsi/dsi_panel.c
  2. 48 0
      msm/dsi/dsi_pwr.c
  3. 18 0
      msm/dsi/dsi_pwr.h

+ 28 - 0
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;

+ 48 - 0
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 = &regs->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;
+}

+ 18 - 0
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_ */