Merge "mmc: sdhci-msm: add quirk for max_discard calculation"
diff --git a/arch/arm/boot/dts/msm8226-pm.dtsi b/arch/arm/boot/dts/msm8226-pm.dtsi
index 34283e8..039c0b7 100644
--- a/arch/arm/boot/dts/msm8226-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-pm.dtsi
@@ -125,8 +125,8 @@
 			qcom,name = "vdd-mem";
 			qcom,type = <0x616F646C>;	/* "ldoa" */
 			qcom,id = <0x03>;
-			qcom,key = <0x7675>;		/* "uv" */
-			qcom,init-value = <1050000>;	/* Super Turbo */
+			qcom,key = <0x6e726f63>;	/* "corn" */
+			qcom,init-value = <3>;		/* Active */
 		};
 
 		qcom,lpm-resources@2 {
@@ -156,10 +156,10 @@
 			qcom,mode = "wfi";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <1>;
 			qcom,ss-power = <784>;
 			qcom,energy-overhead = <190000>;
@@ -171,10 +171,10 @@
 			qcom,mode = "retention";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <75>;
 			qcom,ss-power = <735>;
 			qcom,energy-overhead = <77341>;
@@ -187,10 +187,10 @@
 			qcom,mode = "standalone_pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <95>;
 			qcom,ss-power = <725>;
 			qcom,energy-overhead = <99500>;
@@ -202,10 +202,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <2000>;
 			qcom,ss-power = <138>;
 			qcom,energy-overhead = <1208400>;
@@ -217,10 +217,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
-			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
-			qcom,vdd-dig-lower-bound = <2>;  /* RETENTION HIGH */
+			qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <2>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <3>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <2>;  /* SVS SOC */
 			qcom,latency-us = <3000>;
 			qcom,ss-power = <110>;
 			qcom,energy-overhead = <1250300>;
@@ -232,10 +232,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <3000>;
 			qcom,ss-power = <68>;
 			qcom,energy-overhead = <1350200>;
@@ -247,10 +247,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <10300>;
 			qcom,ss-power = <63>;
 			qcom,energy-overhead = <2128000>;
@@ -262,10 +262,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
-			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
-			qcom,vdd-dig-lower-bound = <2>;  /* RETIONTION HIGH */
+			qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <2>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <3>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <2>;  /* SVS SOC */
 			qcom,latency-us = <18000>;
 			qcom,ss-power = <10>;
 			qcom,energy-overhead = <3202600>;
@@ -277,10 +277,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <750000>; /* RETENTION HIGH */
-			qcom,vdd-mem-lower-bound = <750000>; /* RETENTION LOW */
-			qcom,vdd-dig-upper-bound = <2>; /* RETENTION HIGH */
-			qcom,vdd-dig-lower-bound = <0>; /* RETENTION LOW */
+			qcom,vdd-mem-upper-bound = <2>; /* SVS SOC */
+			qcom,vdd-mem-lower-bound = <0>; /* RETENTION */
+			qcom,vdd-dig-upper-bound = <2>; /* SVS SOC */
+			qcom,vdd-dig-lower-bound = <0>; /* RETENTION */
 			qcom,latency-us = <20000>;
 			qcom,ss-power = <2>;
 			qcom,energy-overhead = <4252000>;
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 9c21707..f24cea1 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -64,7 +64,7 @@
 			regulator-min-microvolt = <1>;
 			regulator-max-microvolt = <7>;
 			qcom,use-voltage-corner;
-			qcom,consumer-supplies = "vdd_dig", "";
+			qcom,consumer-supplies = "vdd_dig", "", "vdd_sr2_dig", "";
 		};
 		pm8226_s1_corner_ao: regulator-s1-corner-ao {
 			compatible = "qcom,rpm-regulator-smd";
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index 5512ccd..d50902c 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -19,7 +19,7 @@
 		qcom,hpm-min-load = <100000>;
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <7>;
-		qcom,consumer-supplies = "vdd_dig", "";
+		qcom,consumer-supplies = "vdd_dig", "", "vdd_sr2_dig", "";
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index ceba72f..a7544ab 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -62,21 +62,21 @@
 				reg = <0>;
 				qcom,gpu-freq = <450000000>;
 				qcom,bus-freq = <5>;
-				qcom,io-fraction = <0>;
+				qcom,io-fraction = <33>;
 			};
 
 			qcom,gpu-pwrlevel@1 {
 				reg = <1>;
 				qcom,gpu-freq = <300000000>;
 				qcom,bus-freq = <4>;
-				qcom,io-fraction = <33>;
+				qcom,io-fraction = <66>;
 			};
 
 			qcom,gpu-pwrlevel@2 {
 				reg = <2>;
 				qcom,gpu-freq = <300000000>;
 				qcom,bus-freq = <3>;
-				qcom,io-fraction = <33>;
+				qcom,io-fraction = <66>;
 			};
 
 			qcom,gpu-pwrlevel@3 {
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 656c3f4..2f44566 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2652,8 +2652,8 @@
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 6144,		  /* log's buffer length in bytes */
+	.log_len_mask = (6144 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device apq8064_rpm_log_device = {
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index 2f8f547..e2a57f9 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -550,14 +550,14 @@
 };
 
 static struct msm_rpm_log_platform_data msm_rpm_log_pdata = {
-	.phys_addr_base = 0x0010C000,
+	.phys_addr_base = 0x10B6A0,
 	.reg_offsets = {
 		[MSM_RPM_LOG_PAGE_INDICES] = 0x00000080,
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 8192,		  /* log's buffer length in bytes */
+	.log_len_mask = (8192 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device msm8930_rpm_log_device = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index e70a0a8..837aef3 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3961,8 +3961,8 @@
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 6144,		  /* log's buffer length in bytes */
+	.log_len_mask = (6144 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device msm8960_rpm_log_device = {
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index b52df44..1458bc5 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -637,19 +637,26 @@
 		uint32_t *low_threshold, uint32_t *high_threshold)
 {
 	struct qpnp_vadc_linear_graph vbatt_param;
+	int rc = 0;
 
-	qpnp_get_vadc_gain_and_offset(&vbatt_param, CALIB_ABSOLUTE);
+	rc = qpnp_get_vadc_gain_and_offset(&vbatt_param, CALIB_ABSOLUTE);
+	if (rc < 0)
+		return rc;
 
-	*low_threshold = param->low_thr * vbatt_param.dy;
-	do_div(*low_threshold, vbatt_param.adc_vref);
+	*low_threshold = (((param->low_thr/3) - QPNP_ADC_625_UV) *
+				vbatt_param.dy);
+	do_div(*low_threshold, QPNP_ADC_625_UV);
 	*low_threshold += vbatt_param.adc_gnd;
 
-	*high_threshold = param->high_thr * vbatt_param.dy;
-	do_div(*high_threshold, vbatt_param.adc_vref);
+	*high_threshold = (((param->high_thr/3) - QPNP_ADC_625_UV) *
+				vbatt_param.dy);
+	do_div(*high_threshold, QPNP_ADC_625_UV);
 	*high_threshold += vbatt_param.adc_gnd;
 
 	pr_debug("high_volt:%d, low_volt:%d\n", param->high_thr,
 				param->low_thr);
+	pr_debug("adc_code_high:%x, adc_code_low:%x\n", *high_threshold,
+				*low_threshold);
 	return 0;
 }
 EXPORT_SYMBOL(qpnp_adc_vbatt_rscaler);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 12ac4cb..9300ce0 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -39,6 +39,9 @@
 #define CDBG(fmt, args...) do { } while (0)
 #endif
 
+/* Max bytes that can be read per CCI read transaction */
+#define CCI_READ_MAX 12
+
 static struct v4l2_subdev *g_cci_subdev;
 
 static void msm_cci_set_clk_param(struct cci_device *cci_dev)
@@ -377,6 +380,61 @@
 	return rc;
 }
 
+static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	int32_t rc = 0;
+	struct cci_device *cci_dev = NULL;
+	enum cci_i2c_master_t master;
+	struct msm_camera_cci_i2c_read_cfg *read_cfg = NULL;
+	uint16_t read_bytes = 0;
+
+	if (!sd || !c_ctrl) {
+		pr_err("%s:%d sd %p c_ctrl %p\n", __func__,
+			__LINE__, sd, c_ctrl);
+		return -EINVAL;
+	}
+	if (!c_ctrl->cci_info) {
+		pr_err("%s:%d cci_info NULL\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	cci_dev = v4l2_get_subdevdata(sd);
+	if (!cci_dev) {
+		pr_err("%s:%d cci_dev NULL\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	master = c_ctrl->cci_info->cci_i2c_master;
+	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
+	if (!read_cfg->num_byte) {
+		pr_err("%s:%d read num bytes 0\n", __func__, __LINE__);
+		rc = -EINVAL;
+		goto ERROR;
+	}
+
+	read_bytes = read_cfg->num_byte;
+	do {
+		if (read_bytes > CCI_READ_MAX)
+			read_cfg->num_byte = CCI_READ_MAX;
+		else
+			read_cfg->num_byte = read_bytes;
+		rc = msm_cci_i2c_read(sd, c_ctrl);
+		if (rc < 0) {
+			pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
+			goto ERROR;
+		}
+		if (read_bytes > CCI_READ_MAX) {
+			read_cfg->addr += CCI_READ_MAX;
+			read_cfg->data += CCI_READ_MAX;
+			read_bytes -= CCI_READ_MAX;
+		} else {
+			read_bytes = 0;
+		}
+	} while (read_bytes);
+ERROR:
+	return rc;
+}
+
 static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
 	struct msm_camera_cci_ctrl *c_ctrl)
 {
@@ -589,7 +647,7 @@
 		rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
 		break;
 	case MSM_CCI_I2C_READ:
-		rc = msm_cci_i2c_read(sd, cci_ctrl);
+		rc = msm_cci_i2c_read_bytes(sd, cci_ctrl);
 		break;
 	case MSM_CCI_I2C_WRITE:
 		rc = msm_cci_i2c_write(sd, cci_ctrl);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile
index f71b09d..86e9214 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile
@@ -1,3 +1,3 @@
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
-obj-$(CONFIG_MSMB_CAMERA)   += msm_camera_io_util.o msm_camera_cci_i2c.o msm_camera_qup_i2c.o msm_camera_i2c_mux.o
+obj-$(CONFIG_MSMB_CAMERA)   += msm_camera_io_util.o msm_camera_cci_i2c.o msm_camera_qup_i2c.o msm_camera_i2c_mux.o msm_camera_spi.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
index b07f04f..b9f49e6 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
@@ -28,7 +28,7 @@
 #define I2C_POLL_MAX_ITERATION 20
 
 int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
+	uint32_t addr, uint16_t *data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc = -EFAULT;
@@ -64,10 +64,10 @@
 }
 
 int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
 {
 	int32_t rc = -EFAULT;
-	unsigned char buf[client->addr_type+num_byte];
+	unsigned char *buf = NULL;
 	int i;
 	struct msm_camera_cci_ctrl cci_ctrl;
 
@@ -76,6 +76,11 @@
 		|| num_byte == 0)
 		return rc;
 
+	buf = kzalloc(num_byte, GFP_KERNEL);
+	if (!buf) {
+		pr_err("%s:%d no memory\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
 	cci_ctrl.cmd = MSM_CCI_I2C_READ;
 	cci_ctrl.cci_info = client->cci_client;
 	cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
@@ -93,11 +98,12 @@
 		S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]);
 		S_I2C_DBG("Data: 0x%x\n", data[i]);
 	}
+	kfree(buf);
 	return rc;
 }
 
 int32_t msm_camera_cci_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc = -EFAULT;
@@ -131,7 +137,7 @@
 }
 
 int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
 {
 	int32_t rc = -EFAULT;
 	uint8_t i = 0;
@@ -272,7 +278,7 @@
 }
 
 static int32_t msm_camera_cci_i2c_compare(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc;
@@ -328,7 +334,7 @@
 }
 
 static int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc;
@@ -347,7 +353,7 @@
 }
 
 static int32_t msm_camera_cci_i2c_set_mask(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t mask,
+	uint32_t addr, uint16_t mask,
 	enum msm_camera_i2c_data_type data_type, uint16_t set_mask)
 {
 	int32_t rc;
@@ -376,7 +382,7 @@
 
 static int32_t msm_camera_cci_i2c_set_write_mask_data(
 	struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data, int16_t mask,
+	uint32_t addr, uint16_t data, int16_t mask,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
index 26f1c4f..09d8f84 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
@@ -21,6 +21,7 @@
 	struct msm_camera_i2c_fn_t *i2c_func_tbl;
 	struct i2c_client *client;
 	struct msm_camera_cci_client *cci_client;
+	struct msm_camera_spi_client *spi_client;
 	enum msm_camera_i2c_reg_addr_type addr_type;
 };
 
@@ -31,13 +32,13 @@
 };
 
 struct msm_camera_i2c_fn_t {
-	int (*i2c_read) (struct msm_camera_i2c_client *, uint16_t, uint16_t *,
+	int (*i2c_read) (struct msm_camera_i2c_client *, uint32_t, uint16_t *,
 		enum msm_camera_i2c_data_type);
-	int32_t (*i2c_read_seq)(struct msm_camera_i2c_client *, uint16_t,
+	int32_t (*i2c_read_seq)(struct msm_camera_i2c_client *, uint32_t,
 		uint8_t *, uint16_t);
-	int (*i2c_write) (struct msm_camera_i2c_client *, uint16_t, uint16_t,
+	int (*i2c_write) (struct msm_camera_i2c_client *, uint32_t, uint16_t,
 		enum msm_camera_i2c_data_type);
-	int (*i2c_write_seq) (struct msm_camera_i2c_client *, uint16_t ,
+	int (*i2c_write_seq) (struct msm_camera_i2c_client *, uint32_t ,
 		uint8_t *, uint16_t);
 	int32_t (*i2c_write_table)(struct msm_camera_i2c_client *,
 		struct msm_camera_i2c_reg_setting *);
@@ -54,18 +55,18 @@
 };
 
 int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
+	uint32_t addr, uint16_t *data,
 	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
 
 int32_t msm_camera_cci_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
 
 int32_t msm_camera_cci_i2c_write_table(
 	struct msm_camera_i2c_client *client,
@@ -89,18 +90,18 @@
 	uint16_t cci_cmd);
 
 int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
+	uint32_t addr, uint16_t *data,
 	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
 
 int32_t msm_camera_qup_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_camera_qup_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
 
 int32_t msm_camera_qup_i2c_write_table(struct msm_camera_i2c_client *client,
 	struct msm_camera_i2c_reg_setting *write_setting);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
index 55f27e0..9222bb5 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
@@ -69,7 +69,7 @@
 }
 
 int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
+	uint32_t addr, uint16_t *data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc = -EFAULT;
@@ -103,7 +103,7 @@
 }
 
 int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
 {
 	int32_t rc = -EFAULT;
 	unsigned char buf[client->addr_type+num_byte];
@@ -136,7 +136,7 @@
 }
 
 int32_t msm_camera_qup_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc = -EFAULT;
@@ -184,7 +184,7 @@
 }
 
 int32_t msm_camera_qup_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
 {
 	int32_t rc = -EFAULT;
 	unsigned char buf[client->addr_type+num_byte];
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.c
new file mode 100644
index 0000000..d1d5f23
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <mach/camera2.h>
+#include "msm_camera_spi.h"
+
+#undef SPIDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define SPIDBG(fmt, args...) pr_debug(fmt, ##args)
+#define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define SPIDBG(fmt, args...) do { } while (0)
+#define S_I2C_DBG(fmt, args...) do { } while (0)
+#endif
+
+static int msm_camera_spi_txfr(struct spi_device *spi, char *txbuf,
+			       char *rxbuf, int num_byte)
+{
+	struct spi_transfer t;
+	struct spi_message m;
+
+	memset(&t, 0, sizeof(t));
+	t.tx_buf = txbuf;
+	t.rx_buf = rxbuf;
+	t.len = num_byte;
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	return spi_sync(spi, &m);
+}
+
+/**
+  * msm_camera_set_addr() - helper function to set transfer address
+  * @addr:	device address
+  * @addr_len:	the addr field length of an instruction
+  * @type:	type (i.e. byte-length) of @addr
+  * @str:	shifted address output, must be zeroed when passed in
+  *
+  * This helper function sets @str based on the addr field length of an
+  * instruction and the data length.
+  */
+static void msm_camera_set_addr(uint32_t addr, uint8_t addr_len,
+				enum msm_camera_i2c_reg_addr_type type,
+				char *str)
+{
+	int i, len;
+
+	if (addr_len < type)
+		SPIDBG("%s: omitting higher bits in address\n", __func__);
+
+	/* only support transfer MSB first for now */
+	len = addr_len - type;
+	for (i = len; i < addr_len; i++) {
+		if (i >= 0)
+			str[i] = (addr >> (BITS_PER_BYTE * (addr_len - i - 1)))
+				& 0xFF;
+	}
+
+}
+
+static int32_t msm_camera_spi_read_helper(struct msm_camera_i2c_client *client,
+		struct msm_camera_spi_inst *inst, uint32_t addr, uint8_t *data,
+		uint16_t num_byte)
+{
+	int32_t rc = -EFAULT;
+	struct spi_device *spi = client->spi_client->spi_master;
+	char *tx, *rx;
+	uint16_t len;
+	int8_t retries = client->spi_client->retries;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR)
+	    && (client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+	    && (client->addr_type != MSM_CAMERA_I2C_3B_ADDR))
+		return rc;
+
+	len = sizeof(inst->opcode) + inst->addr_len + inst->dummy_len
+		+ num_byte;
+
+	tx = kmalloc(len, GFP_KERNEL | GFP_DMA);
+	if (!tx)
+		return -ENOMEM;
+	rx = kmalloc(len, GFP_KERNEL | GFP_DMA);
+	if (!rx) {
+		kfree(tx);
+		return -ENOMEM;
+	}
+	memset(tx, 0, len);
+	memset(rx, 0, len);
+
+	tx[0] = inst->opcode;
+	msm_camera_set_addr(addr, inst->addr_len, client->addr_type, tx + 1);
+	while ((rc = msm_camera_spi_txfr(spi, tx, rx, len)) && retries) {
+		retries--;
+		msleep(client->spi_client->retry_delay);
+	}
+	if (rc) {
+		SPIDBG("%s: failed %d\n", __func__, rc);
+		goto out;
+	}
+	len = sizeof(inst->opcode) + inst->addr_len + inst->dummy_len;
+	memcpy(data, rx + len, num_byte);
+out:
+	kfree(tx);
+	kfree(rx);
+	return rc;
+}
+
+int32_t msm_camera_spi_read(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EFAULT;
+	uint8_t temp[2];
+
+	if ((data_type != MSM_CAMERA_I2C_BYTE_DATA)
+	    && (data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	rc = msm_camera_spi_read_helper(client,
+		&client->spi_client->cmd_tbl.read, addr, &temp[0], data_type);
+	if (rc)
+		return rc;
+
+	if (data_type == MSM_CAMERA_I2C_BYTE_DATA)
+		*data = temp[0];
+	else
+		*data = (temp[0] << BITS_PER_BYTE) | temp[1];
+
+	SPIDBG("%s: addr 0x%x, data %u\n", __func__, addr, *data);
+	return rc;
+}
+
+int32_t msm_camera_spi_read_seq(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
+{
+	return msm_camera_spi_read_helper(client,
+		&client->spi_client->cmd_tbl.read_seq, addr, data, num_byte);
+}
+
+int32_t msm_camera_spi_query_id(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
+{
+	return msm_camera_spi_read_helper(client,
+		&client->spi_client->cmd_tbl.query_id, addr, data, num_byte);
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.h
new file mode 100644
index 0000000..564e470
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.h
@@ -0,0 +1,51 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_CAMERA_SPI_H
+#define __MSM_CAMERA_SPI_H
+
+#include <linux/spi/spi.h>
+#include <media/msm_cam_sensor.h>
+#include "msm_camera_i2c.h"
+
+struct msm_camera_spi_inst {
+	uint8_t opcode;		/* one-byte opcode */
+	uint8_t addr_len;	/* addr len in bytes */
+	uint8_t dummy_len;	/* setup cycles */
+};
+
+struct msm_camera_spi_inst_tbl {
+	struct msm_camera_spi_inst read;
+	struct msm_camera_spi_inst read_seq;
+	struct msm_camera_spi_inst query_id;
+};
+
+struct msm_camera_spi_client {
+	struct spi_device *spi_master;
+	struct msm_camera_spi_inst_tbl cmd_tbl;
+	uint8_t device_id;
+	uint8_t mfr_id;
+	uint8_t retry_delay;	/* ms */
+	uint8_t retries;	/* retry times upon failure */
+};
+
+int32_t msm_camera_spi_read(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_spi_read_seq(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
+
+int32_t msm_camera_spi_query_id(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
+
+#endif
diff --git a/drivers/media/platform/msm/wfd/enc-venus-subdev.c b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
index 9ebf763..b719b3f 100644
--- a/drivers/media/platform/msm/wfd/enc-venus-subdev.c
+++ b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
@@ -767,6 +767,7 @@
 	if (inst->secure)
 		msm_ion_unsecure_buffer(venc_ion_client, mregion->ion_handle);
 
+	ion_free(venc_ion_client, mregion->ion_handle);
 	return rc;
 }
 
@@ -1286,9 +1287,11 @@
 		return rc;
 	}
 
-	if (mregion->paddr)
+	if (mregion->paddr) {
 		ion_unmap_iommu(mmap->ion_client, mregion->ion_handle,
 			domain, partition);
+		mregion->paddr = NULL;
+	}
 
 	if (inst->secure)
 		msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle);
diff --git a/drivers/media/platform/msm/wfd/wfd-ioctl.c b/drivers/media/platform/msm/wfd/wfd-ioctl.c
index cd54449..2ed5f2d 100644
--- a/drivers/media/platform/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/platform/msm/wfd/wfd-ioctl.c
@@ -166,11 +166,15 @@
 	unsigned int alloc_regions = 0, ion_flags = 0, align = 0;
 	int rc = 0;
 
-	alloc_regions = ION_HEAP(ION_CP_MM_HEAP_ID);
-	alloc_regions |= secure ? 0 :
-				ION_HEAP(ION_IOMMU_HEAP_ID);
-	ion_flags |= secure ? ION_SECURE : 0;
-	align = secure ? SZ_1M : SZ_4K;
+	if (secure) {
+		alloc_regions = ION_HEAP(ION_CP_MM_HEAP_ID);
+		ion_flags = ION_SECURE;
+		align = SZ_1M;
+	} else {
+		alloc_regions = ION_HEAP(ION_IOMMU_HEAP_ID);
+		align = SZ_4K;
+	}
+
 	handle = ion_alloc(client, mregion->size, align,
 			alloc_regions, ion_flags);
 
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index 9ef86a7..3b226ad 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -1569,6 +1569,7 @@
 {
 	int i;
 	int id;
+	int table_idx;
 	u32 val;
 
 	struct sps_connect *config;
@@ -1606,16 +1607,18 @@
 	wmb();
 
 	/* unregister all filters for this channel */
-	for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
-		struct tspp_pid_filter *tspp_filter =
-			&pdev->filters[channel->src]->filter[i];
-		id = FILTER_GET_PIPE_NUMBER0(tspp_filter);
-		if (id == channel->id) {
-			if (FILTER_HAS_ENCRYPTION(tspp_filter))
-				tspp_free_key_entry(
-					FILTER_GET_KEY_NUMBER(tspp_filter));
-			tspp_filter->config = 0;
-			tspp_filter->filter = 0;
+	for (table_idx = 0; table_idx < TSPP_FILTER_TABLES; table_idx++) {
+		for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
+			struct tspp_pid_filter *filter =
+				&pdev->filters[table_idx]->filter[i];
+			id = FILTER_GET_PIPE_NUMBER0(filter);
+			if (id == channel->id) {
+				if (FILTER_HAS_ENCRYPTION(filter))
+					tspp_free_key_entry(
+						FILTER_GET_KEY_NUMBER(filter));
+				filter->config = 0;
+				filter->filter = 0;
+			}
 		}
 	}
 	channel->filter_count = 0;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index f3133a0..d58379f 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -66,53 +66,67 @@
 }
 #endif
 
+static void sdhci_dump_state(struct sdhci_host *host)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	pr_info("%s: clk: %d clk-gated: %d claimer: %s pwr: %d\n",
+		mmc_hostname(mmc), host->clock, mmc->clk_gated,
+		mmc->claimer->comm, host->pwr);
+	pr_info("%s: rpmstatus[pltfm](runtime-suspend:usage_count:disable_depth)(%d:%d:%d)\n",
+		mmc_hostname(mmc), mmc->parent->power.runtime_status,
+		atomic_read(&mmc->parent->power.usage_count),
+		mmc->parent->power.disable_depth);
+}
+
 static void sdhci_dumpregs(struct sdhci_host *host)
 {
-	pr_debug(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
+	pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
 		mmc_hostname(host->mmc));
 
-	pr_debug(DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
+	pr_info(DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
 		sdhci_readl(host, SDHCI_DMA_ADDRESS),
 		sdhci_readw(host, SDHCI_HOST_VERSION));
-	pr_debug(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
+	pr_info(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
 		sdhci_readw(host, SDHCI_BLOCK_SIZE),
 		sdhci_readw(host, SDHCI_BLOCK_COUNT));
-	pr_debug(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
 		sdhci_readl(host, SDHCI_ARGUMENT),
 		sdhci_readw(host, SDHCI_TRANSFER_MODE));
-	pr_debug(DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
 		sdhci_readl(host, SDHCI_PRESENT_STATE),
 		sdhci_readb(host, SDHCI_HOST_CONTROL));
-	pr_debug(DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
+	pr_info(DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
 		sdhci_readb(host, SDHCI_POWER_CONTROL),
 		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
-	pr_debug(DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
+	pr_info(DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
 		sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
 		sdhci_readw(host, SDHCI_CLOCK_CONTROL));
-	pr_debug(DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
 		sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
 		sdhci_readl(host, SDHCI_INT_STATUS));
-	pr_debug(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
 		sdhci_readl(host, SDHCI_INT_ENABLE),
 		sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
-	pr_debug(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
+	pr_info(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
 		sdhci_readw(host, SDHCI_ACMD12_ERR),
 		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
-	pr_debug(DRIVER_NAME ": Caps:     0x%08x | Caps_1:   0x%08x\n",
+	pr_info(DRIVER_NAME ": Caps:     0x%08x | Caps_1:   0x%08x\n",
 		sdhci_readl(host, SDHCI_CAPABILITIES),
 		sdhci_readl(host, SDHCI_CAPABILITIES_1));
-	pr_debug(DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
 		sdhci_readw(host, SDHCI_COMMAND),
 		sdhci_readl(host, SDHCI_MAX_CURRENT));
-	pr_debug(DRIVER_NAME ": Host ctl2: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Host ctl2: 0x%08x\n",
 		sdhci_readw(host, SDHCI_HOST_CONTROL2));
 
 	if (host->flags & SDHCI_USE_ADMA)
-		pr_debug(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
+		pr_info(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
 		       readl(host->ioaddr + SDHCI_ADMA_ERROR),
 		       readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
 
-	pr_debug(DRIVER_NAME ": ===========================================\n");
+	sdhci_dump_state(host);
+	pr_info(DRIVER_NAME ": ===========================================\n");
 }
 
 /*****************************************************************************\
@@ -1372,6 +1386,17 @@
 	}
 }
 
+static bool sdhci_check_state(struct sdhci_host *host)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	if (!host->clock || !host->pwr ||
+	    pm_runtime_suspended(mmc->parent))
+		return true;
+	else
+		return false;
+}
+
 static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct sdhci_host *host;
@@ -1381,6 +1406,15 @@
 	host = mmc_priv(mmc);
 
 	sdhci_runtime_pm_get(host);
+	if (sdhci_check_state(host)) {
+		sdhci_dump_state(host);
+		WARN(1, "sdhci in bad state");
+		mrq->cmd->error = -EIO;
+		if (mrq->data)
+			mrq->data->error = -EIO;
+		tasklet_schedule(&host->finish_tasklet);
+		return;
+	}
 
 	spin_lock_irqsave(&host->lock, flags);
 
@@ -2217,6 +2251,11 @@
 		sdhci_dumpregs(host);
 
 		if (host->data) {
+			pr_info("%s: bytes to transfer: %d transferred: %d\n",
+				mmc_hostname(host->mmc),
+				(host->data->blksz * host->data->blocks),
+				(sdhci_readw(host, SDHCI_BLOCK_SIZE) & 0xFFF) *
+				sdhci_readw(host, SDHCI_BLOCK_COUNT));
 			host->data->error = -ETIMEDOUT;
 			sdhci_finish_data(host);
 		} else {
@@ -2354,6 +2393,7 @@
 static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
 {
 	u32 command;
+	bool pr_msg = false;
 	BUG_ON(intmask == 0);
 
 	/* CMD19 generates _only_ Buffer Read Ready interrupt */
@@ -2401,10 +2441,25 @@
 		sdhci_show_adma_error(host);
 		host->data->error = -EIO;
 	}
-
-	if (host->data->error)
+	if (host->data->error) {
+		if ((intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT)) &&
+		    (host->quirks2 & SDHCI_QUIRK2_IGNORE_CMDCRC_FOR_TUNING)) {
+			command = SDHCI_GET_CMD(sdhci_readw(host,
+							    SDHCI_COMMAND));
+			if ((command != MMC_SEND_TUNING_BLOCK_HS200) &&
+			    (command != MMC_SEND_TUNING_BLOCK))
+				pr_msg = true;
+		} else {
+			pr_msg = true;
+		}
+		if (pr_msg) {
+			pr_err("%s: data txfr (0x%08x) error: %d\n",
+			       mmc_hostname(host->mmc), intmask,
+			       host->data->error);
+			sdhci_dumpregs(host);
+		}
 		sdhci_finish_data(host);
-	else {
+	} else {
 		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
 			sdhci_transfer_pio(host);
 
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index cb5be3d..2765836 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -71,9 +71,9 @@
 #define BMS1_VBAT_AVG_DATA0		0x9E
 #define BMS1_VBAT_AVG_DATA1		0x9F
 /* Extra bms registers */
-#define BMS1_BMS_DATA_REG_0		0xB0
+#define SOC_STORAGE_REG			0xB0
 #define IAVG_STORAGE_REG		0xB1
-#define SOC_STORAGE_REG			0xB2
+#define BMS1_BMS_DATA_REG_2		0xB2
 #define BMS1_BMS_DATA_REG_3		0xB3
 /* IADC Channel Select */
 #define IADC1_BMS_ADC_CH_SEL_CTL	0x48
@@ -83,7 +83,7 @@
 #define IAVG_STEP_SIZE_MA		50
 #define IAVG_START			600
 #define IAVG_INVALID			0xFF
-#define SOC_ZERO			0xFF
+#define SOC_INVALID			0xFF
 
 #define IAVG_SAMPLES 16
 
@@ -184,7 +184,6 @@
 	unsigned int			vadc_v1250;
 
 	int				ibat_max_ua;
-	int				prev_iavg_ua;
 	int				prev_uuc_iavg_ma;
 	int				prev_pc_unusable;
 	int				ibat_at_cv_ua;
@@ -849,33 +848,27 @@
 	return rbatt_mohm;
 }
 
+#define IAVG_MINIMAL_TIME	2
 static void calculate_iavg(struct qpnp_bms_chip *chip, int cc_uah,
 				int *iavg_ua, int delta_time_s)
 {
 	int delta_cc_uah = 0;
 
-	/* if anything fails report the previous iavg_ua */
-	*iavg_ua = chip->prev_iavg_ua;
-
-	if (chip->last_cc_uah == INT_MIN) {
+	/*
+	 * use the battery current if called too quickly
+	 */
+	if (delta_time_s < IAVG_MINIMAL_TIME
+			|| chip->last_cc_uah == INT_MIN) {
 		get_battery_current(chip, iavg_ua);
 		goto out;
 	}
 
-	/* use the previous iavg if called within 15 seconds */
-	if (delta_time_s < 15) {
-		*iavg_ua = chip->prev_iavg_ua;
-		goto out;
-	}
-
 	delta_cc_uah = cc_uah - chip->last_cc_uah;
 
 	*iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
 
 out:
 	pr_debug("delta_cc = %d iavg_ua = %d\n", delta_cc_uah, (int)*iavg_ua);
-	/* remember the iavg */
-	chip->prev_iavg_ua = *iavg_ua;
 
 	/* remember cc_uah */
 	chip->last_cc_uah = cc_uah;
@@ -1734,10 +1727,7 @@
 	rc = qpnp_write_wrapper(chip, &temp,
 			chip->base + IAVG_STORAGE_REG, 1);
 
-	if (soc == 0)
-		temp = SOC_ZERO;
-	else
-		temp = soc;
+	temp = soc;
 
 	/* don't store soc if temperature is below 5degC */
 	if (batt_temp > IGNORE_SOC_TEMP_DECIDEG)
@@ -2069,12 +2059,10 @@
 		} else {
 			chip->shutdown_soc = temp;
 
-			if (chip->shutdown_soc == 0) {
+			if (chip->shutdown_soc == SOC_INVALID) {
 				pr_debug("No shutdown soc available\n");
 				chip->shutdown_soc_invalid = true;
 				chip->shutdown_iavg_ma = 0;
-			} else if (chip->shutdown_soc == SOC_ZERO) {
-				chip->shutdown_soc = 0;
 			}
 		}
 	}
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index 4e1fb31..45e6c78 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -47,6 +47,7 @@
 enum msm_camera_i2c_reg_addr_type {
 	MSM_CAMERA_I2C_BYTE_ADDR = 1,
 	MSM_CAMERA_I2C_WORD_ADDR,
+	MSM_CAMERA_I2C_3B_ADDR,
 };
 
 enum msm_camera_i2c_data_type {
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 9c310a9..afd5a42 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1550,6 +1550,7 @@
 enum msm_camera_i2c_reg_addr_type {
 	MSM_CAMERA_I2C_BYTE_ADDR = 1,
 	MSM_CAMERA_I2C_WORD_ADDR,
+	MSM_CAMERA_I2C_3B_ADDR,
 };
 
 struct msm_camera_i2c_reg_array {
diff --git a/include/video/Kbuild b/include/video/Kbuild
index ad3e622..53e13cb 100644
--- a/include/video/Kbuild
+++ b/include/video/Kbuild
@@ -1,3 +1,4 @@
 header-y += edid.h
 header-y += sisfb.h
 header-y += uvesafb.h
+header-y += msm_hdmi_modes.h
diff --git a/include/video/msm_hdmi_modes.h b/include/video/msm_hdmi_modes.h
new file mode 100644
index 0000000..a15272b
--- /dev/null
+++ b/include/video/msm_hdmi_modes.h
@@ -0,0 +1,334 @@
+#ifndef __MSM_HDMI_MODES_H__
+#define __MSM_HDMI_MODES_H__
+#include <linux/types.h>
+
+struct msm_hdmi_mode_timing_info {
+	uint32_t	video_format;
+	uint32_t	active_h;
+	uint32_t	front_porch_h;
+	uint32_t	pulse_width_h;
+	uint32_t	back_porch_h;
+	uint32_t	active_low_h;
+	uint32_t	active_v;
+	uint32_t	front_porch_v;
+	uint32_t	pulse_width_v;
+	uint32_t	back_porch_v;
+	uint32_t	active_low_v;
+	/* Must divide by 1000 to get the actual frequency in MHZ */
+	uint32_t	pixel_freq;
+	/* Must divide by 1000 to get the actual frequency in HZ */
+	uint32_t	refresh_rate;
+	uint32_t	interlaced;
+	uint32_t	supported;
+};
+
+#define MSM_HDMI_MODES_CEA		(1 << 0)
+#define MSM_HDMI_MODES_XTND		(1 << 1)
+#define MSM_HDMI_MODES_DVI		(1 << 2)
+#define MSM_HDMI_MODES_ALL		(MSM_HDMI_MODES_CEA |\
+					 MSM_HDMI_MODES_XTND |\
+					 MSM_HDMI_MODES_DVI)
+
+/* all video formats defined by CEA 861D */
+#define HDMI_VFRMT_UNKNOWN		0
+#define HDMI_VFRMT_640x480p60_4_3	1
+#define HDMI_VFRMT_720x480p60_4_3	2
+#define HDMI_VFRMT_720x480p60_16_9	3
+#define HDMI_VFRMT_1280x720p60_16_9	4
+#define HDMI_VFRMT_1920x1080i60_16_9	5
+#define HDMI_VFRMT_720x480i60_4_3	6
+#define HDMI_VFRMT_1440x480i60_4_3	HDMI_VFRMT_720x480i60_4_3
+#define HDMI_VFRMT_720x480i60_16_9	7
+#define HDMI_VFRMT_1440x480i60_16_9	HDMI_VFRMT_720x480i60_16_9
+#define HDMI_VFRMT_720x240p60_4_3	8
+#define HDMI_VFRMT_1440x240p60_4_3	HDMI_VFRMT_720x240p60_4_3
+#define HDMI_VFRMT_720x240p60_16_9	9
+#define HDMI_VFRMT_1440x240p60_16_9	HDMI_VFRMT_720x240p60_16_9
+#define HDMI_VFRMT_2880x480i60_4_3	10
+#define HDMI_VFRMT_2880x480i60_16_9	11
+#define HDMI_VFRMT_2880x240p60_4_3	12
+#define HDMI_VFRMT_2880x240p60_16_9	13
+#define HDMI_VFRMT_1440x480p60_4_3	14
+#define HDMI_VFRMT_1440x480p60_16_9	15
+#define HDMI_VFRMT_1920x1080p60_16_9	16
+#define HDMI_VFRMT_720x576p50_4_3	17
+#define HDMI_VFRMT_720x576p50_16_9	18
+#define HDMI_VFRMT_1280x720p50_16_9	19
+#define HDMI_VFRMT_1920x1080i50_16_9	20
+#define HDMI_VFRMT_720x576i50_4_3	21
+#define HDMI_VFRMT_1440x576i50_4_3	HDMI_VFRMT_720x576i50_4_3
+#define HDMI_VFRMT_720x576i50_16_9	22
+#define HDMI_VFRMT_1440x576i50_16_9	HDMI_VFRMT_720x576i50_16_9
+#define HDMI_VFRMT_720x288p50_4_3	23
+#define HDMI_VFRMT_1440x288p50_4_3	HDMI_VFRMT_720x288p50_4_3
+#define HDMI_VFRMT_720x288p50_16_9	24
+#define HDMI_VFRMT_1440x288p50_16_9	HDMI_VFRMT_720x288p50_16_9
+#define HDMI_VFRMT_2880x576i50_4_3	25
+#define HDMI_VFRMT_2880x576i50_16_9	26
+#define HDMI_VFRMT_2880x288p50_4_3	27
+#define HDMI_VFRMT_2880x288p50_16_9	28
+#define HDMI_VFRMT_1440x576p50_4_3	29
+#define HDMI_VFRMT_1440x576p50_16_9	30
+#define HDMI_VFRMT_1920x1080p50_16_9	31
+#define HDMI_VFRMT_1920x1080p24_16_9	32
+#define HDMI_VFRMT_1920x1080p25_16_9	33
+#define HDMI_VFRMT_1920x1080p30_16_9	34
+#define HDMI_VFRMT_2880x480p60_4_3	35
+#define HDMI_VFRMT_2880x480p60_16_9	36
+#define HDMI_VFRMT_2880x576p50_4_3	37
+#define HDMI_VFRMT_2880x576p50_16_9	38
+#define HDMI_VFRMT_1920x1250i50_16_9	39
+#define HDMI_VFRMT_1920x1080i100_16_9	40
+#define HDMI_VFRMT_1280x720p100_16_9	41
+#define HDMI_VFRMT_720x576p100_4_3	42
+#define HDMI_VFRMT_720x576p100_16_9	43
+#define HDMI_VFRMT_720x576i100_4_3	44
+#define HDMI_VFRMT_1440x576i100_4_3	HDMI_VFRMT_720x576i100_4_3
+#define HDMI_VFRMT_720x576i100_16_9	45
+#define HDMI_VFRMT_1440x576i100_16_9	HDMI_VFRMT_720x576i100_16_9
+#define HDMI_VFRMT_1920x1080i120_16_9	46
+#define HDMI_VFRMT_1280x720p120_16_9	47
+#define HDMI_VFRMT_720x480p120_4_3	48
+#define HDMI_VFRMT_720x480p120_16_9	49
+#define HDMI_VFRMT_720x480i120_4_3	50
+#define HDMI_VFRMT_1440x480i120_4_3	HDMI_VFRMT_720x480i120_4_3
+#define HDMI_VFRMT_720x480i120_16_9	51
+#define HDMI_VFRMT_1440x480i120_16_9	HDMI_VFRMT_720x480i120_16_9
+#define HDMI_VFRMT_720x576p200_4_3	52
+#define HDMI_VFRMT_720x576p200_16_9	53
+#define HDMI_VFRMT_720x576i200_4_3	54
+#define HDMI_VFRMT_1440x576i200_4_3	HDMI_VFRMT_720x576i200_4_3
+#define HDMI_VFRMT_720x576i200_16_9	55
+#define HDMI_VFRMT_1440x576i200_16_9	HDMI_VFRMT_720x576i200_16_9
+#define HDMI_VFRMT_720x480p240_4_3	56
+#define HDMI_VFRMT_720x480p240_16_9	57
+#define HDMI_VFRMT_720x480i240_4_3	58
+#define HDMI_VFRMT_1440x480i240_4_3	HDMI_VFRMT_720x480i240_4_3
+#define HDMI_VFRMT_720x480i240_16_9	59
+#define HDMI_VFRMT_1440x480i240_16_9	HDMI_VFRMT_720x480i240_16_9
+#define HDMI_VFRMT_1280x720p24_16_9	60
+#define HDMI_VFRMT_1280x720p25_16_9	61
+#define HDMI_VFRMT_1280x720p30_16_9	62
+#define HDMI_VFRMT_1920x1080p120_16_9	63
+#define HDMI_VFRMT_1920x1080p100_16_9	64
+/* Video Identification Codes from 65-127 are reserved for the future */
+#define HDMI_VFRMT_END			127
+
+/* extended video formats */
+#define HDMI_VFRMT_3840x2160p30_16_9	(HDMI_VFRMT_END + 1)
+#define HDMI_VFRMT_3840x2160p25_16_9	(HDMI_VFRMT_END + 2)
+#define HDMI_VFRMT_3840x2160p24_16_9	(HDMI_VFRMT_END + 3)
+#define HDMI_VFRMT_4096x2160p24_16_9	(HDMI_VFRMT_END + 4)
+#define HDMI_EVFRMT_END			HDMI_VFRMT_4096x2160p24_16_9
+
+/* VESA DMT TIMINGS */
+#define HDMI_VFRMT_2560x1600p60_16_9	(HDMI_EVFRMT_END + 1)
+#define HDMI_VFRMT_1280x1024p60_5_4	(HDMI_EVFRMT_END + 2)
+#define VESA_DMT_VFRMT_END		HDMI_VFRMT_1280x1024p60_5_4
+#define HDMI_VFRMT_MAX			(VESA_DMT_VFRMT_END + 1)
+#define HDMI_VFRMT_FORCE_32BIT		0x7FFFFFFF
+
+/* Timing information for supported modes */
+#define VFRMT_NOT_SUPPORTED(VFRMT) \
+	{VFRMT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false}
+
+#define HDMI_VFRMT_640x480p60_4_3_TIMING				\
+	{HDMI_VFRMT_640x480p60_4_3, 640, 16, 96, 48, true,		\
+	 480, 10, 2, 33, true, 25200, 60000, false, true}
+#define HDMI_VFRMT_720x480p60_4_3_TIMING				\
+	{HDMI_VFRMT_720x480p60_4_3, 720, 16, 62, 60, true,		\
+	 480, 9, 6, 30, true, 27030, 60000, false, true}
+#define HDMI_VFRMT_720x480p60_16_9_TIMING				\
+	{HDMI_VFRMT_720x480p60_16_9, 720, 16, 62, 60, true,		\
+	 480, 9, 6, 30, true, 27030, 60000, false, true}
+#define HDMI_VFRMT_1280x720p60_16_9_TIMING				\
+	{HDMI_VFRMT_1280x720p60_16_9, 1280, 110, 40, 220, false,	\
+	 720, 5, 5, 20, false, 74250, 60000, false, true}
+#define HDMI_VFRMT_1920x1080i60_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080i60_16_9, 1920, 88, 44, 148, false,	\
+	 540, 2, 5, 5, false, 74250, 60000, false, true}
+#define HDMI_VFRMT_1440x480i60_4_3_TIMING				\
+	{HDMI_VFRMT_1440x480i60_4_3, 1440, 38, 124, 114, true,		\
+	 240, 4, 3, 15, true, 27000, 60000, true, true}
+#define HDMI_VFRMT_1440x480i60_16_9_TIMING				\
+	{HDMI_VFRMT_1440x480i60_16_9, 1440, 38, 124, 114, true,		\
+	 240, 4, 3, 15, true, 27000, 60000, true, true}
+#define HDMI_VFRMT_1920x1080p60_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p60_16_9, 1920, 88, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 148500, 60000, false, true}
+#define HDMI_VFRMT_720x576p50_4_3_TIMING				\
+	{HDMI_VFRMT_720x576p50_4_3, 720, 12, 64, 68, true,		\
+	 576,  5, 5, 39, true, 27000, 50000, false, true}
+#define HDMI_VFRMT_720x576p50_16_9_TIMING				\
+	{HDMI_VFRMT_720x576p50_16_9, 720, 12, 64, 68, true,		\
+	 576,  5, 5, 39, true, 27000, 50000, false, true}
+#define HDMI_VFRMT_1280x720p50_16_9_TIMING				\
+	{HDMI_VFRMT_1280x720p50_16_9, 1280, 440, 40, 220, false,	\
+	 720,  5, 5, 20, false, 74250, 50000, false, true}
+#define HDMI_VFRMT_1440x576i50_4_3_TIMING				\
+	{HDMI_VFRMT_1440x576i50_4_3, 1440, 24, 126, 138, true,		\
+	 288,  2, 3, 19, true, 27000, 50000, true, true}
+#define HDMI_VFRMT_1440x576i50_16_9_TIMING				\
+	{HDMI_VFRMT_1440x576i50_16_9, 1440, 24, 126, 138, true,		\
+	 288,  2, 3, 19, true, 27000, 50000, true, true}
+#define HDMI_VFRMT_1920x1080p50_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p50_16_9, 1920, 528, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 148500, 50000, false, true}
+#define HDMI_VFRMT_1920x1080p24_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p24_16_9, 1920, 638, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 24000, false, true}
+#define HDMI_VFRMT_1920x1080p25_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p25_16_9, 1920, 528, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 25000, false, true}
+#define HDMI_VFRMT_1920x1080p30_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p30_16_9, 1920, 88, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 30000, false, true}
+#define HDMI_VFRMT_1280x1024p60_5_4_TIMING				\
+	{HDMI_VFRMT_1280x1024p60_5_4, 1280, 48, 112, 248, false,	\
+	1024, 1, 3, 38, false, 108000, 60000, false, true}
+#define HDMI_VFRMT_2560x1600p60_16_9_TIMING				\
+	{HDMI_VFRMT_2560x1600p60_16_9, 2560, 48, 32, 80, false,		\
+	 1600, 3, 6, 37, false, 268500, 60000, false, true}
+#define HDMI_VFRMT_3840x2160p30_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p30_16_9, 3840, 176, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 30000, false, true}
+#define HDMI_VFRMT_3840x2160p25_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p25_16_9, 3840, 1056, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 25000, false, true}
+#define HDMI_VFRMT_3840x2160p24_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p24_16_9, 3840, 1276, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 24000, false, true}
+#define HDMI_VFRMT_4096x2160p24_16_9_TIMING				\
+	{HDMI_VFRMT_4096x2160p24_16_9, 4096, 1020, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 24000, false, true}
+
+#define MSM_HDMI_MODES_SET_TIMING(LUT, MODE) do {		\
+	struct msm_hdmi_mode_timing_info mode = MODE##_TIMING;	\
+	LUT[MODE] = mode;\
+	} while (0)
+
+static inline void MSM_HDMI_MODES_INIT_TIMINGS(
+	struct msm_hdmi_mode_timing_info *lut)
+{
+	int i;
+
+	for (i = 0; i < HDMI_VFRMT_MAX; i++) {
+		struct msm_hdmi_mode_timing_info mode = VFRMT_NOT_SUPPORTED(i);
+		lut[i] = mode;
+	}
+}
+
+static inline void MSM_HDMI_MODES_SET_SUPP_TIMINGS(
+	struct msm_hdmi_mode_timing_info *lut, int type)
+{
+	if (type & MSM_HDMI_MODES_CEA) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_640x480p60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x480p60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x480p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x720p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080i60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x480i60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x480i60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x576p50_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x576p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x720p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x576i50_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x576i50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p24_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p25_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p30_16_9);
+	}
+
+	if (type & MSM_HDMI_MODES_XTND) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p30_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p25_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p24_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_4096x2160p24_16_9);
+	}
+
+	if (type & MSM_HDMI_MODES_DVI) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x1024p60_5_4);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_2560x1600p60_16_9);
+	}
+}
+
+static inline const char *msm_hdmi_mode_2string(uint32_t mode)
+{
+	switch (mode) {
+	case HDMI_VFRMT_UNKNOWN:		return "Unknown";
+	case HDMI_VFRMT_640x480p60_4_3:		return "640x480 p60 4/3";
+	case HDMI_VFRMT_720x480p60_4_3:		return "720x480 p60 4/3";
+	case HDMI_VFRMT_720x480p60_16_9:	return "720x480 p60 16/9";
+	case HDMI_VFRMT_1280x720p60_16_9:	return "1280x 720 p60 16/9";
+	case HDMI_VFRMT_1920x1080i60_16_9:	return "1920x1080 i60 16/9";
+	case HDMI_VFRMT_1440x480i60_4_3:	return "1440x480 i60 4/3";
+	case HDMI_VFRMT_1440x480i60_16_9:	return "1440x480 i60 16/9";
+	case HDMI_VFRMT_1440x240p60_4_3:	return "1440x240 p60 4/3";
+	case HDMI_VFRMT_1440x240p60_16_9:	return "1440x240 p60 16/9";
+	case HDMI_VFRMT_2880x480i60_4_3:	return "2880x480 i60 4/3";
+	case HDMI_VFRMT_2880x480i60_16_9:	return "2880x480 i60 16/9";
+	case HDMI_VFRMT_2880x240p60_4_3:	return "2880x240 p60 4/3";
+	case HDMI_VFRMT_2880x240p60_16_9:	return "2880x240 p60 16/9";
+	case HDMI_VFRMT_1440x480p60_4_3:	return "1440x480 p60 4/3";
+	case HDMI_VFRMT_1440x480p60_16_9:	return "1440x480 p60 16/9";
+	case HDMI_VFRMT_1920x1080p60_16_9:	return "1920x1080 p60 16/9";
+	case HDMI_VFRMT_720x576p50_4_3:		return "720x576 p50 4/3";
+	case HDMI_VFRMT_720x576p50_16_9:	return "720x576 p50 16/9";
+	case HDMI_VFRMT_1280x720p50_16_9:	return "1280x720 p50 16/9";
+	case HDMI_VFRMT_1920x1080i50_16_9:	return "1920x1080 i50 16/9";
+	case HDMI_VFRMT_1440x576i50_4_3:	return "1440x576 i50 4/3";
+	case HDMI_VFRMT_1440x576i50_16_9:	return "1440x576 i50 16/9";
+	case HDMI_VFRMT_1440x288p50_4_3:	return "1440x288 p50 4/3";
+	case HDMI_VFRMT_1440x288p50_16_9:	return "1440x288 p50 16/9";
+	case HDMI_VFRMT_2880x576i50_4_3:	return "2880x576 i50 4/3";
+	case HDMI_VFRMT_2880x576i50_16_9:	return "2880x576 i50 16/9";
+	case HDMI_VFRMT_2880x288p50_4_3:	return "2880x288 p50 4/3";
+	case HDMI_VFRMT_2880x288p50_16_9:	return "2880x288 p50 16/9";
+	case HDMI_VFRMT_1440x576p50_4_3:	return "1440x576 p50 4/3";
+	case HDMI_VFRMT_1440x576p50_16_9:	return "1440x576 p50 16/9";
+	case HDMI_VFRMT_1920x1080p50_16_9:	return "1920x1080 p50 16/9";
+	case HDMI_VFRMT_1920x1080p24_16_9:	return "1920x1080 p24 16/9";
+	case HDMI_VFRMT_1920x1080p25_16_9:	return "1920x1080 p25 16/9";
+	case HDMI_VFRMT_1920x1080p30_16_9:	return "1920x1080 p30 16/9";
+	case HDMI_VFRMT_2880x480p60_4_3:	return "2880x480 p60 4/3";
+	case HDMI_VFRMT_2880x480p60_16_9:	return "2880x480 p60 16/9";
+	case HDMI_VFRMT_2880x576p50_4_3:	return "2880x576 p50 4/3";
+	case HDMI_VFRMT_2880x576p50_16_9:	return "2880x576 p50 16/9";
+	case HDMI_VFRMT_1920x1250i50_16_9:	return "1920x1250 i50 16/9";
+	case HDMI_VFRMT_1920x1080i100_16_9:	return "1920x1080 i100 16/9";
+	case HDMI_VFRMT_1280x720p100_16_9:	return "1280x720 p100 16/9";
+	case HDMI_VFRMT_720x576p100_4_3:	return "720x576 p100 4/3";
+	case HDMI_VFRMT_720x576p100_16_9:	return "720x576 p100 16/9";
+	case HDMI_VFRMT_1440x576i100_4_3:	return "1440x576 i100 4/3";
+	case HDMI_VFRMT_1440x576i100_16_9:	return "1440x576 i100 16/9";
+	case HDMI_VFRMT_1920x1080i120_16_9:	return "1920x1080 i120 16/9";
+	case HDMI_VFRMT_1280x720p120_16_9:	return "1280x720 p120 16/9";
+	case HDMI_VFRMT_720x480p120_4_3:	return "720x480 p120 4/3";
+	case HDMI_VFRMT_720x480p120_16_9:	return "720x480 p120 16/9";
+	case HDMI_VFRMT_1440x480i120_4_3:	return "1440x480 i120 4/3";
+	case HDMI_VFRMT_1440x480i120_16_9:	return "1440x480 i120 16/9";
+	case HDMI_VFRMT_720x576p200_4_3:	return "720x576 p200 4/3";
+	case HDMI_VFRMT_720x576p200_16_9:	return "720x576 p200 16/9";
+	case HDMI_VFRMT_1440x576i200_4_3:	return "1440x576 i200 4/3";
+	case HDMI_VFRMT_1440x576i200_16_9:	return "1440x576 i200 16/9";
+	case HDMI_VFRMT_720x480p240_4_3:	return "720x480 p240 4/3";
+	case HDMI_VFRMT_720x480p240_16_9:	return "720x480 p240 16/9";
+	case HDMI_VFRMT_1440x480i240_4_3:	return "1440x480 i240 4/3";
+	case HDMI_VFRMT_1440x480i240_16_9:	return "1440x480 i240 16/9";
+	case HDMI_VFRMT_1280x720p24_16_9:	return "1280x720 p24 16/9";
+	case HDMI_VFRMT_1280x720p25_16_9:	return "1280x720 p25 16/9";
+	case HDMI_VFRMT_1280x720p30_16_9:	return "1280x720 p30 16/9";
+	case HDMI_VFRMT_1920x1080p120_16_9:	return "1920x1080 p120 16/9";
+	case HDMI_VFRMT_1920x1080p100_16_9:	return "1920x1080 p100 16/9";
+	case HDMI_VFRMT_3840x2160p30_16_9:	return "3840x2160 p30 16/9";
+	case HDMI_VFRMT_3840x2160p25_16_9:	return "3840x2160 p25 16/9";
+	case HDMI_VFRMT_3840x2160p24_16_9:	return "3840x2160 p24 16/9";
+	case HDMI_VFRMT_4096x2160p24_16_9:	return "4096x2160 p24 16/9";
+	case HDMI_VFRMT_2560x1600p60_16_9:	return "2560x1600 p60 16/9";
+	case HDMI_VFRMT_1280x1024p60_5_4:	return "1280x1042 p60 5/4";
+	default:				return "???";
+	}
+}
+#endif /* __MSM_HDMI_MODES_H__ */