Merge cherrypicks of ['partner-android-review.googlesource.com/2718470'] into android13-msm-pixelwatch-5.15-p11-release.

Change-Id: I11bbbd4ff6b15e579421364a728ddc3736936c26
diff --git a/tma525c/pt_loader.c b/tma525c/pt_loader.c
index 83e7a59..09d84bd 100644
--- a/tma525c/pt_loader.c
+++ b/tma525c/pt_loader.c
@@ -81,6 +81,8 @@
 #define PT_ROW_DATA_OFFSET				5
 
 #define PT_CALIBRATION_REV 1035728
+#define PT_STARTING_SUPPORT_DOWNGRADE_FW_VER 0x010A
+#define PT_STARTING_SUPPORT_DOWNGRADE_FW_REV 1035728
 
 #define PT_POST_TT_CFG_CRC_MASK				0x2
 static inline struct pt_loader_data *pt_get_loader_data(
@@ -361,6 +363,53 @@
 
 
 #if (PT_FW_UPGRADE || PT_TTCONFIG_UPGRADE)
+static bool pt_check_if_calibration(u32 fw_revctrl_img, u32 fw_revctrl_new)
+{
+	// Need to do calibration if the old and new version
+	// is crossing the version needed calibration.
+	if (fw_revctrl_img < PT_CALIBRATION_REV && fw_revctrl_new >= PT_CALIBRATION_REV)
+		return true;
+	else if (fw_revctrl_img >= PT_CALIBRATION_REV && fw_revctrl_new < PT_CALIBRATION_REV)
+		return true;
+	return false;
+}
+
+static bool pt_check_if_downgrade(struct device *dev, u32 fw_ver_img, u32 fw_ver_new,
+				  u32 fw_revctrl_img, u32 fw_revctrl_new)
+{
+	/* Should downgrade FW only when
+	 * new fw is older and new fw ver/rev supports downgrade mechanism.
+	 */
+	if (fw_ver_new < fw_ver_img && fw_ver_new >= PT_STARTING_SUPPORT_DOWNGRADE_FW_VER) {
+		pt_debug(dev, DL_INFO, "%s: FW ver is older, will downgrade\n", __func__);
+		return true;
+	}
+
+	if (fw_revctrl_new < fw_revctrl_img &&
+	    fw_revctrl_new >= PT_STARTING_SUPPORT_DOWNGRADE_FW_REV) {
+		pt_debug(dev, DL_INFO, "%s: FW rev is older, will downgrade\n", __func__);
+		return true;
+	}
+
+	return false;
+}
+
+static bool pt_check_if_upgrade(struct device *dev, u32 fw_ver_img, u32 fw_ver_new,
+				u32 fw_revctrl_img, u32 fw_revctrl_new)
+{
+	/* Upgrade FW when fw img is newer
+	 */
+	if (fw_ver_new > fw_ver_img) {
+		pt_debug(dev, DL_INFO, "%s: FW ver is newer, will upgrade\n", __func__);
+		return true;
+	}
+
+	if (fw_revctrl_new > fw_revctrl_img) {
+		pt_debug(dev, DL_INFO, "%s: FW rev is newer, will upgrade\n", __func__);
+		return true;
+	}
+	return false;
+}
 /*******************************************************************************
  * FUNCTION: pt_check_firmware_version
  *
@@ -386,51 +435,31 @@
 	fw_ver_img = ld->si->ttdata.fw_ver_major << 8;
 	fw_ver_img += ld->si->ttdata.fw_ver_minor;
 
-	pt_debug(dev, DL_WARN,
-		"%s: Current FW ver:0x%04X New FW ver:0x%04X\n", __func__,
-			fw_ver_img, fw_ver_new);
+	pt_debug(dev, DL_INFO, "%s: Current FW ver:0x%04X New FW ver:0x%04X\n", __func__,
+		 fw_ver_img, fw_ver_new);
 
 	fw_revctrl_img = ld->si->ttdata.revctrl;
 
-	pt_debug(dev, DL_WARN, "%s: Current FW rev:%d New FW rev:%d\n", __func__, fw_revctrl_img,
+	pt_debug(dev, DL_INFO, "%s: Current FW rev:%d New FW rev:%d\n", __func__, fw_revctrl_img,
 		 fw_revctrl_new);
 
 	// Check if calibaration needed
-	if (fw_revctrl_img < PT_CALIBRATION_REV && fw_revctrl_new >= PT_CALIBRATION_REV) {
+	if (pt_check_if_calibration(fw_revctrl_img, fw_revctrl_new)) {
 		ld->loader_pdata->flags = PT_LOADER_FLAG_CALIBRATE_AFTER_FW_UPGRADE;
-		pt_debug(dev, DL_WARN, "%s: Will do auto calibration after FW updated.\n",
+		pt_debug(dev, DL_INFO, "%s: Will do auto calibration after FW updated.\n",
 			 __func__);
 	} else {
 		ld->loader_pdata->flags = PT_LOADER_FLAG_NONE;
 		if (fw_revctrl_new > fw_revctrl_img) {
-			pt_debug(dev, DL_WARN,
+			pt_debug(dev, DL_INFO,
 				 "%s: Will not do auto calibration after FW updated.\n", __func__);
 		}
 	}
 
-	if (fw_ver_new > fw_ver_img) {
-		pt_debug(dev, DL_WARN,
-			"%s: Image is newer, will upgrade\n", __func__);
+	if (pt_check_if_downgrade(dev, fw_ver_img, fw_ver_new, fw_revctrl_img, fw_revctrl_new))
 		return 1;
-	}
-
-	if (fw_ver_new < fw_ver_img) {
-		pt_debug(dev, DL_WARN,
-			"%s: Image is older, will NOT upgrade\n", __func__);
-		return -1;
-	}
-
-	if (fw_revctrl_new > fw_revctrl_img) {
-		pt_debug(dev, DL_WARN,
-			"%s: Image is newer, will upgrade\n", __func__);
+	else if (pt_check_if_upgrade(dev, fw_ver_img, fw_ver_new, fw_revctrl_img, fw_revctrl_new))
 		return 1;
-	}
-
-	if (fw_revctrl_new < fw_revctrl_img) {
-		pt_debug(dev, DL_WARN,
-			"%s: Image is older, will NOT upgrade\n", __func__);
-		return -1;
-	}
 
 	return 0;
 }