msm: cpr: Define Vmin based on fused bits in MSM

As per chip charactrization data, it is observed that
minimum voltage requirement is variable and should be
based on the fused bits as per chip characteristics.

Change-Id: Ic6cc8512185657f7901a64b8d30407c2398112fa
Signed-off-by: Kaushal Kumar <kaushalk@codeaurora.org>
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index c0ad39b..9943812 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1730,9 +1730,9 @@
 			.step_quot = ~0,
 			.tgt_volt_offset = 0,
 			.turbo_Vmax = 1350000,
-			.turbo_Vmin = 1100000,
+			.turbo_Vmin = 1150000,
 			.nom_Vmax = 1350000,
-			.nom_Vmin = 1100000,
+			.nom_Vmin = 1150000,
 			.calibrated_uV = 1300000,
 	},
 };
@@ -1864,10 +1864,25 @@
 	msm_cpr_mode_data[TURBO_MODE].calibrated_uV =
 				msm_c2_pmic_mv[cpr_info->pvs_fuse & 0x1F];
 
+	if ((cpr_info->floor_fuse & 0x3) == 0x0) {
+		msm_cpr_mode_data[TURBO_MODE].nom_Vmin = 1000000;
+		msm_cpr_mode_data[TURBO_MODE].turbo_Vmin = 1100000;
+	} else if ((cpr_info->floor_fuse & 0x3) == 0x1) {
+		msm_cpr_mode_data[TURBO_MODE].nom_Vmin = 1050000;
+		msm_cpr_mode_data[TURBO_MODE].turbo_Vmin = 1100000;
+	} else if ((cpr_info->floor_fuse & 0x3) == 0x2) {
+		msm_cpr_mode_data[TURBO_MODE].nom_Vmin = 1100000;
+		msm_cpr_mode_data[TURBO_MODE].turbo_Vmin = 1100000;
+	}
+
 	pr_debug("%s: cpr: ring_osc: 0x%x\n", __func__,
 		msm_cpr_mode_data[TURBO_MODE].ring_osc);
 	pr_debug("%s: cpr: turbo_quot: 0x%x\n", __func__, cpr_info->turbo_quot);
 	pr_debug("%s: cpr: pvs_fuse: 0x%x\n", __func__, cpr_info->pvs_fuse);
+	pr_debug("%s: cpr: floor_fuse: 0x%x\n", __func__, cpr_info->floor_fuse);
+	pr_debug("%s: cpr: nom_Vmin: %d, turbo_Vmin: %d\n", __func__,
+		msm_cpr_mode_data[TURBO_MODE].nom_Vmin,
+		msm_cpr_mode_data[TURBO_MODE].turbo_Vmin);
 	kfree(cpr_info);
 
 	if (msm8625_cpu_id() == MSM8625A)
diff --git a/arch/arm/mach-msm/msm_smem_iface.c b/arch/arm/mach-msm/msm_smem_iface.c
index b09fda5..b35467b 100644
--- a/arch/arm/mach-msm/msm_smem_iface.c
+++ b/arch/arm/mach-msm/msm_smem_iface.c
@@ -41,4 +41,5 @@
 	cpr_info->ring_osc = temp_cpr_info->ring_osc;
 	cpr_info->turbo_quot = temp_cpr_info->turbo_quot;
 	cpr_info->pvs_fuse = temp_cpr_info->pvs_fuse;
+	cpr_info->floor_fuse = temp_cpr_info->floor_fuse;
 }
diff --git a/arch/arm/mach-msm/msm_smem_iface.h b/arch/arm/mach-msm/msm_smem_iface.h
index 2da0232..a6d6714 100644
--- a/arch/arm/mach-msm/msm_smem_iface.h
+++ b/arch/arm/mach-msm/msm_smem_iface.h
@@ -33,10 +33,12 @@
 	uint8_t  iv[MAX_SEC_KEY_PAYLOAD]; /* Initialization Vector */
 };
 
+/* floor_fuse to re-use the fuse bit earlier used by ring_osc */
 struct cpr_info_type {
-	uint8_t ring_osc;         /* CPR FUSE [0]: TURBO RO SEL BIT */
-	uint8_t turbo_quot;        /* CPRFUSE[1:7] : TURBO QUOT*/
-	uint8_t pvs_fuse;         /* TURBO PVS FUSE */
+	uint8_t ring_osc;   /* CPR FUSE [0]: TURBO RO SEL BIT */
+	uint8_t turbo_quot; /* CPRFUSE[1:7] : TURBO QUOT*/
+	uint8_t pvs_fuse;   /* TURBO PVS FUSE */
+	uint8_t floor_fuse; /* Vmin Selection. b1: FAB_ID(2), b0: CPR_fuse[0] */
 };
 
 struct boot_info_for_apps {
@@ -47,7 +49,7 @@
 	uint16_t boot_keys_pressed[MAX_KEY_EVENTS]; /* Log of key presses */
 	uint32_t timetick; /* Modem tick timer value before apps out of reset */
 	struct cpr_info_type cpr_info;
-	uint8_t PAD[25];
+	uint8_t PAD[24];
 };
 
 void msm_smem_get_cpr_info(struct cpr_info_type *cpr_info);