Merge "msm: vidc: Adds support for VC-1 MP and SP support"
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index 3ee63c0..717dd8c 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -11,11 +11,10 @@
 KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
 KERNEL_IMG=$(KERNEL_OUT)/arch/arm/boot/Image
 
-MSM_ARCH ?= $(shell $(PERL) -e 'while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/; $$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/;} print lc("$$a$$r\n");' $(KERNEL_CONFIG))
+DTS_NAMES ?= $(shell $(PERL) -e 'while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/; $$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/; $$arch = $$arch.lc("$$a$$r ") if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/} print $$arch;' $(KERNEL_CONFIG))
 KERNEL_USE_OF ?= $(shell $(PERL) -e '$$of = "n"; while (<>) { if (/CONFIG_USE_OF=y/) { $$of = "y"; break; } } print $$of;' kernel/arch/arm/configs/$(KERNEL_DEFCONFIG))
 
 ifeq "$(KERNEL_USE_OF)" "y"
-DTS_NAME ?= $(MSM_ARCH)
 DTS_FILES = $(wildcard $(TOP)/kernel/arch/arm/boot/dts/$(DTS_NAME)*.dts)
 DTS_FILE = $(lastword $(subst /, ,$(1)))
 DTB_FILE = $(addprefix $(KERNEL_OUT)/arch/arm/boot/,$(patsubst %.dts,%.dtb,$(call DTS_FILE,$(1))))
@@ -25,9 +24,10 @@
 
 define append-dtb
 mkdir -p $(KERNEL_OUT)/arch/arm/boot;\
-$(foreach d, $(DTS_FILES), \
-   $(DTC) -p 1024 -O dtb -o $(call DTB_FILE,$(d)) $(d); \
-   cat $(KERNEL_ZIMG) $(call DTB_FILE,$(d)) > $(call ZIMG_FILE,$(d));)
+$(foreach DTS_NAME, $(DTS_NAMES), \
+   $(foreach d, $(DTS_FILES), \
+      $(DTC) -p 1024 -O dtb -o $(call DTB_FILE,$(d)) $(d); \
+      cat $(KERNEL_ZIMG) $(call DTB_FILE,$(d)) > $(call ZIMG_FILE,$(d));))
 endef
 else
 
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 1fd96f9..de9e98c 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -58,6 +58,15 @@
 			status = "okay";
 			compatible = "qcom,rpm-regulator-smd";
 		};
+		pm8841_s1_so: regulator-s1-so {
+			regulator-name = "8841_s1_so";
+			qcom,set = <2>;
+			regulator-min-microvolt = <675000>;
+			regulator-max-microvolt = <1050000>;
+			qcom,init-voltage = <675000>;
+			status = "okay";
+			compatible = "qcom,rpm-regulator-smd";
+		};
 	};
 
 	rpm-regulator-smpb2 {
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 3a82b07..7c9f652 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2822,19 +2822,24 @@
 		msm_kgsl_3d0.dev.platform_data;
 	uint32_t soc_platform_version = socinfo_get_version();
 
+	/* Fixup data that needs to change based on GPU ID */
 	if (cpu_is_msm8960ab()) {
 		kgsl_3d0_pdata->chipid = ADRENO_CHIPID(3, 2, 1, 0);
 		/* 8960PRO nominal clock rate is 325Mhz instead of 320Mhz */
 		kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 325000000;
-	} else if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
-		kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
-		kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
-	} else if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
-		/* 8960v3 GPU registers returns 5 for patch release
-		 * but it should be 6, so dummy up the chipid here
-		 * based the platform type
-		 */
-		kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+	} else {
+		kgsl_3d0_pdata->iommu_count = 1;
+		if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
+			kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
+			kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
+		}
+		if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
+			/* 8960v3 GPU registers returns 5 for patch release
+			 * but it should be 6, so dummy up the chipid here
+			 * based the platform type
+			 */
+			kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+		}
 	}
 
 	/* Register the 3D core */
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index d22690c..33782ab 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3145,18 +3145,29 @@
 	},
 };
 
-static const struct kgsl_iommu_ctx kgsl_3d0_iommu_ctxs[] = {
+static const struct kgsl_iommu_ctx kgsl_3d0_iommu0_ctxs[] = {
 	{ "gfx3d_user", 0 },
 	{ "gfx3d_priv", 1 },
 };
 
+static const struct kgsl_iommu_ctx kgsl_3d0_iommu1_ctxs[] = {
+	{ "gfx3d1_user", 0 },
+	{ "gfx3d1_priv", 1 },
+};
+
 static struct kgsl_device_iommu_data kgsl_3d0_iommu_data[] = {
 	{
-		.iommu_ctxs = kgsl_3d0_iommu_ctxs,
-		.iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu_ctxs),
+		.iommu_ctxs = kgsl_3d0_iommu0_ctxs,
+		.iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu0_ctxs),
 		.physstart = 0x07C00000,
 		.physend = 0x07C00000 + SZ_1M - 1,
 	},
+	{
+		.iommu_ctxs = kgsl_3d0_iommu1_ctxs,
+		.iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu1_ctxs),
+		.physstart = 0x07D00000,
+		.physend = 0x07D00000 + SZ_1M - 1,
+	},
 };
 
 static struct kgsl_device_platform_data kgsl_3d0_pdata = {
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 5430f99..e0fec65 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -497,7 +497,7 @@
 
 void __init msm_map_mpq8092_io(void)
 {
-	msm_shared_ram_phys = MSM8974_MSM_SHARED_RAM_PHYS;
+	msm_shared_ram_phys = MSM8092_MSM_SHARED_RAM_PHYS;
 	msm_map_io(mpq8092_io_desc, ARRAY_SIZE(mpq8092_io_desc));
 }
 #endif /* CONFIG_ARCH_MPQ8092 */
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 25723d5..53736ac 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -26,6 +26,7 @@
 #include <linux/mfd/pm8xxx/misc.h>
 
 #include <asm/mach-types.h>
+#include <asm/cacheflush.h>
 
 #include <mach/msm_iomap.h>
 #include <mach/restart.h>
@@ -221,6 +222,8 @@
 			__raw_writel(0x77665501, restart_reason);
 		}
 	}
+
+	flush_cache_all();
 }
 
 void msm_restart(char mode, const char *cmd)
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index 9bc0da5..c0690c8 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -218,8 +218,10 @@
 	spin_lock_irqsave(&obj->active_list_lock, flags);
 
 	err = _sync_pt_has_signaled(pt);
-	if (err != 0)
+	if (err != 0) {
+		sync_fence_signal_pt(pt);
 		goto out;
+	}
 
 	list_add_tail(&pt->active_list, &obj->active_list_head);
 
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 03fdc5a..c799c1f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -556,7 +556,6 @@
 	  PMICs through RPC.
 
 config GPIO_QPNP_PIN
-	depends on ARCH_MSM8974
 	depends on SPMI
 	depends on OF_SPMI
 	depends on MSM_QPNP_INT
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 98254b5..7f760ed 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1391,8 +1391,10 @@
 				   sizeof(struct ion_fd_data)))
 			return -EFAULT;
 		data.handle = ion_import_dma_buf(client, data.fd);
-		if (IS_ERR(data.handle))
+		if (IS_ERR(data.handle)) {
+			ret = PTR_ERR(data.handle);
 			data.handle = NULL;
+		}
 		if (copy_to_user((void __user *)arg, &data,
 				 sizeof(struct ion_fd_data)))
 			return -EFAULT;
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
index 68653ba..3dc31bb 100644
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
@@ -55,6 +55,8 @@
 
 static int mpq_int_vid_dec_decode_frame(struct video_client_ctx *client_ctx,
 				struct video_data_buffer *input_frame);
+static int mpq_int_vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
+				  struct video_buffer_req *vdec_buf_req);
 
 static struct mpq_dvb_video_dev *mpq_dvb_video_device;
 
@@ -819,11 +821,32 @@
 		return 0;
 }
 
+static int mpq_int_set_out_buffer_req(struct video_client_ctx *client_ctx,
+					struct video_buffer_req *vdec_buf_req)
+{
+	struct vcd_buffer_requirement buffer_req;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	buffer_req.actual_count = vdec_buf_req->num_output_buffers;
+	buffer_req.align = vdec_buf_req->output_buf_prop.alignment;
+	buffer_req.max_count = vdec_buf_req->num_output_buffers;
+	buffer_req.min_count = vdec_buf_req->num_output_buffers;
+	buffer_req.sz = vdec_buf_req->output_buf_prop.buf_size;
+
+	vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
+			VCD_BUFFER_OUTPUT, &buffer_req);
+	if (vcd_status)
+		return -EFAULT;
+	else
+		return 0;
+}
+
 static int mpq_int_set_full_hd_frame_resolution(
 				struct video_client_ctx *client_ctx)
 {
 	struct vdec_picsize pic_res;
 	int rc;
+	struct video_buffer_req vdec_buf_req;
 
 	pic_res.frame_height = 1080;
 	pic_res.frame_width  = 1920;
@@ -841,6 +864,15 @@
 		DBG("Failed in mpq_int_vid_dec_set_cont_on_reconfig : %d\n",\
 			rc);
 
+	rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_buf_req);
+	if (rc)
+		DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
+
+	vdec_buf_req.num_output_buffers = 15;
+	rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_buf_req);
+	if (rc)
+		DBG("Failed in mpq_int_set_out_buffer_req (15) : %d\n", rc);
+
 	return rc;
 
 }
diff --git a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
index 9549dcc..d508c1d 100644
--- a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
+++ b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
@@ -139,11 +139,11 @@
 	switch (perf_setting) {
 	case S_INIT:
 		add_axi_qos();
-		break;
-	case S_PREVIEW:
 		update_axi_qos(MSM_AXI_QOS_PREVIEW);
 		axi_allocate(AXI_FLOW_VIEWFINDER_HI);
 		break;
+	case S_PREVIEW:
+		break;
 	case S_VIDEO:
 		update_axi_qos(MSM_AXI_QOS_RECORDING);
 		break;
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 2613986..1e17c5c 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -555,6 +555,7 @@
 	case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC:
 	case CMD_AXI_START:
 	case CMD_AXI_STOP:
+	case CMD_AXI_RESET:
 	case CMD_AXI_CFG_TERT1:
 	case CMD_AXI_CFG_TERT2:
 		/* Dont need to pass buffer information.
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index eb6a8b0..f6cf427 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -23,6 +23,8 @@
 
 static struct msm_camera_i2c_reg_conf ov5647_start_settings[] = {
 	{0x4202, 0x00},  /* streaming on */
+	{0x0100, 0x01},
+	{0x4800, 0x04},
 };
 
 static struct msm_camera_i2c_reg_conf ov5647_stop_settings[] = {
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index bb9a9b7..b78e20d 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -1643,6 +1643,10 @@
 
 		rp = (struct msm_vfe_resp *)arg;
 		frame_info = rp->evt_msg.data;
+		if (!frame_info) {
+			interface = PIX_0;
+			break;
+		}
 		if (frame_info->inst_handle) {
 			vnode_id = GET_DEVID_MODE(frame_info->inst_handle);
 			if (vnode_id < MAX_NUM_ACTIVE_CAMERA &&
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
index 15c38af..9deae65 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
@@ -1561,6 +1561,11 @@
 	}
 		return 0;
 
+	case CMD_AXI_START:
+	case CMD_AXI_STOP:
+	case CMD_AXI_RESET:
+		return 0;
+
 	case CMD_CONFIG_FREE_BUF_ADDR: {
 		int path = *((int *)cmd->value);
 		struct buf_info *outch = vfe2x_get_ch(path);
@@ -1853,9 +1858,6 @@
 						flags);
 				if (op_mode & SNAPSHOT_MASK_MODE) {
 					vfe2x_ctrl->stop_pending = 0;
-					vfe2x_send_isp_msg(vfe2x_ctrl,
-						msgs_map[MSG_STOP_ACK].
-						isp_id);
 					spin_unlock_irqrestore(
 							&vfe2x_ctrl->table_lock,
 							flags);
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index 8724138..c32978e 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -21,7 +21,6 @@
 
 config MSM_QPNP_INT
 	depends on SPARSE_IRQ
-	depends on ARCH_MSM8974
 	depends on SPMI
 	depends on OF_SPMI
 	bool "MSM QPNP INT"
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 5432df0..06d8769 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1137,6 +1137,31 @@
 	return 0;
 }
 
+static int mdss_fb_handle_pp_ioctl(void __user *argp)
+{
+	int ret;
+	struct msmfb_mdp_pp mdp_pp;
+	u32 copyback = 0;
+
+	ret = copy_from_user(&mdp_pp, argp, sizeof(mdp_pp));
+	if (ret)
+		return ret;
+
+	switch (mdp_pp.op) {
+	case mdp_op_pa_cfg:
+		ret = mdss_mdp_pa_config(&mdp_pp.data.pa_cfg_data,
+				&copyback);
+		break;
+	default:
+		pr_err("Unsupported request to MDP_PP IOCTL.\n");
+		ret = -EINVAL;
+		break;
+	}
+	if ((ret == 0) && copyback)
+		ret = copy_to_user(argp, &mdp_pp, sizeof(struct msmfb_mdp_pp));
+	return ret;
+}
+
 static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			 unsigned long arg)
 {
@@ -1163,6 +1188,10 @@
 			return ret;
 		break;
 
+	case MSMFB_MDP_PP:
+		ret = mdss_fb_handle_pp_ioctl(argp);
+		break;
+
 	default:
 		if (mfd->ioctl_handler)
 			ret = mfd->ioctl_handler(mfd, cmd, argp);
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 80e056f..3fb70bd 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -846,10 +846,17 @@
 		pr_err("unable to initialize mdss mdp resources\n");
 		goto probe_done;
 	}
+	rc = mdss_mdp_pp_init(&pdev->dev);
+	if (rc) {
+		pr_err("unable to initialize mdss pp resources\n");
+		goto probe_done;
+	}
 	rc = mdss_mdp_bus_scale_register(mdata);
 probe_done:
-	if (IS_ERR_VALUE(rc))
+	if (IS_ERR_VALUE(rc)) {
 		mdss_res = NULL;
+		mdss_mdp_pp_term(&pdev->dev);
+	}
 
 	return rc;
 }
@@ -942,6 +949,7 @@
 	if (!mdata)
 		return -ENODEV;
 	pm_runtime_disable(&pdev->dev);
+	mdss_mdp_pp_term(&pdev->dev);
 	mdss_mdp_bus_scale_unregister(mdata);
 	return 0;
 }
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index a77c18e..610c132 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -295,7 +295,7 @@
 int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg);
 
 int mdss_mdp_csc_setup(u32 block, u32 blk_idx, u32 tbl_idx, u32 csc_type);
-int mdss_mdp_dspp_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_mixer *mixer);
+int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl);
 
 struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(u32 pnum);
 struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_locked(u32 type);
@@ -318,4 +318,9 @@
 int mdss_mdp_wb_kickoff(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
 
+int mdss_mdp_pp_init(struct device *dev);
+void mdss_mdp_pp_term(struct device *dev);
+int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback);
+
+int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id);
 #endif /* MDSS_MDP_H */
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 1486779..26fbca1 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -20,8 +20,8 @@
 #include "mdss_fb.h"
 #include "mdss_mdp.h"
 
-/* 1.10 bus fudge factor */
-#define MDSS_MDP_BUS_FUDGE_FACTOR(val) ALIGN((((val) * 11) / 10), SZ_16M)
+/* 1.5 bus fudge factor */
+#define MDSS_MDP_BUS_FUDGE_FACTOR(val) ALIGN((((val) * 3) / 2), SZ_16M)
 /* 1.25 clock fudge factor */
 #define MDSS_MDP_CLK_FUDGE_FACTOR(val) (((val) * 5) / 4)
 
@@ -63,7 +63,6 @@
 		}
 	}
 	if (flags & MDSS_MDP_PERF_UPDATE_BUS) {
-		bus_ab_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ab_quota);
 		bus_ib_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ib_quota);
 		mdss_mdp_bus_scale_set_quota(bus_ab_quota, bus_ib_quota);
 	}
@@ -808,9 +807,6 @@
 {
 	mixer->params_changed = 0;
 
-	if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF)
-		mdss_mdp_dspp_setup(mixer->ctl, mixer);
-
 	/* skip mixer setup for rotator */
 	if (!mixer->rotator_mode)
 		mdss_mdp_mixer_setup(mixer->ctl, mixer);
@@ -864,6 +860,8 @@
 		ctl->flush_bits |= BIT(17);	/* CTL */
 	}
 
+	/* postprocessing setup, including dspp */
+	mdss_mdp_pp_setup(ctl);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits);
 	wmb();
 	ctl->flush_bits = 0;
@@ -885,3 +883,30 @@
 
 	return ret;
 }
+
+int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id)
+{
+	int i;
+	struct mdss_mdp_ctl *ctl;
+	u32 mixer_cnt = 0;
+	mutex_lock(&mdss_mdp_ctl_lock);
+	for (i = 0; i < MDSS_MDP_MAX_CTL; i++) {
+		ctl = &mdss_mdp_ctl_list[i];
+		if ((ctl->power_on) &&
+			(ctl->mfd->index == fb_num)) {
+			if (ctl->mixer_left) {
+				mixer_id[mixer_cnt] = ctl->mixer_left->num;
+				mixer_cnt++;
+			}
+			if (mixer_cnt && ctl->mixer_right) {
+				mixer_id[mixer_cnt] = ctl->mixer_right->num;
+				mixer_cnt++;
+			}
+			if (mixer_cnt)
+				break;
+		}
+	}
+	mutex_unlock(&mdss_mdp_ctl_lock);
+	return mixer_cnt;
+}
+
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 8825cc6..0139afd 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -321,6 +321,10 @@
 	MDSS_MDP_MAX_DSPP
 };
 
+#define MDSS_MDP_REG_DSPP_OFFSET(pipe)	(0x4600 + ((pipe) * 0x400))
+#define MDSS_MDP_REG_DSPP_OP_MODE			0x000
+#define MDSS_MDP_REG_DSPP_PA_BASE			0x238
+
 enum mdss_mpd_intf_index {
 	MDSS_MDP_NO_INTF,
 	MDSS_MDP_INTF0,
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index db840a8..7ab3b01 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -13,6 +13,7 @@
 
 #define pr_fmt(fmt)	"%s: " fmt, __func__
 
+#include "mdss_fb.h"
 #include "mdss_mdp.h"
 
 struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
@@ -71,6 +72,27 @@
 #define CSC_LV_OFF	0x14
 #define CSC_POST_OFF	0xC
 
+#define MDSS_BLOCK_DISP_NUM	(MDP_BLOCK_MAX - MDP_LOGICAL_BLOCK_DISP_0)
+
+struct pp_sts_type {
+	u32 pa_sts;
+};
+
+#define PP_FLAGS_DIRTY_PA	0x1
+
+#define PP_STS_ENABLE	0x1
+
+struct mdss_pp_res_type {
+	/* logical info */
+	u32 pp_disp_flags[MDSS_BLOCK_DISP_NUM];
+	struct mdp_pa_cfg_data pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
+	/* physical info */
+	struct pp_sts_type pp_dspp_sts[MDSS_MDP_MAX_DSPP];
+};
+
+static DEFINE_MUTEX(mdss_pp_mutex);
+static struct mdss_pp_res_type *mdss_pp_res;
+
 static int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
 				   struct mdp_csc_cfg *data)
 {
@@ -160,16 +182,147 @@
 	return mdss_mdp_csc_setup_data(block, blk_idx, tbl_idx, data);
 }
 
-int mdss_mdp_dspp_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_mixer *mixer)
+static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_mixer *mixer)
 {
-	int dspp_num;
-
-	if (!ctl || !mixer)
-		return -EINVAL;
+	u32 flags, base, offset, dspp_num, opmode = 0;
+	struct mdp_pa_cfg_data *pa_config;
+	struct pp_sts_type *pp_sts;
 
 	dspp_num = mixer->num;
+	/* no corresponding dspp */
+	if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
+		(dspp_num >= MDSS_MDP_MAX_DSPP))
+		return 0;
 
-	ctl->flush_bits |= BIT(13 + dspp_num);	/* DSPP */
+	if (disp_num < MDSS_BLOCK_DISP_NUM)
+		flags = mdss_pp_res->pp_disp_flags[disp_num];
+	else
+		flags = 0;
+
+	/* nothing to update */
+	if (!flags)
+		return 0;
+	pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
+	base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num);
+	if (flags & PP_FLAGS_DIRTY_PA) {
+		pa_config = &mdss_pp_res->pa_disp_cfg[disp_num];
+		if (pa_config->flags & MDP_PP_OPS_WRITE) {
+			offset = base + MDSS_MDP_REG_DSPP_PA_BASE;
+			MDSS_MDP_REG_WRITE(offset, pa_config->hue_adj);
+			offset += 4;
+			MDSS_MDP_REG_WRITE(offset, pa_config->sat_adj);
+			offset += 4;
+			MDSS_MDP_REG_WRITE(offset, pa_config->val_adj);
+			offset += 4;
+			MDSS_MDP_REG_WRITE(offset, pa_config->cont_adj);
+		}
+		if (pa_config->flags & MDP_PP_OPS_DISABLE)
+			pp_sts->pa_sts &= ~PP_STS_ENABLE;
+		else if (pa_config->flags & MDP_PP_OPS_ENABLE)
+			pp_sts->pa_sts |= PP_STS_ENABLE;
+	}
+	if (pp_sts->pa_sts & PP_STS_ENABLE)
+		opmode |= (1 << 20); /* PA_EN */
+	MDSS_MDP_REG_WRITE(base + MDSS_MDP_REG_DSPP_OP_MODE, opmode);
+	ctl->flush_bits |= BIT(13 + dspp_num); /* DSPP */
+	return 0;
+
+}
+int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
+{
+	u32 disp_num;
+	if ((!ctl->mfd) || (!mdss_pp_res))
+		return -EINVAL;
+
+	/* treat fb_num the same as block logical id*/
+	disp_num = ctl->mfd->index;
+
+	mutex_lock(&mdss_pp_mutex);
+	if (ctl->mixer_left)
+		pp_dspp_setup(disp_num, ctl, ctl->mixer_left);
+	if (ctl->mixer_right)
+		pp_dspp_setup(disp_num, ctl, ctl->mixer_right);
+	/* clear dirty flag */
+	if (disp_num < MDSS_BLOCK_DISP_NUM)
+		mdss_pp_res->pp_disp_flags[disp_num] = 0;
+	mutex_unlock(&mdss_pp_mutex);
 
 	return 0;
 }
+
+int mdss_mdp_pp_init(struct device *dev)
+{
+	int ret = 0;
+	mutex_lock(&mdss_pp_mutex);
+	if (!mdss_pp_res) {
+		mdss_pp_res = devm_kzalloc(dev, sizeof(*mdss_pp_res),
+				GFP_KERNEL);
+		if (mdss_pp_res == NULL) {
+			pr_err("%s mdss_pp_res allocation failed!", __func__);
+			ret = -ENOMEM;
+		}
+	}
+	mutex_unlock(&mdss_pp_mutex);
+	return ret;
+}
+void mdss_mdp_pp_term(struct device *dev)
+{
+	if (!mdss_pp_res) {
+		mutex_lock(&mdss_pp_mutex);
+		devm_kfree(dev, mdss_pp_res);
+		mdss_pp_res = NULL;
+		mutex_unlock(&mdss_pp_mutex);
+	}
+}
+
+int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback)
+{
+	int i, ret = 0;
+	u32 pa_offset, disp_num, mixer_cnt;
+	u32 mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+
+	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+		(config->block >= MDP_BLOCK_MAX))
+		return -EINVAL;
+
+	mutex_lock(&mdss_pp_mutex);
+	disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+	if (config->flags & MDP_PP_OPS_READ) {
+		mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
+		if (!mixer_cnt) {
+			ret = -EPERM;
+			goto pa_config_exit;
+		}
+		/* only read the first mixer */
+		for (i = 0; i < mixer_cnt; i++) {
+			if (mixer_id[i] < MDSS_MDP_MAX_DSPP)
+				break;
+		}
+		if (i >= mixer_cnt) {
+			ret = -EPERM;
+			goto pa_config_exit;
+		}
+		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+		pa_offset = MDSS_MDP_REG_DSPP_OFFSET(mixer_id[i]) +
+			  MDSS_MDP_REG_DSPP_PA_BASE;
+
+		config->hue_adj = MDSS_MDP_REG_READ(pa_offset);
+		pa_offset += 4;
+		config->sat_adj = MDSS_MDP_REG_READ(pa_offset);
+		pa_offset += 4;
+		config->val_adj = MDSS_MDP_REG_READ(pa_offset);
+		pa_offset += 4;
+		config->cont_adj = MDSS_MDP_REG_READ(pa_offset);
+		*copyback = 1;
+		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+	} else {
+		mdss_pp_res->pa_disp_cfg[disp_num] = *config;
+		mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_PA;
+	}
+
+pa_config_exit:
+	mutex_unlock(&mdss_pp_mutex);
+	return ret;
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
index 3620f1a..2af76f3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -70,7 +70,6 @@
 	case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED:
 	case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE:
 	case VIDC_1080P_ERROR_DIVIDE_BY_ZERO:
-	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
 	case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE:
 	case VIDC_1080P_ERROR_VSP_NOT_READY:
 	case VIDC_1080P_ERROR_BUFFER_FULL_STATE:
@@ -242,6 +241,7 @@
 	case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
 	case VIDC_1080P_ERROR_SLICE_PARSE_ERROR:
 	case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
 		vcd_status = VCD_ERR_BITSTREAM_ERR;
 		DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR");
 		break;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index bfc27dc..4f19de9 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -364,7 +364,7 @@
 				ddl->command_channel);
 		} else {
 			u32 seq_hdr_only_frame = false;
-			u32 need_reconfig = false;
+			u32 need_reconfig = false, eos_present = 0;
 			struct vcd_frame_data *input_vcd_frm =
 				&ddl->input_frame.vcd_frm;
 			need_reconfig = ddl_check_reconfig(ddl);
@@ -380,15 +380,25 @@
 				input_vcd_frm->offset +=
 					seq_hdr_info.dec_frm_size;
 				input_vcd_frm->data_len = 0;
-				input_vcd_frm->flags |=
-					VCD_FRAME_FLAG_CODECCONFIG;
-				ddl->input_frame.frm_trans_end =
-					!need_reconfig;
-				ddl_context->ddl_callback(
+				eos_present =
+				input_vcd_frm->flags & VCD_FRAME_FLAG_EOS;
+				if (!eos_present) {
+					input_vcd_frm->flags |=
+						VCD_FRAME_FLAG_CODECCONFIG;
+					ddl->input_frame.frm_trans_end =
+						!need_reconfig;
+					ddl_context->ddl_callback(
 					VCD_EVT_RESP_INPUT_DONE,
 					VCD_S_SUCCESS, &ddl->input_frame,
 					sizeof(struct ddl_frame_data_tag),
 					(u32 *) ddl, ddl->client_data);
+				} else {
+					input_vcd_frm->flags &=
+					~(VCD_FRAME_FLAG_CODECCONFIG);
+					seq_hdr_only_frame = false;
+					pr_err("%s() Codec config buffer with eos\n",
+						__func__);
+				}
 			} else {
 				if (decoder->codec.codec ==
 					VCD_CODEC_VC1_RCV) {
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index c9f9d74..d03ecfa 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -272,8 +272,10 @@
 	struct msmfb_img img;
 };
 
+#define MDP_PP_OPS_ENABLE 0x1
 #define MDP_PP_OPS_READ 0x2
 #define MDP_PP_OPS_WRITE 0x4
+#define MDP_PP_OPS_DISABLE 0x8
 
 struct mdp_qseed_cfg {
 	uint32_t table_num;
@@ -473,12 +475,22 @@
 	uint32_t scale;
 };
 
+struct mdp_pa_cfg_data {
+	uint32_t block;
+	uint32_t flags;
+	uint32_t hue_adj;
+	uint32_t sat_adj;
+	uint32_t val_adj;
+	uint32_t cont_adj;
+};
+
 enum {
 	mdp_op_pcc_cfg,
 	mdp_op_csc_cfg,
 	mdp_op_lut_cfg,
 	mdp_op_qseed_cfg,
 	mdp_bl_scale_cfg,
+	mdp_op_pa_cfg,
 	mdp_op_max,
 };
 
@@ -490,6 +502,7 @@
 		struct mdp_lut_cfg_data lut_cfg_data;
 		struct mdp_qseed_cfg_data qseed_cfg_data;
 		struct mdp_bl_scale_data bl_scale_data;
+		struct mdp_pa_cfg_data pa_cfg_data;
 	} data;
 };
 
diff --git a/include/linux/sync.h b/include/linux/sync.h
index 943f414..4c00f04 100644
--- a/include/linux/sync.h
+++ b/include/linux/sync.h
@@ -24,6 +24,7 @@
 struct sync_timeline;
 struct sync_pt;
 struct sync_fence;
+struct seq_file;
 
 /**
  * struct sync_timeline_ops - sync object implementation ops
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 5180b10..5b69da4 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1433,6 +1433,9 @@
 	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
 	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 
@@ -2361,6 +2364,7 @@
 	{"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+	{"MultiMedia5 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
 	{"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
 
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},