Snap for 10302501 from fcc1c561eb0294b732aeda55fa3c1f4a8e989cac to android13-gs-pixel-5.10-release

Change-Id: I6660fa43a533adc8681d5de4705f5666be5c76b5
diff --git a/display/panel-samsung-ana6707-f10.c b/display/panel-samsung-ana6707-f10.c
index a679640..83e671a 100644
--- a/display/panel-samsung-ana6707-f10.c
+++ b/display/panel-samsung-ana6707-f10.c
@@ -103,6 +103,11 @@
 	bool delayed_idle;
 	/** @tzd: thermal zone struct */
 	struct thermal_zone_device *tzd;
+	/**
+	 * @is_pixel_off: pixel-off command is sent to panel. Only sending normal-on or resetting
+	 *			panel can recover to normal mode after entering pixel-off state.
+	 */
+	bool is_pixel_off;
 };
 
 #define to_spanel(ctx) container_of(ctx, struct ana6707_f10_panel, base)
@@ -138,14 +143,25 @@
 static const u8 early_exit_global_para[] = { 0xB0, 0x05 };
 static const u8 mode_set_60hz[] = { 0x60, 0x08 };
 static const u8 mode_set_120hz[] = { 0x60, 0x00 };
+static const u8 pixel_off[] = { 0x22 };
+static const u8 normal_on[] = { 0x13 };
 
 static const struct exynos_dsi_cmd ana6707_f10_off_cmds[] = {
-	EXYNOS_DSI_CMD_SEQ(0xF0, 0x5A, 0x5A),
-	EXYNOS_DSI_CMD_SEQ(0xB0, 0x10),
-	EXYNOS_DSI_CMD_SEQ(0xEF, 0x03, 0x03),
-	EXYNOS_DSI_CMD_SEQ(0xF7, 0x07),
-	EXYNOS_DSI_CMD_SEQ(0xF0, 0xA5, 0xA5),
-	EXYNOS_DSI_CMD(display_off, 20),
+	EXYNOS_DSI_CMD_REV(display_off, 20, PANEL_REV_LT(PANEL_REV_DVT1)),
+	EXYNOS_DSI_CMD_REV(display_off, 0, PANEL_REV_GE(PANEL_REV_DVT1)),
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xB0, 0x0E),
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xF3, 0x10),
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xB0, 0x9B),
+	/* VLIN 7.9V */
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xF3, 0x23, 0x02),
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xB0, 0x9A),
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xF3, 0xF6),
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xB0, 0x16),
+	/* VGH 7.4V */
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xF4, 0x30, 0x22),
+	EXYNOS_DSI_CMD_SEQ_REV(PANEL_REV_GE(PANEL_REV_DVT1), 0xB0, 0x1B),
+	/* VREG 5.9V */
+	EXYNOS_DSI_CMD_SEQ_DELAY_REV(PANEL_REV_GE(PANEL_REV_DVT1), 20, 0xF4, 0x0E),
 	EXYNOS_DSI_CMD(sleep_in, 120),
 };
 static DEFINE_EXYNOS_CMD_SET(ana6707_f10_off);
@@ -346,6 +362,47 @@
 	.manual_mode_hlpm_cmd_set = &ana6707_f10_60hz_manual_mode_hlpm_cmd_set,
 };
 
+static void ana6707_f10_set_voltage(struct exynos_panel *ctx, bool enable)
+{
+	if (ctx->panel_rev < PANEL_REV_DVT1)
+		return;
+
+	dev_dbg(ctx->dev, "%s enable = %d\n", __func__, enable);
+	EXYNOS_DCS_WRITE_TABLE(ctx, unlock_cmd_f0);
+
+	if (enable) {
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x0E);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF3, 0x10);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x9B);
+		/* VLIN 7.3V */
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF3, 0x23, 0x0E);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x9A);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF3, 0xF6);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x16);
+		/* VGH 6.7V */
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF4, 0x00, 0xBB);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x1B);
+		/* VREG 6.5V */
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF4, 0x14);
+	} else {
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x0E);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF3, 0x10);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x9B);
+		/* VLIN 7.9V */
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF3, 0x23, 0x02);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x9A);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF3, 0xF6);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x16);
+		/* VGH 7.4V */
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF4, 0x30, 0x22);
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xB0, 0x1B);
+		/* VREG 5.9V */
+		EXYNOS_DCS_WRITE_SEQ(ctx, 0xF4, 0x0E);
+	}
+
+	EXYNOS_DCS_WRITE_TABLE(ctx, lock_cmd_f0);
+}
+
 static inline bool is_auto_mode_preferred(struct exynos_panel *ctx)
 {
 	return ctx->panel_idle_enabled;
@@ -652,6 +709,8 @@
 
 	EXYNOS_DCS_WRITE_SEQ_DELAY(ctx, 10, 0x11); /* sleep out: 10ms delay */
 
+	ana6707_f10_set_voltage(ctx, false);
+
 	exynos_dcs_compression_mode(ctx, 0x1); /* DSC_DEC_ON */
 	EXYNOS_DCS_WRITE_TABLE(ctx, pps_setting);
 	EXYNOS_DCS_WRITE_TABLE(ctx, update_key);
@@ -697,6 +756,8 @@
 
 	EXYNOS_DCS_WRITE_SEQ_DELAY(ctx, delay, 0x53, 0x20); /* backlight control */
 
+	ana6707_f10_set_voltage(ctx, true);
+
 	ctx->enabled = true;
 	if (pmode->exynos_mode.is_lp_mode) {
 		exynos_panel_set_lp_mode(ctx, pmode);
@@ -849,14 +910,18 @@
 	if (unlikely(!pmode))
 		return false;
 
+	/* self refresh is not supported in lp mode since that always makes use of early exit */
+	if (pmode->exynos_mode.is_lp_mode) {
+		/* set 1Hz while self refresh is active, otherwise clear it */
+		ctx->panel_idle_vrefresh = enable ? 1 : 0;
+		backlight_state_changed(ctx->bl);
+		return false;
+	}
+
 	mdata = pmode->priv_data;
 	if (unlikely(!mdata))
 		return false;
 
-	/* self refresh is not supported in lp mode since that always makes use of early exit */
-	if (pmode->exynos_mode.is_lp_mode)
-		return false;
-
 	idle_vrefresh = ana6707_f10_get_min_idle_vrefresh(ctx, pmode);
 
 	if (pmode->idle_mode != IDLE_MODE_ON_SELF_REFRESH) {
@@ -1053,6 +1118,43 @@
 	return 0;
 }
 
+static int ana6707_f10_set_brightness(struct exynos_panel *ctx, u16 br)
+{
+	u16 brightness;
+	struct ana6707_f10_panel *spanel = to_spanel(ctx);
+
+	if (ctx->current_mode->exynos_mode.is_lp_mode) {
+		const struct exynos_panel_funcs *funcs;
+
+		/* don't stay at pixel-off state in AOD, or black screen is possibly seen */
+		if (spanel->is_pixel_off) {
+			EXYNOS_DCS_WRITE_TABLE(ctx, normal_on);
+			spanel->is_pixel_off = false;
+		}
+		funcs = ctx->desc->exynos_panel_func;
+		if (funcs && funcs->set_binned_lp)
+			funcs->set_binned_lp(ctx, br);
+		return 0;
+	}
+
+	/* Use pixel off command instead of setting DBV 0 */
+	if (!br) {
+		if (!spanel->is_pixel_off) {
+			EXYNOS_DCS_WRITE_TABLE(ctx, pixel_off);
+			spanel->is_pixel_off = true;
+			dev_dbg(ctx->dev, "%s: pixel off instead of dbv 0\n", __func__);
+		}
+		return 0;
+	} else if (br && spanel->is_pixel_off) {
+		EXYNOS_DCS_WRITE_TABLE(ctx, normal_on);
+		spanel->is_pixel_off = false;
+	}
+
+	brightness = (br & 0xff) << 8 | br >> 8;
+
+	return exynos_dcs_set_brightness(ctx, brightness);
+}
+
 static const struct exynos_display_underrun_param underrun_param = {
 	.te_idle_us = 350,
 	.te_var = 1,
@@ -1235,6 +1337,7 @@
 
 	spanel->auto_mode_vrefresh = 0;
 	spanel->delayed_idle = false;
+	spanel->is_pixel_off = false;
 	spanel->tzd = thermal_zone_device_register("inner-disp",
 				0, 0, spanel, &spanel_tzd_ops, NULL, 0, 0);
 	if (IS_ERR(spanel->tzd))
@@ -1259,7 +1362,7 @@
 };
 
 static const struct exynos_panel_funcs ana6707_f10_exynos_funcs = {
-	.set_brightness = exynos_panel_set_brightness,
+	.set_brightness = ana6707_f10_set_brightness,
 	.set_lp_mode = ana6707_f10_set_lp_mode,
 	.set_binned_lp = exynos_panel_set_binned_lp,
 	.set_nolp_mode = ana6707_f10_set_nolp_mode,
diff --git a/display/panel-samsung-ea8182-f10.c b/display/panel-samsung-ea8182-f10.c
index e0baba7..15ed10e 100644
--- a/display/panel-samsung-ea8182-f10.c
+++ b/display/panel-samsung-ea8182-f10.c
@@ -79,11 +79,10 @@
 static const u8 pixel_off[] = { 0x22 };
 static const u8 normal_on[] = { 0x13 };
 
-static const struct exynos_dsi_cmd ea8182_f10_off_cmds[] = {
-	EXYNOS_DSI_CMD(display_off, 20),
+static const struct exynos_dsi_cmd ea8182_f10_sleep_in_cmds[] = {
 	EXYNOS_DSI_CMD(sleep_in, 130),
 };
-static DEFINE_EXYNOS_CMD_SET(ea8182_f10_off);
+static DEFINE_EXYNOS_CMD_SET(ea8182_f10_sleep_in);
 
 static const struct exynos_dsi_cmd ea8182_f10_lp_cmds[] = {
 	EXYNOS_DSI_CMD(display_off, 0),
@@ -321,9 +320,16 @@
 static int ea8182_f10_disable(struct drm_panel *panel)
 {
 	struct exynos_panel *ctx = container_of(panel, struct exynos_panel, panel);
+	const struct exynos_panel_mode *pmode = ctx->current_mode;
 
 	dev_dbg(ctx->dev, "%s\n", __func__);
 
+	/* exit lp mode via 0x53 cmd to avoid green flicker when adjusting voltage  */
+	if (pmode && pmode->exynos_mode.is_lp_mode)
+		EXYNOS_DCS_WRITE_SEQ(ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY,
+				EA8182_F10_WRCTRLD_BCTRL_BIT);
+
+	EXYNOS_DCS_WRITE_TABLE_DELAY(ctx, 20, display_off);
 	ea8182_f10_set_default_voltage(ctx, false);
 	exynos_panel_disable(panel);
 
@@ -799,7 +805,7 @@
 	.min_luminance = 5,
 	.modes = ea8182_f10_modes,
 	.num_modes = ARRAY_SIZE(ea8182_f10_modes),
-	.off_cmd_set = &ea8182_f10_off_cmd_set,
+	.off_cmd_set = &ea8182_f10_sleep_in_cmd_set,
 	.lp_mode = &ea8182_f10_lp_mode,
 	.lp_cmd_set = &ea8182_f10_lp_cmd_set,
 	.binned_lp = ea8182_f10_binned_lp,
diff --git a/dts/gs201-felix-uwb.dtsi b/dts/gs201-felix-uwb.dtsi
index d02c6a6..345a040 100644
--- a/dts/gs201-felix-uwb.dtsi
+++ b/dts/gs201-felix-uwb.dtsi
@@ -52,6 +52,8 @@
 		decawave,eui64 = /bits/ 64 <0>;
 		decawave,panid = /bits/ 16 <0>;
 
+		min_clamp = <620>;
+
 		status = "okay";
 
 		controller-data {
diff --git a/touch/ftm5/fts.c b/touch/ftm5/fts.c
index 738afa4..38801ab 100644
--- a/touch/ftm5/fts.c
+++ b/touch/ftm5/fts.c
@@ -3163,7 +3163,7 @@
 		/* before reset clear all slot */
 		release_all_touches(info);
 #endif
-		fts_chip_powercycle(info);
+		fts_chip_powercycle(info, false);
 
 		error = fts_system_reset(info);
 		error |= fts_mode_handler(info, 0);
@@ -4265,7 +4265,7 @@
 			dev_err(info->dev, "%s: firmware update failed; retrying. ERROR %08X\n",
 				__func__, ret);
 			/* Power cycle the touch IC */
-			fts_chip_powercycle(info);
+			fts_chip_powercycle(info, false);
 			ret = flashProcedure(info, info->board->fw_name,
 					     info->reflash_fw, keep_cx);
 			if ((ret & 0xFF000000) == ERROR_FLASH_PROCEDURE) {
@@ -4457,7 +4457,7 @@
 		initretrycnt++;
 		dev_err(info->dev, "initialization cycle count = %04d - ERROR %08X\n",
 			initretrycnt, ret2);
-		fts_chip_powercycle(info);
+		fts_chip_powercycle(info, false);
 	}
 
 	if (ret2 < OK)	/* initialization error */
@@ -4582,9 +4582,10 @@
   * Execute a power cycle in the IC, toggling the power lines (AVDD and DVDD)
   * @param info pointer to fts_ts_info struct which contain information of the
   * regulators
+  * @param wait_drain to drain the AVDD/DVDD before reenable
   * @return 0 if success or another value if fail
   */
-int fts_chip_powercycle(struct fts_ts_info *info)
+int fts_chip_powercycle(struct fts_ts_info *info, bool wait_drain)
 {
 	int error = 0;
 
@@ -4608,10 +4609,15 @@
 				__func__);
 	}
 
-	if (info->board->reset_gpio != GPIO_NOT_DEFINED)
+	if (info->board->reset_gpio != GPIO_NOT_DEFINED) {
+		if (wait_drain)
+			usleep_range(15 * USEC_PER_MSEC, 15 * USEC_PER_MSEC + 100);
 		gpio_set_value(info->board->reset_gpio, 0);
-	else
+		if (wait_drain)
+			usleep_range(5 * USEC_PER_MSEC, 5 * USEC_PER_MSEC + 100);
+	} else {
 		mdelay(300);
+	}
 
 	/* in FTI power up first the digital and then the analog */
 	if (info->vdd_reg) {
diff --git a/touch/ftm5/fts.h b/touch/ftm5/fts.h
index 93b4037..825eac6 100644
--- a/touch/ftm5/fts.h
+++ b/touch/ftm5/fts.h
@@ -851,7 +851,7 @@
 int dsi_panel_read_vendor_extinfo(struct drm_panel *panel, char *buffer,
 				  size_t len);
 
-int fts_chip_powercycle(struct fts_ts_info *info);
+int fts_chip_powercycle(struct fts_ts_info *info, bool wait_drain);
 extern int input_register_notifier_client(struct notifier_block *nb);
 extern int input_unregister_notifier_client(struct notifier_block *nb);
 
diff --git a/touch/ftm5/fts_lib/ftsCore.c b/touch/ftm5/fts_lib/ftsCore.c
index 4c52fe2..6cc9b50 100644
--- a/touch/ftm5/fts_lib/ftsCore.c
+++ b/touch/ftm5/fts_lib/ftsCore.c
@@ -91,7 +91,7 @@
 						    data));
 		else {
 			gpio_set_value(info->board->reset_gpio, 0);
-			msleep(10);
+			usleep_range(10 * USEC_PER_MSEC, 10 * USEC_PER_MSEC + 100);
 			gpio_set_value(info->board->reset_gpio, 1);
 			res = OK;
 		}
@@ -99,16 +99,24 @@
 			dev_err(info->dev, "fts_system_reset: ERROR %08X\n", ERROR_BUS_W);
 		else {
 			res = pollForEvent(info, &event_to_search, 1, readData,
-					   GENERAL_TIMEOUT);
+					   TIMEOUT_SYSTEM_RESET);
 			if (res < OK)
 				dev_err(info->dev, "fts_system_reset: ERROR %08X\n", res);
 		}
 	}
 
 	if (res < OK) {
-		dev_err(info->dev, "fts_system_reset...failed after 3 attempts: ERROR %08X\n",
-			(res | ERROR_SYSTEM_RESET_FAIL));
-		return res | ERROR_SYSTEM_RESET_FAIL;
+		dev_err(info->dev, "%s: failed after %d attempts: ERROR %08X\n",
+			__func__, i, (res | ERROR_SYSTEM_RESET_FAIL));
+		/* Do powercycle to recover unexpected system reset fail. */
+		fts_chip_powercycle(info, true);
+		res = pollForEvent(info, &event_to_search, 1, readData, TIMEOUT_SYSTEM_RESET);
+		if (res < OK) {
+			dev_err(info->dev, "%s: no ready ack after powercycle!\n", __func__);
+			return res | ERROR_SYSTEM_RESET_FAIL;
+		}
+
+		return OK;
 	} else {
 #ifdef FTS_GPIO6_UNUSED
 		u8ToU64_be(&cmd[1], &addr, ADDR_SIZE_HW_REG);
diff --git a/touch/ftm5/fts_lib/ftsCore.h b/touch/ftm5/fts_lib/ftsCore.h
index 4c87907..8edc6c8 100644
--- a/touch/ftm5/fts_lib/ftsCore.h
+++ b/touch/ftm5/fts_lib/ftsCore.h
@@ -63,7 +63,7 @@
 #define RETRY_MAX_REQU_DATA		2	/* /< Max number of attempts
 						 * performed
 						 * when requesting data */
-#define RETRY_SYSTEM_RESET		3	/* /< Max number of attempts
+#define RETRY_SYSTEM_RESET		2	/* /< Max number of attempts
 						 * performed
 						 * to reset the IC */
 
diff --git a/touch/ftm5/fts_lib/ftsError.c b/touch/ftm5/fts_lib/ftsError.c
index fcffbce..2e2b307 100644
--- a/touch/ftm5/fts_lib/ftsError.c
+++ b/touch/ftm5/fts_lib/ftsError.c
@@ -143,7 +143,7 @@
 		switch (event[1]) {	/* TODO: write an error log for
 					 * undefined command subtype 0xBA */
 		case EVT_TYPE_ERROR_ESD:	/* esd */
-			res = fts_chip_powercycle(info);
+			res = fts_chip_powercycle(info, false);
 			if (res < OK)
 				dev_err(info->dev, "errorHandler: Error performing powercycle ERROR %08X\n",
 					res);
diff --git a/touch/ftm5/fts_lib/ftsTime.h b/touch/ftm5/fts_lib/ftsTime.h
index f2b99a8..6b9095b 100644
--- a/touch/ftm5/fts_lib/ftsTime.h
+++ b/touch/ftm5/fts_lib/ftsTime.h
@@ -37,6 +37,8 @@
 #define RELEASE_INFO_TIMEOUT			(2 * TIMEOUT_RESOLUTION)
 /* /< timeout to request release info in ms */
 
+#define TIMEOUT_SYSTEM_RESET			(2 * TIMEOUT_RESOLUTION)
+/* /< timeout to system reset in ms */
 #define TIMEOUT_CMD_CUSTOM_W			(1 * TIMEOUT_RESOLUTION)
 /* /< timeout to perform custom write cmd in ms */
 #define TIMEOUT_CMD_SCAN_MODE			(1 * TIMEOUT_RESOLUTION)
diff --git a/touch/ftm5/fts_proc.c b/touch/ftm5/fts_proc.c
index 3492127..ffc7a86 100644
--- a/touch/ftm5/fts_proc.c
+++ b/touch/ftm5/fts_proc.c
@@ -2046,7 +2046,7 @@
 			break;
 
 		case CMD_POWERCYCLE:
-			res = fts_chip_powercycle(info);
+			res = fts_chip_powercycle(info, false);
 			break;
 
 		case CMD_GETLIMITSFILE: