Merge "msm: copper: Low Power Resource manager driver" into msm-3.4
diff --git a/arch/arm/boot/dts/msmcopper-iommu.dtsi b/arch/arm/boot/dts/msmcopper-iommu.dtsi
index e0ce8ac..697136a 100644
--- a/arch/arm/boot/dts/msmcopper-iommu.dtsi
+++ b/arch/arm/boot/dts/msmcopper-iommu.dtsi
@@ -17,6 +17,7 @@
 		#size-cells = <1>;
 		ranges;
 		reg = <0xfda64000 0x10000>;
+		vdd-supply = <&gdsc_jpeg>;
 
 		qcom,iommu-ctx@fda6c000 {
 			reg = <0xfda6c000 0x1000>;
@@ -44,6 +45,7 @@
 		#size-cells = <1>;
 		ranges;
 		reg = <0xfd928000 0x10000>;
+		vdd-supply = <&gdsc_mdss>;
 
 		qcom,iommu-ctx@fd930000 {
 			reg = <0xfd930000 0x1000>;
@@ -65,6 +67,7 @@
 		#size-cells = <1>;
 		ranges;
 		reg = <0xfdc84000 0x10000>;
+		vdd-supply = <&gdsc_venus>;
 
 		qcom,iommu-ctx@fdc8c000 {
 			reg = <0xfdc8c000 0x1000>;
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index d8543f3..6d2c25a 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -94,6 +94,7 @@
 	VFE_MSG_V2X_CAPTURE,
 	VFE_MSG_OUTPUT_PRIMARY,
 	VFE_MSG_OUTPUT_SECONDARY,
+	VFE_MSG_OUTPUT_TERTIARY1,
 };
 
 enum vpe_resp_msg {
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index b57ae10..4bfbe61 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -15,6 +15,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/clk.h>
+#include <linux/regulator/consumer.h>
 #include <mach/socinfo.h>
 
 extern pgprot_t     pgprot_kernel;
@@ -79,6 +80,7 @@
 	struct clk *clk;
 	struct clk *pclk;
 	const char *name;
+	struct regulator *gdsc;
 };
 
 /**
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index dae64cb..9c8f7ee 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -170,11 +170,10 @@
 	CLK_SUSPEND,
 };
 
-int msm_rotator_iommu_map_buf(int mem_id, unsigned char src,
+int msm_rotator_iommu_map_buf(int mem_id, int domain,
 	unsigned long *start, unsigned long *len,
-	struct ion_handle **pihdl)
+	struct ion_handle **pihdl, unsigned int secure)
 {
-	int domain;
 	if (!msm_rotator_dev->client)
 		return -EINVAL;
 
@@ -186,12 +185,20 @@
 	pr_debug("%s(): ion_hdl %p, ion_buf %p\n", __func__, *pihdl,
 		ion_share(msm_rotator_dev->client, *pihdl));
 
-	domain = src ? ROTATOR_SRC_DOMAIN : ROTATOR_DST_DOMAIN;
-	if (ion_map_iommu(msm_rotator_dev->client,
-		*pihdl,	domain, GEN_POOL,
-		SZ_4K, 0, start, len, 0, ION_IOMMU_UNMAP_DELAYED)) {
-		pr_err("ion_map_iommu() failed\n");
-		return -EINVAL;
+	if (secure) {
+		if (ion_phys(msm_rotator_dev->client,
+			*pihdl, start, (unsigned *)len)) {
+			pr_err("%s:%d: ion_phys map failed\n",
+				 __func__, __LINE__);
+			return -ENOMEM;
+		}
+	} else {
+		if (ion_map_iommu(msm_rotator_dev->client,
+			*pihdl,	domain, GEN_POOL,
+			SZ_4K, 0, start, len, 0, ION_IOMMU_UNMAP_DELAYED)) {
+			pr_err("ion_map_iommu() failed\n");
+			return -EINVAL;
+		}
 	}
 
 	pr_debug("%s(): mem_id %d, start 0x%lx, len 0x%lx\n",
@@ -808,9 +815,9 @@
 	return 0;
 }
 
-static int get_img(struct msmfb_data *fbd, unsigned char src,
+static int get_img(struct msmfb_data *fbd, int domain,
 	unsigned long *start, unsigned long *len, struct file **p_file,
-	int *p_need, struct ion_handle **p_ihdl)
+	int *p_need, struct ion_handle **p_ihdl, unsigned int secure)
 {
 	int ret = 0;
 #ifdef CONFIG_FB
@@ -852,8 +859,8 @@
 #endif
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	return msm_rotator_iommu_map_buf(fbd->memory_id, src, start,
-		len, p_ihdl);
+	return msm_rotator_iommu_map_buf(fbd->memory_id, domain, start,
+		len, p_ihdl, secure);
 #endif
 #ifdef CONFIG_ANDROID_PMEM
 	if (!get_pmem_file(fbd->memory_id, start, &vstart, len, p_file))
@@ -865,7 +872,7 @@
 }
 
 static void put_img(struct file *p_file, struct ion_handle *p_ihdl,
-	unsigned char src)
+	int domain, unsigned int secure)
 {
 #ifdef CONFIG_ANDROID_PMEM
 	if (p_file != NULL)
@@ -874,11 +881,10 @@
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	if (!IS_ERR_OR_NULL(p_ihdl)) {
-		int domain = src ? ROTATOR_SRC_DOMAIN : \
-			ROTATOR_DST_DOMAIN;
 		pr_debug("%s(): p_ihdl %p\n", __func__, p_ihdl);
-		ion_unmap_iommu(msm_rotator_dev->client,
-			p_ihdl, domain, GEN_POOL);
+		if (!secure)
+			ion_unmap_iommu(msm_rotator_dev->client,
+				p_ihdl, domain, GEN_POOL);
 
 		ion_free(msm_rotator_dev->client, p_ihdl);
 	}
@@ -945,18 +951,18 @@
 		goto do_rotate_unlock_mutex;
 	}
 
-	rc = get_img(&info.src, 1, (unsigned long *)&in_paddr,
+	rc = get_img(&info.src, ROTATOR_SRC_DOMAIN, (unsigned long *)&in_paddr,
 			(unsigned long *)&src_len, &srcp0_file, &ps0_need,
-			&srcp0_ihdl);
+			&srcp0_ihdl, 0);
 	if (rc) {
 		pr_err("%s: in get_img() failed id=0x%08x\n",
 			DRIVER_NAME, info.src.memory_id);
 		goto do_rotate_unlock_mutex;
 	}
 
-	rc = get_img(&info.dst, 0, (unsigned long *)&out_paddr,
+	rc = get_img(&info.dst, ROTATOR_DST_DOMAIN, (unsigned long *)&out_paddr,
 			(unsigned long *)&dst_len, &dstp0_file, &p_need,
-			&dstp0_ihdl);
+			&dstp0_ihdl, img_info->secure);
 	if (rc) {
 		pr_err("%s: out get_img() failed id=0x%08x\n",
 		       DRIVER_NAME, info.dst.memory_id);
@@ -984,20 +990,20 @@
 			goto do_rotate_unlock_mutex;
 		}
 
-		rc = get_img(&info.src_chroma, 1,
+		rc = get_img(&info.src_chroma, ROTATOR_SRC_DOMAIN,
 				(unsigned long *)&in_chroma_paddr,
 				(unsigned long *)&src_len, &srcp1_file, &p_need,
-				&srcp1_ihdl);
+				&srcp1_ihdl, 0);
 		if (rc) {
 			pr_err("%s: in chroma get_img() failed id=0x%08x\n",
 				DRIVER_NAME, info.src_chroma.memory_id);
 			goto do_rotate_unlock_mutex;
 		}
 
-		rc = get_img(&info.dst_chroma, 0,
+		rc = get_img(&info.dst_chroma, ROTATOR_DST_DOMAIN,
 				(unsigned long *)&out_chroma_paddr,
 				(unsigned long *)&dst_len, &dstp1_file, &p_need,
-				&dstp1_ihdl);
+				&dstp1_ihdl, img_info->secure);
 		if (rc) {
 			pr_err("%s: out chroma get_img() failed id=0x%08x\n",
 				DRIVER_NAME, info.dst_chroma.memory_id);
@@ -1168,15 +1174,17 @@
 #endif
 	schedule_delayed_work(&msm_rotator_dev->rot_clk_work, HZ);
 do_rotate_unlock_mutex:
-	put_img(dstp1_file, dstp1_ihdl, 0);
-	put_img(srcp1_file, srcp1_ihdl, 1);
-	put_img(dstp0_file, dstp0_ihdl, 0);
+	put_img(dstp1_file, dstp1_ihdl, ROTATOR_DST_DOMAIN,
+		msm_rotator_dev->img_info[s]->secure);
+	put_img(srcp1_file, srcp1_ihdl, ROTATOR_SRC_DOMAIN, 0);
+	put_img(dstp0_file, dstp0_ihdl, ROTATOR_DST_DOMAIN,
+		msm_rotator_dev->img_info[s]->secure);
 
 	/* only source may use frame buffer */
 	if (info.src.flags & MDP_MEMORY_ID_TYPE_FB)
 		fput_light(srcp0_file, ps0_need);
 	else
-		put_img(srcp0_file, srcp0_ihdl, 1);
+		put_img(srcp0_file, srcp0_ihdl, ROTATOR_SRC_DOMAIN, 0);
 	mutex_unlock(&msm_rotator_dev->rotator_lock);
 	dev_dbg(msm_rotator_dev->device, "%s() returning rc = %d\n",
 		__func__, rc);
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 58a0963..56696c4 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2558,11 +2558,6 @@
 {
 	struct kgsl_device *device = &adreno_dev->dev;
 
-	/* Reset the core */
-	adreno_regwrite(device, A3XX_RBBM_SW_RESET_CMD,
-		0x00000001);
-	msleep(20);
-
 	/* Set up 16 deep read/write request queues */
 
 	adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010);
diff --git a/drivers/iommu/msm_iommu-v2.c b/drivers/iommu/msm_iommu-v2.c
index 2ae9f28..6e62e60 100644
--- a/drivers/iommu/msm_iommu-v2.c
+++ b/drivers/iommu/msm_iommu-v2.c
@@ -25,7 +25,7 @@
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-
+#include <linux/regulator/consumer.h>
 #include <asm/sizes.h>
 
 #include <mach/iommu_hw-v2.h>
@@ -383,10 +383,16 @@
 		goto fail;
 	}
 
-	ret = __enable_clocks(iommu_drvdata);
+	ret = regulator_enable(iommu_drvdata->gdsc);
 	if (ret)
 		goto fail;
 
+	ret = __enable_clocks(iommu_drvdata);
+	if (ret) {
+		regulator_disable(iommu_drvdata->gdsc);
+		goto fail;
+	}
+
 	if (!msm_iommu_ctx_attached(dev->parent))
 		__program_iommu(iommu_drvdata->base);
 
@@ -431,6 +437,8 @@
 	__reset_context(iommu_drvdata->base, ctx_drvdata->num);
 	__disable_clocks(iommu_drvdata);
 
+	regulator_disable(iommu_drvdata->gdsc);
+
 	list_del_init(&ctx_drvdata->attached_elm);
 	ctx_drvdata->attached_domain = NULL;
 
diff --git a/drivers/iommu/msm_iommu_dev-v2.c b/drivers/iommu/msm_iommu_dev-v2.c
index d6858de..87e1a46 100644
--- a/drivers/iommu/msm_iommu_dev-v2.c
+++ b/drivers/iommu/msm_iommu_dev-v2.c
@@ -75,6 +75,10 @@
 	if (!drvdata->base)
 		return -ENOMEM;
 
+	drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
+	if (IS_ERR(drvdata->gdsc))
+		return -EINVAL;
+
 	drvdata->pclk = clk_get(&pdev->dev, "iface_clk");
 	if (IS_ERR(drvdata->pclk))
 		return PTR_ERR(drvdata->pclk);
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 834c9b0..9b42f9b 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -136,6 +136,15 @@
 			image_mode = -1;
 			break;
 		}
+	} else if (vfe_msg == VFE_MSG_OUTPUT_TERTIARY1) {
+		switch (pmctl->vfe_output_mode) {
+		case VFE_OUTPUTS_RDI0:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+			break;
+		default:
+			image_mode = -1;
+			break;
+		}
 	} else
 		image_mode = -1;
 
@@ -331,6 +340,9 @@
 			case MSG_ID_OUTPUT_SECONDARY:
 				msgid = VFE_MSG_OUTPUT_SECONDARY;
 				break;
+			case MSG_ID_OUTPUT_TERTIARY1:
+				msgid = VFE_MSG_OUTPUT_TERTIARY1;
+				break;
 			default:
 				pr_err("%s: Invalid VFE output id: %d\n",
 					   __func__, isp_output->output_id);
@@ -673,6 +685,7 @@
 	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC:
 	case CMD_AXI_START:
 	case CMD_AXI_STOP:
+	case CMD_AXI_CFG_TERT1:
 		/* Dont need to pass buffer information.
 		 * subdev will get the buffer from media
 		 * controller free queue.
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 9382292..acff492 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -432,8 +432,15 @@
 	axi_ctrl->share_ctrl->outpath.out2.ch1 =
 		0x0000FFFF & (*ch_info++ >> 16);
 	axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+	axi_ctrl->share_ctrl->outpath.out2.image_mode =
+		0x0000FFFF & (*ch_info++ >> 16);
+
 
 	switch (mode) {
+	case OUTPUT_TERT1:
+		axi_ctrl->share_ctrl->outpath.output_mode =
+			VFE32_OUTPUT_MODE_TERTIARY1;
+		break;
 	case OUTPUT_PRIM:
 		axi_ctrl->share_ctrl->outpath.output_mode =
 			VFE32_OUTPUT_MODE_PRIMARY;
@@ -714,7 +721,7 @@
 
 static void vfe32_start_common(struct vfe32_ctrl_type *vfe32_ctrl)
 {
-	uint32_t irq_mask = 0x00E00021;
+	uint32_t irq_mask = 0x00E00021, irq_mask1;
 	vfe32_ctrl->start_ack_pending = TRUE;
 	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
 		vfe32_ctrl->share_ctrl->operation_mode,
@@ -723,19 +730,31 @@
 		irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
 	else
 		irq_mask |= 0x000FE000;
-
+	irq_mask |=
+		msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
 	msm_camera_io_w(irq_mask,
 		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
 	msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
 		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
 
+	if (vfe32_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_RDI0) {
+		irq_mask1 =
+		msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_1);
+		irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
+		msm_camera_io_w(irq_mask1, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_1);
+		msm_camera_io_w_mb(2, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_REG_UPDATE_CMD);
+	} else {
+		msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_REG_UPDATE_CMD);
+		msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_CAMIF_COMMAND);
+	}
 	/* Ensure the write order while writing
 	to the command register using the barrier */
-	msm_camera_io_w_mb(1,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camera_io_w_mb(1,
-		vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
-
 	atomic_set(&vfe32_ctrl->share_ctrl->vstate, 1);
 }
 
@@ -989,7 +1008,8 @@
 	struct msm_cam_media_controller *pmctl,
 	struct vfe32_ctrl_type *vfe32_ctrl)
 {
-	uint32_t irq_comp_mask = 0;
+	uint32_t irq_comp_mask = 0, irq_mask = 0;
+
 	irq_comp_mask	=
 		msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
 			VFE_IRQ_COMP_MASK);
@@ -1018,6 +1038,16 @@
 			0x1 << (vfe32_ctrl->share_ctrl->outpath.out1.ch1 + 8) |
 			0x1 << (vfe32_ctrl->share_ctrl->outpath.out1.ch2 + 8));
 	}
+	if (vfe32_ctrl->share_ctrl->outpath.output_mode &
+		VFE32_OUTPUT_MODE_TERTIARY1) {
+		irq_mask = msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+		irq_mask |= (0x1 << (vfe32_ctrl->share_ctrl->outpath.out2.ch0 +
+			VFE_WM_OFFSET));
+		msm_camera_io_w(irq_mask, vfe32_ctrl->share_ctrl->vfebase +
+			VFE_IRQ_MASK_0);
+	}
+
 	msm_camera_io_w(irq_comp_mask,
 		vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
@@ -1235,6 +1265,8 @@
 		ch = &share_ctrl->outpath.out0;
 	else if (path == VFE_MSG_OUTPUT_SECONDARY)
 		ch = &share_ctrl->outpath.out1;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		ch = &share_ctrl->outpath.out2;
 	else
 		pr_err("%s: Invalid path %d\n", __func__,
 			path);
@@ -1251,8 +1283,10 @@
 
 	if (path == VFE_MSG_OUTPUT_PRIMARY)
 		image_mode = axi_ctrl->share_ctrl->outpath.out0.image_mode;
-	else
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
 		image_mode = axi_ctrl->share_ctrl->outpath.out1.image_mode;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		image_mode = axi_ctrl->share_ctrl->outpath.out2.image_mode;
 
 	vfe32_subdev_notify(id, path, image_mode,
 		&axi_ctrl->subdev, axi_ctrl->share_ctrl);
@@ -1269,8 +1303,10 @@
 	uint32_t image_mode = 0;
 	if (path == VFE_MSG_OUTPUT_PRIMARY)
 		image_mode = vfe32_ctrl->share_ctrl->outpath.out0.image_mode;
-	else
+	else if (path == VFE_MSG_OUTPUT_SECONDARY)
 		image_mode = vfe32_ctrl->share_ctrl->outpath.out1.image_mode;
+	else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+		image_mode = vfe32_ctrl->share_ctrl->outpath.out2.image_mode;
 
 	vfe32_subdev_notify(id, path, image_mode,
 		&vfe32_ctrl->subdev, vfe32_ctrl->share_ctrl);
@@ -1286,8 +1322,9 @@
 			vfe32_ctrl->share_ctrl->vfebase, outch->ch0,
 			outch->pong.ch_paddr[0]);
 
-		if (vfe32_ctrl->share_ctrl->operation_mode !=
-			VFE_OUTPUTS_RAW) {
+		if ((vfe32_ctrl->share_ctrl->operation_mode !=
+			VFE_OUTPUTS_RAW) &&
+			(path != VFE_MSG_OUTPUT_TERTIARY1)) {
 			vfe32_put_ch_ping_addr(
 				vfe32_ctrl->share_ctrl->vfebase, outch->ch1,
 				outch->ping.ch_paddr[1]);
@@ -1377,6 +1414,11 @@
 			rc = vfe32_configure_pingpong_buffers(
 				VFE_MSG_V32_START, VFE_MSG_OUTPUT_PRIMARY,
 				vfe32_ctrl);
+		else if (vfe32_ctrl->share_ctrl->operation_mode ==
+				VFE_OUTPUTS_RDI0)
+			rc = vfe32_configure_pingpong_buffers(
+				VFE_MSG_V32_START, VFE_MSG_OUTPUT_TERTIARY1,
+				vfe32_ctrl);
 		else
 			/* Configure secondary channel */
 			rc = vfe32_configure_pingpong_buffers(
@@ -2844,11 +2886,14 @@
 		CDBG("stop video triggered .\n");
 	}
 
+	spin_lock_irqsave(&vfe32_ctrl->start_ack_lock, flags);
 	if (vfe32_ctrl->start_ack_pending == TRUE) {
+		vfe32_ctrl->start_ack_pending = FALSE;
+		spin_unlock_irqrestore(&vfe32_ctrl->start_ack_lock, flags);
 		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
 			vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_START_ACK);
-		vfe32_ctrl->start_ack_pending = FALSE;
 	} else {
+		spin_unlock_irqrestore(&vfe32_ctrl->start_ack_lock, flags);
 		if (vfe32_ctrl->recording_state ==
 				VFE_STATE_STOP_REQUESTED) {
 			vfe32_ctrl->recording_state = VFE_STATE_STOPPED;
@@ -2977,6 +3022,23 @@
 	} /* if snapshot mode. */
 }
 
+static void vfe32_process_rdi0_reg_update_irq(
+	struct vfe32_ctrl_type *vfe32_ctrl)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&vfe32_ctrl->start_ack_lock, flags);
+	if (vfe32_ctrl->start_ack_pending == TRUE) {
+		vfe32_ctrl->start_ack_pending = FALSE;
+		spin_unlock_irqrestore(
+				&vfe32_ctrl->start_ack_lock, flags);
+		vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+			vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_START_ACK);
+	} else {
+		spin_unlock_irqrestore(
+				&vfe32_ctrl->start_ack_lock, flags);
+	}
+}
+
 static void vfe32_set_default_reg_values(
 			struct vfe32_ctrl_type *vfe32_ctrl)
 {
@@ -3381,6 +3443,48 @@
 	}
 }
 
+static void vfe32_process_output_path_irq_rdi0(
+			struct axi_ctrl_t *axi_ctrl)
+{
+	uint32_t ping_pong;
+	uint32_t ch0_paddr = 0;
+	/* this must be rdi image output. */
+	struct msm_free_buf *free_buf = NULL;
+	/*RDI0*/
+	if (axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_RDI0) {
+		free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+			VFE_MSG_OUTPUT_TERTIARY1, axi_ctrl);
+		if (free_buf) {
+			ping_pong = msm_camera_io_r(axi_ctrl->
+				share_ctrl->vfebase +
+				VFE_BUS_PING_PONG_STATUS);
+
+			/* Y only channel */
+			ch0_paddr = vfe32_get_ch_addr(ping_pong,
+				axi_ctrl->share_ctrl->vfebase,
+				axi_ctrl->share_ctrl->outpath.out2.ch0);
+
+			pr_debug("%s ch0 = 0x%x\n",
+				__func__, ch0_paddr);
+
+			/* Y channel */
+			vfe32_put_ch_addr(ping_pong,
+				axi_ctrl->share_ctrl->vfebase,
+				axi_ctrl->share_ctrl->outpath.out2.ch0,
+				free_buf->ch_paddr[0]);
+
+			vfe_send_outmsg(axi_ctrl,
+				MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
+				0, 0,
+				axi_ctrl->share_ctrl->outpath.out2.image_mode);
+
+		} else {
+			axi_ctrl->share_ctrl->outpath.out2.frame_drop_cnt++;
+			pr_err("path_irq_2 irq - no free buffer for rdi0!\n");
+		}
+	}
+}
+
 static uint32_t  vfe32_process_stats_irq_common(
 	struct vfe32_ctrl_type *vfe32_ctrl,
 	uint32_t statsNum, uint32_t newAddr)
@@ -3756,6 +3860,10 @@
 		CDBG("irq	regUpdateIrq\n");
 		vfe32_process_reg_update_irq(vfe32_ctrl);
 		break;
+	case VFE_IRQ_STATUS1_RDI0_REG_UPDATE:
+		CDBG("irq	rdi0 regUpdateIrq\n");
+		vfe32_process_rdi0_reg_update_irq(vfe32_ctrl);
+		break;
 	case VFE_IMASK_WHILE_STOPPING_1:
 		CDBG("irq	resetAckIrq\n");
 		vfe32_process_reset_irq(vfe32_ctrl);
@@ -3845,6 +3953,12 @@
 				(void *)VFE_IRQ_STATUS0_REG_UPDATE_MASK);
 
 		if (qcmd->vfeInterruptStatus1 &
+				VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK)
+			v4l2_subdev_notify(&axi_ctrl->subdev,
+				NOTIFY_VFE_IRQ,
+				(void *)VFE_IRQ_STATUS1_RDI0_REG_UPDATE);
+
+		if (qcmd->vfeInterruptStatus1 &
 				VFE_IMASK_WHILE_STOPPING_1)
 			v4l2_subdev_notify(&axi_ctrl->subdev,
 				NOTIFY_VFE_IRQ,
@@ -4284,6 +4398,7 @@
 	spin_lock_init(&vfe32_ctrl->state_lock);
 	spin_lock_init(&vfe32_ctrl->io_lock);
 	spin_lock_init(&vfe32_ctrl->update_ack_lock);
+	spin_lock_init(&vfe32_ctrl->start_ack_lock);
 
 	spin_lock_init(&vfe32_ctrl->aec_ack_lock);
 	spin_lock_init(&vfe32_ctrl->awb_ack_lock);
@@ -4366,6 +4481,11 @@
 				share_ctrl->outpath.out0.ch2]);
 		}
 		break;
+	case VFE_OUTPUTS_RDI0:
+		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+			vfe32_AXI_WM_CFG[axi_ctrl->
+			share_ctrl->outpath.out2.ch0]);
+		break;
 	default:
 		if (axi_ctrl->share_ctrl->outpath.output_mode &
 			VFE32_OUTPUT_MODE_SECONDARY) {
@@ -4467,8 +4587,8 @@
 		}
 		vfe32_config_axi(axi_ctrl, OUTPUT_PRIM, axio);
 		kfree(axio);
-	}
 		break;
+		}
 	case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
 		uint32_t *axio = NULL;
 		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
@@ -4486,8 +4606,8 @@
 		}
 		vfe32_config_axi(axi_ctrl, OUTPUT_PRIM_ALL_CHNLS, axio);
 		kfree(axio);
-	}
 		break;
+		}
 	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
 		uint32_t *axio = NULL;
 		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
@@ -4505,8 +4625,8 @@
 		}
 		vfe32_config_axi(axi_ctrl, OUTPUT_PRIM|OUTPUT_SEC, axio);
 		kfree(axio);
-	}
 		break;
+		}
 	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
 		uint32_t *axio = NULL;
 		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
@@ -4525,8 +4645,8 @@
 		vfe32_config_axi(axi_ctrl,
 			OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
 		kfree(axio);
-	}
 		break;
+		}
 	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
 		uint32_t *axio = NULL;
 		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
@@ -4545,8 +4665,28 @@
 		vfe32_config_axi(axi_ctrl,
 			OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
 		kfree(axio);
-	}
 		break;
+		}
+	case CMD_AXI_CFG_TERT1: {
+		uint32_t *axio = NULL;
+		axio = kmalloc(vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe32_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe32_config_axi(axi_ctrl,
+			OUTPUT_TERT1, axio);
+		kfree(axio);
+		break;
+		}
 	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
 		pr_err("%s Invalid/Unsupported AXI configuration %x",
 			__func__, cfgcmd.cmd_type);
@@ -4585,6 +4725,13 @@
 		CDBG("Image composite done 1 irq occured.\n");
 		vfe32_process_output_path_irq_1(axi_ctrl);
 	}
+
+	if (axi_ctrl->share_ctrl->outpath.output_mode &
+		VFE32_OUTPUT_MODE_TERTIARY1)
+		if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0
+			+ VFE_WM_OFFSET)))
+			vfe32_process_output_path_irq_rdi0(axi_ctrl);
+
 	/* in snapshot mode if done then send
 	snapshot done message */
 	if (axi_ctrl->share_ctrl->operation_mode ==
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index d5da432..1746f3f 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -87,6 +87,9 @@
  * the luma samples.  JPEG 4:2:2 */
 #define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
 
+/* wm bit offset for IRQ MASK and IRQ STATUS register */
+#define VFE_WM_OFFSET 6
+
 /* constants for irq registers */
 #define VFE_DISABLE_ALL_IRQS 0
 /* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
@@ -115,6 +118,17 @@
 #define VFE_IRQ_STATUS0_ASYNC_TIMER2  0x40000000  /* bit 30 */
 #define VFE_IRQ_STATUS0_ASYNC_TIMER3  0x80000000  /* bit 32 */
 
+#define VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK  0x4000000 /*bit 26*/
+#define VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK  0x8000000 /*bit 27*/
+
+/*TODOs the irq status passed from axi to vfe irq handler does not account
+* for 2 irq status registers. So below macro is added to differentiate between
+* same bit set on both irq status registers. This wil be fixed later by passing
+*entire payload to vfe irq handler and parsing there instead of passing just the
+*status bit*/
+#define VFE_IRQ_STATUS1_RDI0_REG_UPDATE  0x84000000 /*bit 26*/
+#define VFE_IRQ_STATUS1_RDI1_REG_UPDATE  0x88000000 /*bit 27*/
+
 /* imask for while waiting for stop ack,  driver has already
  * requested stop, waiting for reset irq, and async timer irq.
  * For irq_status_0, bit 28-32 are for async timer. For
@@ -788,7 +802,7 @@
 
 	struct vfe32_output_ch out0; /* preview and thumbnail */
 	struct vfe32_output_ch out1; /* snapshot */
-	struct vfe32_output_ch out2; /* video    */
+	struct vfe32_output_ch out2; /* rdi0    */
 };
 
 struct vfe32_frame_extra {
@@ -893,6 +907,7 @@
 #define VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS	BIT(7)
 #define VFE32_OUTPUT_MODE_SECONDARY		BIT(8)
 #define VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS	BIT(9)
+#define VFE32_OUTPUT_MODE_TERTIARY1		BIT(10)
 
 struct vfe_stats_control {
 	uint8_t  ackPending;
@@ -946,6 +961,7 @@
 	uint32_t vfeImaskCompositePacked;
 
 	spinlock_t  update_ack_lock;
+	spinlock_t  start_ack_lock;
 	spinlock_t  state_lock;
 	spinlock_t  io_lock;
 
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index e60b24e..b232e0a 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -74,7 +74,8 @@
 
 struct mdp_buf_type {
 	struct ion_handle *ihdl;
-	u32 phys_addr;
+	u32 write_addr;
+	u32 read_addr;
 	u32 size;
 };
 
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 1557eed..59404d0 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -337,7 +337,8 @@
 	uint32 element1; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
 	uint32 element0; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
 	struct completion comp;
-	ulong blt_addr; /* blt mode addr */
+	ulong ov_blt_addr; /* blt mode addr */
+	ulong dma_blt_addr; /* blt mode addr */
 	ulong blt_base;
 	ulong blt_offset;
 	uint32 blt_cnt;
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index b3ec39e..287b564 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -346,7 +346,7 @@
 
 	MDP_OUTP(MDP_BASE + 0xb0004,
 			(pipe->src_height << 16 | pipe->src_width));
-	if (pipe->blt_addr) {
+	if (pipe->dma_blt_addr) {
 		uint32 off, bpp;
 #ifdef BLT_RGB565
 		bpp = 2; /* overlay ouput is RGB565 */
@@ -356,7 +356,7 @@
 		off = 0;
 		if (pipe->ov_cnt & 0x01)
 			off = pipe->src_height * pipe->src_width * bpp;
-		MDP_OUTP(MDP_BASE + 0xb0008, pipe->blt_addr + off);
+		MDP_OUTP(MDP_BASE + 0xb0008, pipe->dma_blt_addr + off);
 		/* RGB888, output of overlay blending */
 		MDP_OUTP(MDP_BASE + 0xb000c, pipe->src_width * bpp);
 	} else {
@@ -427,7 +427,7 @@
 	/* dma_p source */
 	MDP_OUTP(MDP_BASE + 0x90004,
 			(pipe->src_height << 16 | pipe->src_width));
-	if (pipe->blt_addr) {
+	if (pipe->dma_blt_addr) {
 #ifdef BLT_RGB565
 		bpp = 2; /* overlay ouput is RGB565 */
 #else
@@ -436,7 +436,7 @@
 		off = 0;
 		if (pipe->dmap_cnt & 0x01)
 			off = pipe->src_height * pipe->src_width * bpp;
-		MDP_OUTP(MDP_BASE + 0x90008, pipe->blt_addr + off);
+		MDP_OUTP(MDP_BASE + 0x90008, pipe->dma_blt_addr + off);
 		/* RGB888, output of overlay blending */
 		MDP_OUTP(MDP_BASE + 0x9000c, pipe->src_width * bpp);
 	} else {
@@ -1321,7 +1321,7 @@
 	/*
 	 * BLT support both primary and external external
 	 */
-	if (pipe->blt_addr) {
+	if (pipe->ov_blt_addr) {
 		int off, bpp;
 #ifdef BLT_RGB565
 		bpp = 2;  /* overlay ouput is RGB565 */
@@ -1338,10 +1338,10 @@
 			if (pipe->ov_cnt & 0x01)
 				off = pipe->src_height * pipe->src_width * bpp;
 
-			outpdw(overlay_base + 0x000c, pipe->blt_addr + off);
+			outpdw(overlay_base + 0x000c, pipe->ov_blt_addr + off);
 			/* overlay ouput is RGB888 */
 			outpdw(overlay_base + 0x0010, pipe->src_width * bpp);
-			outpdw(overlay_base + 0x001c, pipe->blt_addr + off);
+			outpdw(overlay_base + 0x001c, pipe->ov_blt_addr + off);
 			/* MDDI - BLT + on demand */
 			outpdw(overlay_base + 0x0004, 0x08);
 
@@ -1361,19 +1361,19 @@
 							pipe->src_width * bpp;
 
 				outpdw(overlay_base + 0x000c,
-						pipe->blt_addr + off);
+						pipe->ov_blt_addr + off);
 				/* overlay ouput is RGB888 */
 				outpdw(overlay_base + 0x0010,
 					((pipe->src_width << 16) |
 					 pipe->src_width));
 				outpdw(overlay_base + 0x001c,
-						pipe->blt_addr + off);
+						pipe->ov_blt_addr + off);
 				off = pipe->src_height * pipe->src_width;
 				/* align chroma to 2k address */
 				off = (off + 2047) & ~2047;
 				/* UV plane adress */
 				outpdw(overlay_base + 0x0020,
-						pipe->blt_addr + off);
+						pipe->ov_blt_addr + off);
 				/* MDDI - BLT + on demand */
 				outpdw(overlay_base + 0x0004, 0x08);
 				/* pseudo planar + writeback */
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 7ba4e75..0d8fea7 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -162,7 +162,8 @@
 		dsi_pipe = pipe; /* keep it */
 
 		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
-		pipe->blt_addr = 0;
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
 
 	} else {
 		pipe = dsi_pipe;
@@ -321,24 +322,25 @@
 {
 	unsigned long flag;
 
-	pr_debug("%s: blt_end=%d blt_addr=%x pid=%d\n",
-	__func__, dsi_pipe->blt_end, (int)dsi_pipe->blt_addr, current->pid);
+	pr_debug("%s: blt_end=%d ov_blt_addr=%x pid=%d\n",
+	__func__, dsi_pipe->blt_end, (int)dsi_pipe->ov_blt_addr, current->pid);
 
 	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
 
-	if (mfd->ov0_wb_buf->phys_addr == 0) {
+	if (mfd->ov0_wb_buf->write_addr == 0) {
 		pr_info("%s: no blt_base assigned\n", __func__);
 		return -EBUSY;
 	}
 
-	if (dsi_pipe->blt_addr == 0) {
+	if (dsi_pipe->ov_blt_addr == 0) {
 		mdp4_dsi_cmd_dma_busy_wait(mfd);
 		spin_lock_irqsave(&mdp_spin_lock, flag);
 		dsi_pipe->blt_end = 0;
 		dsi_pipe->blt_cnt = 0;
 		dsi_pipe->ov_cnt = 0;
 		dsi_pipe->dmap_cnt = 0;
-		dsi_pipe->blt_addr = mfd->ov0_wb_buf->phys_addr;
+		dsi_pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
+		dsi_pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr;
 		mdp4_stat.blt_dsi_cmd++;
 		spin_unlock_irqrestore(&mdp_spin_lock, flag);
 		return 0;
@@ -352,10 +354,10 @@
 	unsigned long flag;
 
 
-	pr_debug("%s: blt_end=%d blt_addr=%x\n",
-		 __func__, dsi_pipe->blt_end, (int)dsi_pipe->blt_addr);
+	pr_debug("%s: blt_end=%d ov_blt_addr=%x\n",
+		 __func__, dsi_pipe->blt_end, (int)dsi_pipe->ov_blt_addr);
 
-	if ((dsi_pipe->blt_end == 0) && dsi_pipe->blt_addr) {
+	if ((dsi_pipe->blt_end == 0) && dsi_pipe->ov_blt_addr) {
 		spin_lock_irqsave(&mdp_spin_lock, flag);
 		dsi_pipe->blt_end = 1;	/* mark as end */
 		spin_unlock_irqrestore(&mdp_spin_lock, flag);
@@ -393,7 +395,7 @@
 	char *overlay_base;
 
 
-	if (pipe->blt_addr == 0)
+	if (pipe->ov_blt_addr == 0)
 		return;
 
 
@@ -405,7 +407,7 @@
 	off = 0;
 	if (pipe->dmap_cnt & 0x01)
 		off = pipe->src_height * pipe->src_width * bpp;
-	addr = pipe->blt_addr + off;
+	addr = pipe->dma_blt_addr + off;
 
 	/* dmap */
 	MDP_OUTP(MDP_BASE + 0x90008, addr);
@@ -413,7 +415,7 @@
 	off = 0;
 	if (pipe->ov_cnt & 0x01)
 		off = pipe->src_height * pipe->src_width * bpp;
-	addr2 = pipe->blt_addr + off;
+	addr2 = pipe->ov_blt_addr + off;
 	/* overlay 0 */
 	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
 	outpdw(overlay_base + 0x000c, addr2);
@@ -441,7 +443,8 @@
 		spin_unlock(&mdp_spin_lock);
 		if (dsi_pipe->blt_end) {
 			dsi_pipe->blt_end = 0;
-			dsi_pipe->blt_addr = 0;
+			dsi_pipe->dma_blt_addr = 0;
+			dsi_pipe->ov_blt_addr = 0;
 			pr_debug("%s: END, ov_cnt=%d dmap_cnt=%d\n",
 				__func__, dsi_pipe->ov_cnt, dsi_pipe->dmap_cnt);
 			mdp_intr_mask &= ~INTR_DMA_P_DONE;
@@ -479,7 +482,7 @@
 {
 	int diff;
 
-	if (dsi_pipe->blt_addr == 0) {
+	if (dsi_pipe->ov_blt_addr == 0) {
 		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
 		spin_lock(&mdp_spin_lock);
 		dma->busy = FALSE;
@@ -539,7 +542,7 @@
 		mipi_dsi_mdp_busy_wait(dsi_mfd);
 		mdp4_overlay_update_dsi_cmd(dsi_mfd);
 
-		if (dsi_pipe->blt_addr)
+		if (dsi_pipe->ov_blt_addr)
 			mdp4_dsi_blt_dmap_busy_wait(dsi_mfd);
 		mdp4_dsi_cmd_overlay_kickoff(dsi_mfd, dsi_pipe);
 	}
@@ -622,17 +625,17 @@
 	 * to be called before kickoff.
 	 * vice versa for blt disabled.
 	 */
-	if (dsi_pipe->blt_addr && dsi_pipe->blt_cnt == 0)
+	if (dsi_pipe->ov_blt_addr && dsi_pipe->blt_cnt == 0)
 		mdp4_overlay_update_dsi_cmd(mfd); /* first time */
-	else if (dsi_pipe->blt_addr == 0  && dsi_pipe->blt_cnt) {
+	else if (dsi_pipe->ov_blt_addr == 0  && dsi_pipe->blt_cnt) {
 		mdp4_overlay_update_dsi_cmd(mfd); /* last time */
 		dsi_pipe->blt_cnt = 0;
 	}
 
-	pr_debug("%s: blt_addr=%d blt_cnt=%d\n",
-		__func__, (int)dsi_pipe->blt_addr, dsi_pipe->blt_cnt);
+	pr_debug("%s: ov_blt_addr=%d blt_cnt=%d\n",
+		__func__, (int)dsi_pipe->ov_blt_addr, dsi_pipe->blt_cnt);
 
-	if (dsi_pipe->blt_addr)
+	if (dsi_pipe->ov_blt_addr)
 		mdp4_dsi_blt_dmap_busy_wait(dsi_mfd);
 
 	mdp4_dsi_cmd_overlay_kickoff(mfd, pipe);
@@ -658,7 +661,7 @@
 
 	mipi_dsi_mdp_busy_wait(mfd);
 
-	if (dsi_pipe->blt_addr == 0)
+	if (dsi_pipe->ov_blt_addr == 0)
 		mipi_dsi_cmd_mdp_start();
 
 	mdp4_overlay_dsi_state_set(ST_DSI_PLAYING);
@@ -666,7 +669,7 @@
 	spin_lock_irqsave(&mdp_spin_lock, flag);
 	mdp_enable_irq(MDP_OVERLAY0_TERM);
 	mfd->dma->busy = TRUE;
-	if (dsi_pipe->blt_addr)
+	if (dsi_pipe->ov_blt_addr)
 		mfd->dma->dmap_busy = TRUE;
 	/* start OVERLAY pipe */
 	spin_unlock_irqrestore(&mdp_spin_lock, flag);
@@ -700,7 +703,7 @@
 	if (mfd && mfd->panel_power_on) {
 		mdp4_dsi_cmd_dma_busy_wait(mfd);
 
-		if (dsi_pipe && dsi_pipe->blt_addr)
+		if (dsi_pipe && dsi_pipe->ov_blt_addr)
 			mdp4_dsi_blt_dmap_busy_wait(mfd);
 
 		mdp4_overlay_update_dsi_cmd(mfd);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 05c6fe8..478a8ce 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -152,7 +152,8 @@
 		init_completion(&dsi_video_comp);
 
 		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
-		pipe->blt_addr = 0;
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
 
 	} else {
 		pipe = dsi_pipe;
@@ -415,7 +416,7 @@
 	char *overlay_base;
 
 
-	if (pipe->blt_addr == 0)
+	if (pipe->ov_blt_addr == 0)
 		return;
 
 
@@ -427,7 +428,7 @@
 	off = 0;
 	if (pipe->ov_cnt & 0x01)
 		off = pipe->src_height * pipe->src_width * bpp;
-	addr = pipe->blt_addr + off;
+	addr = pipe->ov_blt_addr + off;
 
 	/* overlay 0 */
 	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
@@ -440,7 +441,7 @@
 	uint32 off, addr;
 	int bpp;
 
-	if (pipe->blt_addr == 0)
+	if (pipe->ov_blt_addr == 0)
 		return;
 
 
@@ -452,7 +453,7 @@
 	off = 0;
 	if (pipe->dmap_cnt & 0x01)
 		off = pipe->src_height * pipe->src_width * bpp;
-	addr = pipe->blt_addr + off;
+	addr = pipe->dma_blt_addr + off;
 
 	/* dmap */
 	MDP_OUTP(MDP_BASE + 0x90008, addr);
@@ -529,7 +530,7 @@
 	if (pipe->flags & MDP_OV_PLAY_NOWAIT)
 		return;
 
-	if (dsi_pipe->blt_addr) {
+	if (dsi_pipe->ov_blt_addr) {
 		mdp4_overlay_dsi_video_dma_busy_wait(mfd);
 
 		mdp4_dsi_video_blt_ov_update(dsi_pipe);
@@ -572,7 +573,7 @@
 		mdp4_overlayproc_cfg(dsi_pipe);
 		mdp4_overlay_dmap_xy(dsi_pipe);
 		mdp_is_in_isr = FALSE;
-		if (dsi_pipe->blt_addr) {
+		if (dsi_pipe->ov_blt_addr) {
 			mdp4_dsi_video_blt_ov_update(dsi_pipe);
 			dsi_pipe->ov_cnt++;
 			outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
@@ -595,7 +596,7 @@
 {
 	spin_lock(&mdp_spin_lock);
 	dma->busy = FALSE;
-	if (dsi_pipe->blt_addr == 0) {
+	if (dsi_pipe->ov_blt_addr == 0) {
 		spin_unlock(&mdp_spin_lock);
 		return;
 	}
@@ -618,21 +619,23 @@
 
 	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
 
-	if (mfd->ov0_wb_buf->phys_addr == 0) {
+	if (mfd->ov0_wb_buf->write_addr == 0) {
 		pr_info("%s: no blt_base assigned\n", __func__);
 		return;
 	}
 
 	spin_lock_irqsave(&mdp_spin_lock, flag);
-	if (enable && dsi_pipe->blt_addr == 0) {
-		dsi_pipe->blt_addr = mfd->ov0_wb_buf->phys_addr;
+	if (enable && dsi_pipe->ov_blt_addr == 0) {
+		dsi_pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
+		dsi_pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr;
 		dsi_pipe->blt_cnt = 0;
 		dsi_pipe->ov_cnt = 0;
 		dsi_pipe->dmap_cnt = 0;
 		mdp4_stat.blt_dsi_video++;
 		change++;
-	} else if (enable == 0 && dsi_pipe->blt_addr) {
-		dsi_pipe->blt_addr = 0;
+	} else if (enable == 0 && dsi_pipe->ov_blt_addr) {
+		dsi_pipe->ov_blt_addr = 0;
+		dsi_pipe->dma_blt_addr = 0;
 		change++;
 	}
 
@@ -641,8 +644,8 @@
 		return;
 	}
 
-	pr_debug("%s: enable=%d blt_addr=%x\n", __func__,
-			enable, (int)dsi_pipe->blt_addr);
+	pr_debug("%s: enable=%d ov_blt_addr=%x\n", __func__,
+			enable, (int)dsi_pipe->ov_blt_addr);
 	blt_cfg_changed = 1;
 
 	spin_unlock_irqrestore(&mdp_spin_lock, flag);
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 9174bc5..e41f9e8 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -376,7 +376,8 @@
 		return -ENODEV;
 
 	mdp4_init_writeback_buf(mfd, MDP4_MIXER1);
-	dtv_pipe->blt_addr = 0;
+	dtv_pipe->ov_blt_addr = 0;
+	dtv_pipe->dma_blt_addr = 0;
 
 	return mdp4_dtv_start(mfd);
 }
@@ -407,7 +408,7 @@
 	int bpp;
 	char *overlay_base;
 
-	if (pipe->blt_addr == 0)
+	if (pipe->ov_blt_addr == 0)
 		return;
 #ifdef BLT_RGB565
 	bpp = 2; /* overlay ouput is RGB565 */
@@ -417,7 +418,7 @@
 	off = (pipe->ov_cnt & 0x01) ?
 		pipe->src_height * pipe->src_width * bpp : 0;
 
-	addr = pipe->blt_addr + off;
+	addr = pipe->ov_blt_addr + off;
 	pr_debug("%s overlay addr 0x%x\n", __func__, addr);
 	/* overlay 1 */
 	overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
@@ -430,7 +431,7 @@
 	uint32 off, addr;
 	int bpp;
 
-	if (pipe->blt_addr == 0)
+	if (pipe->ov_blt_addr == 0)
 		return;
 
 #ifdef BLT_RGB565
@@ -440,7 +441,7 @@
 #endif
 	off =  (pipe->dmae_cnt & 0x01) ?
 		pipe->src_height * pipe->src_width * bpp : 0;
-	addr = pipe->blt_addr + off;
+	addr = pipe->dma_blt_addr + off;
 	MDP_OUTP(MDP_BASE + 0xb0008, addr);
 }
 
@@ -463,7 +464,7 @@
 		return;
 	}
 
-	if (dtv_pipe->blt_addr) {
+	if (dtv_pipe->ov_blt_addr) {
 		mdp4_dtv_blt_ov_update(dtv_pipe);
 		dtv_pipe->ov_cnt++;
 		mdp4_overlay_dtv_ov_kick_start();
@@ -523,7 +524,7 @@
 			msecs_to_jiffies(VSYNC_PERIOD*2));
 	mdp_disable_irq(MDP_OVERLAY1_TERM);
 
-	if (dtv_pipe->blt_addr)
+	if (dtv_pipe->ov_blt_addr)
 		mdp4_overlay_dtv_wait4dmae(mfd);
 }
 
@@ -581,7 +582,7 @@
 {
 	if (!dtv_pipe)
 		return;
-	if (dtv_pipe->blt_addr) {
+	if (dtv_pipe->ov_blt_addr) {
 		mdp4_dtv_blt_dmae_update(dtv_pipe);
 		dtv_pipe->dmae_cnt++;
 	}
@@ -642,7 +643,7 @@
 	unsigned long flag;
 	int change = 0;
 
-	if (!mfd->ov1_wb_buf->phys_addr) {
+	if (!mfd->ov1_wb_buf->write_addr) {
 		pr_debug("%s: no writeback buf assigned\n", __func__);
 		return;
 	}
@@ -654,16 +655,18 @@
 	}
 
 	spin_lock_irqsave(&mdp_spin_lock, flag);
-	if (enable && dtv_pipe->blt_addr == 0) {
-		dtv_pipe->blt_addr = mfd->ov1_wb_buf->phys_addr;
+	if (enable && dtv_pipe->ov_blt_addr == 0) {
+		dtv_pipe->ov_blt_addr = mfd->ov1_wb_buf->write_addr;
+		dtv_pipe->dma_blt_addr = mfd->ov1_wb_buf->read_addr;
 		change++;
 		dtv_pipe->ov_cnt = 0;
 		dtv_pipe->dmae_cnt = 0;
-	} else if (enable == 0 && dtv_pipe->blt_addr) {
-		dtv_pipe->blt_addr = 0;
+	} else if (enable == 0 && dtv_pipe->ov_blt_addr) {
+		dtv_pipe->ov_blt_addr = 0;
+		dtv_pipe->dma_blt_addr = 0;
 		change++;
 	}
-	pr_debug("%s: blt_addr=%x\n", __func__, (int)dtv_pipe->blt_addr);
+	pr_debug("%s: ov_blt_addr=%x\n", __func__, (int)dtv_pipe->ov_blt_addr);
 	spin_unlock_irqrestore(&mdp_spin_lock, flag);
 
 	if (!change)
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index fd6d365..1c3bf3f 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -133,8 +133,8 @@
 		init_completion(&lcdc_comp);
 
 		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
-		pipe->blt_addr = 0;
-
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
 	} else {
 		pipe = lcdc_pipe;
 	}
@@ -322,7 +322,7 @@
 	char *overlay_base;
 
 
-	if (pipe->blt_addr == 0)
+	if (pipe->ov_blt_addr == 0)
 		return;
 
 
@@ -334,7 +334,7 @@
 	off = 0;
 	if (pipe->ov_cnt & 0x01)
 		off = pipe->src_height * pipe->src_width * bpp;
-	addr = pipe->blt_addr + off;
+	addr = pipe->ov_blt_addr + off;
 
 	/* overlay 0 */
 	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
@@ -347,7 +347,7 @@
 	uint32 off, addr;
 	int bpp;
 
-	if (pipe->blt_addr == 0)
+	if (pipe->ov_blt_addr == 0)
 		return;
 
 
@@ -359,7 +359,7 @@
 	off = 0;
 	if (pipe->dmap_cnt & 0x01)
 		off = pipe->src_height * pipe->src_width * bpp;
-	addr = pipe->blt_addr + off;
+	addr = pipe->dma_blt_addr + off;
 
 	/* dmap */
 	MDP_OUTP(MDP_BASE + 0x90008, addr);
@@ -436,7 +436,7 @@
 	if (pipe->flags & MDP_OV_PLAY_NOWAIT)
 		return;
 
-	if (lcdc_pipe->blt_addr) {
+	if (lcdc_pipe->ov_blt_addr) {
 		mdp4_overlay_lcdc_dma_busy_wait(mfd);
 
 		mdp4_lcdc_blt_ov_update(lcdc_pipe);
@@ -483,7 +483,7 @@
 {
 	spin_lock(&mdp_spin_lock);
 	dma->busy = FALSE;
-	if (lcdc_pipe->blt_addr == 0) {
+	if (lcdc_pipe->ov_blt_addr == 0) {
 		spin_unlock(&mdp_spin_lock);
 		return;
 	}
@@ -498,7 +498,7 @@
 {
 	unsigned long flag;
 
-	if (lcdc_pipe->blt_addr) {
+	if (lcdc_pipe->ov_blt_addr) {
 		mdp4_overlay_lcdc_dma_busy_wait(mfd);
 
 		mdp4_lcdc_blt_ov_update(lcdc_pipe);
@@ -528,24 +528,26 @@
 
 	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
 
-	if (!mfd->ov0_wb_buf->phys_addr) {
+	if (!mfd->ov0_wb_buf->write_addr) {
 		pr_debug("%s: no blt_base assigned\n", __func__);
 		return;
 	}
 
 	spin_lock_irqsave(&mdp_spin_lock, flag);
-	if (enable && lcdc_pipe->blt_addr == 0) {
-		lcdc_pipe->blt_addr = mfd->ov0_wb_buf->phys_addr;
+	if (enable && lcdc_pipe->ov_blt_addr == 0) {
+		lcdc_pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
+		lcdc_pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr;
 		change++;
 		lcdc_pipe->blt_cnt = 0;
 		lcdc_pipe->ov_cnt = 0;
 		lcdc_pipe->dmap_cnt = 0;
 		mdp4_stat.blt_lcdc++;
-	} else if (enable == 0 && lcdc_pipe->blt_addr) {
-		lcdc_pipe->blt_addr = 0;
+	} else if (enable == 0 && lcdc_pipe->ov_blt_addr) {
+		lcdc_pipe->ov_blt_addr = 0;
+		lcdc_pipe->dma_blt_addr = 0;
 		change++;
 	}
-	pr_info("%s: blt_addr=%x\n", __func__, (int)lcdc_pipe->blt_addr);
+	pr_info("%s: ov_blt_addr=%x\n", __func__, (int)lcdc_pipe->ov_blt_addr);
 	spin_unlock_irqrestore(&mdp_spin_lock, flag);
 
 	if (!change)
@@ -559,7 +561,7 @@
 
 	mdp4_overlayproc_cfg(lcdc_pipe);
 	mdp4_overlay_dmap_xy(lcdc_pipe);
-	if (lcdc_pipe->blt_addr) {
+	if (lcdc_pipe->ov_blt_addr) {
 		mdp4_overlay_lcdc_prefill(mfd);
 		mdp4_overlay_lcdc_prefill(mfd);
 	}
diff --git a/drivers/video/msm/mdp4_overlay_mddi.c b/drivers/video/msm/mdp4_overlay_mddi.c
index 82864918..c4e6793 100644
--- a/drivers/video/msm/mdp4_overlay_mddi.c
+++ b/drivers/video/msm/mdp4_overlay_mddi.c
@@ -163,7 +163,8 @@
 
 		MDP_OUTP(MDP_BASE + 0x00098, 0x01);
 		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
-		pipe->blt_addr = 0;
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
 	} else {
 		pipe = mddi_pipe;
 	}
@@ -254,23 +255,25 @@
 	unsigned long flag;
 
 	pr_debug("%s: blt_end=%d blt_addr=%x pid=%d\n",
-	__func__, mddi_pipe->blt_end, (int)mddi_pipe->blt_addr, current->pid);
+		__func__, mddi_pipe->blt_end,
+		(int)mddi_pipe->ov_blt_addr, current->pid);
 
 	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
 
-	if (mfd->ov0_wb_buf->phys_addr == 0) {
+	if (mfd->ov0_wb_buf->write_addr == 0) {
 		pr_info("%s: no blt_base assigned\n", __func__);
 		return -EBUSY;
 	}
 
-	if (mddi_pipe->blt_addr == 0) {
+	if (mddi_pipe->ov_blt_addr == 0) {
 		mdp4_mddi_dma_busy_wait(mfd);
 		spin_lock_irqsave(&mdp_spin_lock, flag);
 		mddi_pipe->blt_end = 0;
 		mddi_pipe->blt_cnt = 0;
 		mddi_pipe->ov_cnt = 0;
 		mddi_pipe->dmap_cnt = 0;
-		mddi_pipe->blt_addr = mfd->ov0_wb_buf->phys_addr;
+		mddi_pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
+		mddi_pipe->dma_blt_addr = mfd->ov0_wb_buf->write_addr;
 		mdp4_stat.blt_mddi++;
 		spin_unlock_irqrestore(&mdp_spin_lock, flag);
 	return 0;
@@ -284,9 +287,9 @@
 	unsigned long flag;
 
 	pr_debug("%s: blt_end=%d blt_addr=%x\n",
-		 __func__, mddi_pipe->blt_end, (int)mddi_pipe->blt_addr);
+		 __func__, mddi_pipe->blt_end, (int)mddi_pipe->ov_blt_addr);
 
-	if ((mddi_pipe->blt_end == 0) && mddi_pipe->blt_addr) {
+	if ((mddi_pipe->blt_end == 0) && mddi_pipe->ov_blt_addr) {
 		spin_lock_irqsave(&mdp_spin_lock, flag);
 		mddi_pipe->blt_end = 1;	/* mark as end */
 		spin_unlock_irqrestore(&mdp_spin_lock, flag);
@@ -323,7 +326,7 @@
 	int bpp;
 	char *overlay_base;
 
-	if (pipe->blt_addr == 0)
+	if (pipe->ov_blt_addr == 0)
 		return;
 
 
@@ -336,7 +339,7 @@
 	if (pipe->dmap_cnt & 0x01)
 		off = pipe->src_height * pipe->src_width * bpp;
 
-	addr = pipe->blt_addr + off;
+	addr = pipe->ov_blt_addr + off;
 
 	/* dmap */
 	MDP_OUTP(MDP_BASE + 0x90008, addr);
@@ -344,7 +347,7 @@
 	off = 0;
 	if (pipe->ov_cnt & 0x01)
 		off = pipe->src_height * pipe->src_width * bpp;
-	addr2 = pipe->blt_addr + off;
+	addr2 = pipe->ov_blt_addr + off;
 	/* overlay 0 */
 	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
 	outpdw(overlay_base + 0x000c, addr2);
@@ -371,7 +374,8 @@
 
 		if (mddi_pipe->blt_end) {
 			mddi_pipe->blt_end = 0;
-			mddi_pipe->blt_addr = 0;
+			mddi_pipe->ov_blt_addr = 0;
+			mddi_pipe->dma_blt_addr = 0;
 			pr_debug("%s: END, ov_cnt=%d dmap_cnt=%d\n", __func__,
 				mddi_pipe->ov_cnt, mddi_pipe->dmap_cnt);
 			mdp_intr_mask &= ~INTR_DMA_P_DONE;
@@ -406,7 +410,7 @@
 {
 	int diff;
 
-	if (mddi_pipe->blt_addr == 0) {
+	if (mddi_pipe->ov_blt_addr == 0) {
 		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
 		spin_lock(&mdp_spin_lock);
 		dma->busy = FALSE;
@@ -473,7 +477,7 @@
 		mdp4_mddi_dma_busy_wait(mddi_mfd);
 		mdp4_overlay_update_lcd(mddi_mfd);
 
-		if (mddi_pipe->blt_addr)
+		if (mddi_pipe->ov_blt_addr)
 			mdp4_mddi_blt_dmap_busy_wait(mddi_mfd);
 		mdp4_mddi_overlay_kickoff(mddi_mfd, mddi_pipe);
 		mddi_mfd->dma_update_flag = 1;
@@ -539,17 +543,17 @@
 	 * to be called before kickoff.
 	 * vice versa for blt disabled.
 	 */
-	if (mddi_pipe->blt_addr && mddi_pipe->blt_cnt == 0)
+	if (mddi_pipe->ov_blt_addr && mddi_pipe->blt_cnt == 0)
 		mdp4_overlay_update_lcd(mfd); /* first time */
-	else if (mddi_pipe->blt_addr == 0  && mddi_pipe->blt_cnt) {
+	else if (mddi_pipe->ov_blt_addr == 0  && mddi_pipe->blt_cnt) {
 		mdp4_overlay_update_lcd(mfd); /* last time */
 		mddi_pipe->blt_cnt = 0;
 	}
 
 	pr_debug("%s: blt_addr=%d blt_cnt=%d\n",
-		__func__, (int)mddi_pipe->blt_addr, mddi_pipe->blt_cnt);
+		__func__, (int)mddi_pipe->ov_blt_addr, mddi_pipe->blt_cnt);
 
-	if (mddi_pipe->blt_addr)
+	if (mddi_pipe->ov_blt_addr)
 		mdp4_mddi_blt_dmap_busy_wait(mddi_mfd);
 	mdp4_mddi_overlay_kickoff(mfd, pipe);
 }
@@ -572,7 +576,7 @@
 	mdp_enable_irq(MDP_OVERLAY0_TERM);
 	spin_lock_irqsave(&mdp_spin_lock, flag);
 	mfd->dma->busy = TRUE;
-	if (mddi_pipe->blt_addr)
+	if (mddi_pipe->ov_blt_addr)
 		mfd->dma->dmap_busy = TRUE;
 	spin_unlock_irqrestore(&mdp_spin_lock, flag);
 	/* start OVERLAY pipe */
@@ -657,7 +661,7 @@
 
 	mdp_enable_irq(MDP_DMA_S_TERM);
 
-	if (mddi_pipe->blt_addr == 0)
+	if (mddi_pipe->ov_blt_addr == 0)
 		mfd->dma->busy = TRUE;
 
 	mfd->ibuf_flushed = TRUE;
@@ -688,7 +692,7 @@
 	if (mfd && mfd->panel_power_on) {
 		mdp4_mddi_dma_busy_wait(mfd);
 
-		if (mddi_pipe && mddi_pipe->blt_addr)
+		if (mddi_pipe && mddi_pipe->ov_blt_addr)
 			mdp4_mddi_blt_dmap_busy_wait(mfd);
 
 		mdp4_overlay_update_lcd(mfd);
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index f1a2ada..0174309 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -272,11 +272,11 @@
 	}
 	mutex_unlock(&mfd->writeback_mutex);
 
-	writeback_pipe->blt_addr = (ulong) (node ? node->addr : NULL);
+	writeback_pipe->ov_blt_addr = (ulong) (node ? node->addr : NULL);
 
-	if (!writeback_pipe->blt_addr) {
+	if (!writeback_pipe->ov_blt_addr) {
 		pr_err("%s: no writeback buffer 0x%x, %p\n", __func__,
-				(unsigned int)writeback_pipe->blt_addr, node);
+			(unsigned int)writeback_pipe->ov_blt_addr, node);
 		mutex_unlock(&mfd->unregister_mutex);
 		return;
 	}
@@ -324,13 +324,13 @@
 	}
 	mutex_unlock(&mfd->writeback_mutex);
 
-	writeback_pipe->blt_addr = (ulong) (node ? node->addr : NULL);
+	writeback_pipe->ov_blt_addr = (ulong) (node ? node->addr : NULL);
 
 	mutex_lock(&mfd->dma->ov_mutex);
 	pr_debug("%s in writeback\n", __func__);
-	if (writeback_pipe && !writeback_pipe->blt_addr) {
+	if (writeback_pipe && !writeback_pipe->ov_blt_addr) {
 		pr_err("%s: no writeback buffer 0x%x\n", __func__,
-				(unsigned int)writeback_pipe->blt_addr);
+				(unsigned int)writeback_pipe->ov_blt_addr);
 		ret = mdp4_overlay_writeback_update(mfd);
 		if (ret)
 			pr_err("%s: update failed writeback pipe NULL\n",
@@ -351,7 +351,7 @@
 		}
 
 		pr_debug("%s: in writeback pan display 0x%x\n", __func__,
-				(unsigned int)writeback_pipe->blt_addr);
+				(unsigned int)writeback_pipe->ov_blt_addr);
 		mdp4_writeback_kickoff_ui(mfd, writeback_pipe);
 		mdp4_iommu_unmap(writeback_pipe);
 
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index cce8ea4..208e3ce 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -2559,13 +2559,14 @@
 		buf = mfd->ov1_wb_buf;
 
 	buf->ihdl = NULL;
-	buf->phys_addr = 0;
+	buf->write_addr = 0;
+	buf->read_addr = 0;
 }
 
 u32 mdp4_allocate_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num)
 {
 	struct mdp_buf_type *buf;
-	ion_phys_addr_t	addr;
+	ion_phys_addr_t	addr, read_addr = 0;
 	size_t buffer_size;
 	unsigned long len;
 
@@ -2574,7 +2575,7 @@
 	else
 		buf = mfd->ov1_wb_buf;
 
-	if (buf->phys_addr || !IS_ERR_OR_NULL(buf->ihdl))
+	if (buf->write_addr || !IS_ERR_OR_NULL(buf->ihdl))
 		return 0;
 
 	if (!buf->size) {
@@ -2602,10 +2603,16 @@
 				if (ion_map_iommu(mfd->iclient, buf->ihdl,
 					DISPLAY_WRITE_DOMAIN, GEN_POOL, SZ_4K,
 					0, &addr, &len, 0, 0)) {
-					pr_err("ion_map_iommu() failed\n");
+					pr_err("ion_map_iommu() write failed\n");
 					return -ENOMEM;
 				}
 			}
+			if (ion_map_iommu(mfd->iclient, buf->ihdl,
+				DISPLAY_READ_DOMAIN, GEN_POOL, SZ_4K,
+				0, &read_addr, &len, 0, 0)) {
+				pr_err("ion_map_iommu() read failed\n");
+				return -ENOMEM;
+			}
 		} else {
 			pr_err("%s:%d: ion_alloc failed\n", __func__,
 				__LINE__);
@@ -2618,7 +2625,13 @@
 	if (addr) {
 		pr_info("allocating %d bytes at %x for mdp writeback\n",
 			buffer_size, (u32) addr);
-		buf->phys_addr = addr;
+		buf->write_addr = addr;
+
+		if (read_addr)
+			buf->read_addr = read_addr;
+		else
+			buf->read_addr = buf->write_addr;
+
 		return 0;
 	} else {
 		pr_err("%s cannot allocate memory for mdp writeback!\n",
@@ -2641,19 +2654,22 @@
 			if (!(mfd->mem_hid & ION_SECURE))
 				ion_unmap_iommu(mfd->iclient, buf->ihdl,
 					DISPLAY_WRITE_DOMAIN, GEN_POOL);
+			ion_unmap_iommu(mfd->iclient, buf->ihdl,
+				DISPLAY_READ_DOMAIN, GEN_POOL);
 			ion_free(mfd->iclient, buf->ihdl);
 			pr_debug("%s:%d free writeback imem\n", __func__,
 				__LINE__);
 			buf->ihdl = NULL;
 		}
 	} else {
-		if (buf->phys_addr) {
-			free_contiguous_memory_by_paddr(buf->phys_addr);
+		if (buf->write_addr) {
+			free_contiguous_memory_by_paddr(buf->write_addr);
 			pr_debug("%s:%d free writeback pmem\n", __func__,
 				__LINE__);
 		}
 	}
-	buf->phys_addr = 0;
+	buf->write_addr = 0;
+	buf->read_addr = 0;
 }
 
 static int mdp4_update_pcc_regs(uint32_t offset,
diff --git a/include/linux/msm_rotator.h b/include/linux/msm_rotator.h
index 0f15a8b..6cfbb35 100644
--- a/include/linux/msm_rotator.h
+++ b/include/linux/msm_rotator.h
@@ -31,6 +31,7 @@
 	unsigned char   rotations;
 	int enable;
 	unsigned int	downscale_ratio;
+	unsigned int secure;
 };
 
 struct msm_rotator_data_info {
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 320ac8b..3308243 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -446,10 +446,12 @@
 #define CMD_VFE_BUFFER_RELEASE 51
 #define CMD_VFE_PROCESS_IRQ 52
 
-#define CMD_AXI_CFG_PRIM		0xF1
-#define CMD_AXI_CFG_PRIM_ALL_CHNLS	0xF2
-#define CMD_AXI_CFG_SEC			0xF4
-#define CMD_AXI_CFG_SEC_ALL_CHNLS	0xF8
+#define CMD_AXI_CFG_PRIM		0xc1
+#define CMD_AXI_CFG_PRIM_ALL_CHNLS	0xc2
+#define CMD_AXI_CFG_SEC			0xc4
+#define CMD_AXI_CFG_SEC_ALL_CHNLS	0xc8
+#define CMD_AXI_CFG_TERT1		0xd0
+
 
 #define CMD_AXI_START  0xE1
 #define CMD_AXI_STOP   0xE2
@@ -549,10 +551,11 @@
 #define OUTPUT_ZSL_ALL_CHNLS 10
 #define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_ZSL_ALL_CHNLS
 
-#define OUTPUT_PRIM		0xF1
-#define OUTPUT_PRIM_ALL_CHNLS	0xF2
-#define OUTPUT_SEC		0xF4
-#define OUTPUT_SEC_ALL_CHNLS	0xF8
+#define OUTPUT_PRIM		0xC1
+#define OUTPUT_PRIM_ALL_CHNLS	0xC2
+#define OUTPUT_SEC		0xC4
+#define OUTPUT_SEC_ALL_CHNLS	0xC8
+#define OUTPUT_TERT1		0xD0
 
 
 #define MSM_FRAME_PREV_1	0
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 333d0df..93f6c8b 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -59,6 +59,8 @@
 #define MSG_ID_OUTPUT_PRIMARY           40
 #define MSG_ID_OUTPUT_SECONDARY         41
 #define MSG_ID_STATS_COMPOSITE          42
+#define MSG_ID_OUTPUT_TERTIARY1         43
+
 
 /* ISP command IDs */
 #define VFE_CMD_DUMMY_0                                 0
@@ -326,6 +328,9 @@
 #define VFE_OUTPUTS_RAW			BIT(8)
 #define VFE_OUTPUTS_JPEG_AND_THUMB	BIT(9)
 #define VFE_OUTPUTS_THUMB_AND_JPEG	BIT(10)
+#define VFE_OUTPUTS_RDI0	BIT(11)
+
+
 
 struct msm_frame_info {
 	uint32_t image_mode;