Merge "msm: camera: reqmgr: Skip reset if no request from UMD" into dev/msm-4.14-camx
diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie-camera-sensor-idp.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie-camera-sensor-idp.dtsi
index 85a3974..baf25c4 100644
--- a/arch/arm64/boot/dts/qcom/sdmmagpie-camera-sensor-idp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdmmagpie-camera-sensor-idp.dtsi
@@ -33,6 +33,16 @@
 		switch-source = <&pm6150l_switch2 &pm6150l_switch2>;
 		status = "ok";
 	};
+
+	led_flash_rear_aux2: qcom,camera-flash@2 {
+		cell-index = <2>;
+		reg = <0x02 0x00>;
+		compatible = "qcom,camera-flash";
+		flash-source = <&pm6150l_flash0 &pm6150l_flash1>;
+		torch-source = <&pm6150l_torch0 &pm6150l_torch1>;
+		switch-source = <&pm6150l_switch2 &pm6150l_switch2>;
+		status = "ok";
+	};
 };
 
 &cam_cci0 {
@@ -525,11 +535,11 @@
 		compatible = "qcom,cam-sensor";
 		reg = <0x6>;
 		csiphy-sd-index = <2>;
-		sensor-position-roll = <270>;
+		sensor-position-roll = <90>;
 		sensor-position-pitch = <0>;
-		sensor-position-yaw = <0>;
+		sensor-position-yaw = <180>;
 		eeprom-src = <&eeprom_triple_uw>;
-		led-flash-src = <&led_flash_rear_aux>;
+		led-flash-src = <&led_flash_rear_aux2>;
 		actuator-src = <&actuator_rear_aux>;
 		cam_vio-supply = <&pm8009_l7>;
 		cam_vana-supply = <&pm8009_l6>;
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h
index ff8be35..178d33d 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -251,6 +251,17 @@ struct cam_cdm_intf_mgr {
 	int32_t refcount;
 };
 
+/**
+ * struct cam_cdm_debugfs_entry : debugfs entry struct
+ *
+ * @dentry                       : entry of debugfs
+ * @dump_register                : flag to dump registers
+ */
+struct cam_cdm_debugfs_entry {
+	struct dentry   *dentry;
+	bool             dump_register;
+};
+
 int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw,
 	struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
 	uint32_t *index);
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
index 19413d6..af83aba 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
@@ -38,6 +38,8 @@
 
 static void cam_hw_cdm_work(struct work_struct *work);
 
+static struct cam_cdm_debugfs_entry debugfs_entry;
+
 /* DT match table entry for all CDM variants*/
 static const struct of_device_id msm_cam_hw_cdm_dt_match[] = {
 	{
@@ -69,6 +71,31 @@ int cam_hw_cdm_bl_fifo_pending_bl_rb(struct cam_hw_info *cdm_hw,
 	return rc;
 }
 
+static int cam_hw_cdm_create_debugfs_entry(void)
+{
+	int rc = 0;
+
+	debugfs_entry.dentry = debugfs_create_dir("camera_cdm", NULL);
+	if (!debugfs_entry.dentry)
+		return -ENOMEM;
+
+	if (!debugfs_create_bool("dump_register",
+		0644,
+		debugfs_entry.dentry,
+		&debugfs_entry.dump_register)) {
+		CAM_ERR(CAM_CDM,
+			"failed to create dump_register entry");
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	return rc;
+err:
+	debugfs_remove_recursive(debugfs_entry.dentry);
+	debugfs_entry.dentry = NULL;
+	return rc;
+}
+
 static int cam_hw_cdm_enable_bl_done_irq(struct cam_hw_info *cdm_hw,
 	bool enable)
 {
@@ -186,6 +213,9 @@ void cam_hw_cdm_dump_core_debug_registers(
 {
 	uint32_t dump_reg, core_dbg, loop_cnt;
 
+	if (!debugfs_entry.dump_register)
+		return;
+
 	mutex_lock(&cdm_hw->hw_mutex);
 	cam_cdm_read_hw_reg(cdm_hw, CDM_CFG_CORE_EN, &dump_reg);
 	CAM_ERR(CAM_CDM, "CDM HW core status=%x", dump_reg);
@@ -482,6 +512,14 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
 
 		if ((!rc) && (hw_vaddr_ptr) && (len) &&
 			(len >= cdm_cmd->cmd[i].offset)) {
+
+			if ((len - cdm_cmd->cmd[i].offset) <
+				cdm_cmd->cmd[i].len) {
+				CAM_ERR(CAM_CDM, "Not enough buffer");
+				rc = -EINVAL;
+				break;
+			}
+
 			CAM_DBG(CAM_CDM, "Got the HW VA");
 			if (core->bl_tag >=
 				(CAM_CDM_HWFIFO_SIZE - 1))
@@ -1012,6 +1050,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
 	}
 	cdm_hw->open_count--;
 	mutex_unlock(&cdm_hw->hw_mutex);
+	cam_hw_cdm_create_debugfs_entry();
 
 	CAM_DBG(CAM_CDM, "CDM%d probe successful", cdm_hw_intf->hw_idx);
 
diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
index 54f82ee..b2838b4 100644
--- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
@@ -596,6 +596,15 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl,
 					return -ENOMEM;
 				}
 
+				if (io_cfg[i].offsets[plane] >= size) {
+					CAM_ERR(CAM_FD,
+						"Invalid cpu buf %d %d %d",
+						io_cfg[i].direction,
+						io_cfg[i].resource_type, plane);
+					rc = -EINVAL;
+					goto rel_cpu_buf;
+				}
+
 				io_addr[plane] += io_cfg[i].offsets[plane];
 			}
 
diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
index fa9b442..41d1751 100644
--- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
+++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
@@ -45,6 +45,14 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
 		return -EINVAL;
 	}
 
+	mutex_lock(&ctx->ctx_mutex);
+
+	if (ctx->state < CAM_CTX_ACQUIRED || ctx->state > CAM_CTX_ACTIVATED) {
+		CAM_ERR(CAM_ICP, "Invalid state icp ctx %d state %d",
+			ctx->ctx_id, ctx->state);
+		goto end;
+	}
+
 	CAM_INFO(CAM_ICP, "iommu fault for icp ctx %d state %d",
 		ctx->ctx_id, ctx->state);
 
@@ -63,6 +71,8 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
 				req->request_id, rc);
 	}
 
+end:
+	mutex_unlock(&ctx->ctx_mutex);
 	return rc;
 }
 
@@ -137,6 +147,12 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
 		return rc;
 	}
 
+	if ((len < sizeof(struct cam_packet)) ||
+		(cmd->offset >= (len - sizeof(struct cam_packet)))) {
+		CAM_ERR(CAM_CTXT, "Not enough buf");
+		return -EINVAL;
+	}
+
 	packet = (struct cam_packet *) ((uint8_t *)packet_addr +
 		(uint32_t)cmd->offset);
 
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index 8c83cbc..eec56c7 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -64,6 +64,37 @@ static struct cam_icp_hw_mgr icp_hw_mgr;
 
 static void cam_icp_mgr_process_dbg_buf(unsigned int debug_lvl);
 
+static int cam_icp_dump_io_cfg(struct cam_icp_hw_ctx_data *ctx_data,
+	int32_t buf_handle)
+{
+	uintptr_t vaddr_ptr;
+	uint32_t  *ptr;
+	size_t    len;
+	int       rc, i;
+	char      buf[512];
+	int       used = 0;
+
+	rc = cam_mem_get_cpu_buf(buf_handle, &vaddr_ptr, &len);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Unable to get io_cfg buf address for %d",
+			ctx_data->ctx_id);
+		return rc;
+	}
+
+	len = len / sizeof(uint32_t);
+	ptr = (uint32_t *)vaddr_ptr;
+	for (i = 0; i < len; i++) {
+		used += snprintf(buf + used,
+			sizeof(buf) - used, "0X%08X-", ptr[i]);
+		if (!(i % 8)) {
+			CAM_INFO(CAM_ICP, "%s: %s", __func__, buf);
+			used = 0;
+		}
+	}
+
+	return rc;
+}
+
 static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr)
 {
 	struct cam_hw_intf *a5_dev_intf = NULL;
@@ -1262,6 +1293,44 @@ static int cam_icp_mgr_ipe_bps_power_collapse(struct cam_icp_hw_mgr *hw_mgr,
 	return rc;
 }
 
+static int cam_icp_mgr_ipe_bps_get_gdsc_control(
+	struct cam_icp_hw_mgr *hw_mgr)
+{
+	int rc = 0;
+	struct cam_hw_intf *ipe0_dev_intf = NULL;
+	struct cam_hw_intf *ipe1_dev_intf = NULL;
+	struct cam_hw_intf *bps_dev_intf = NULL;
+
+	ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
+	ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
+	bps_dev_intf = hw_mgr->bps_dev_intf;
+
+	if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
+		CAM_ERR(CAM_ICP, "dev intfs are wrong");
+		return -EINVAL;
+	}
+
+	if (icp_hw_mgr.ipe_bps_pc_flag) {
+		rc = bps_dev_intf->hw_ops.process_cmd(
+			bps_dev_intf->hw_priv,
+			CAM_ICP_BPS_CMD_POWER_COLLAPSE,
+			NULL, 0);
+
+		rc = ipe0_dev_intf->hw_ops.process_cmd(
+			ipe0_dev_intf->hw_priv,
+			CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0);
+
+		if (ipe1_dev_intf) {
+			rc = ipe1_dev_intf->hw_ops.process_cmd(
+				ipe1_dev_intf->hw_priv,
+				CAM_ICP_IPE_CMD_POWER_COLLAPSE,
+				NULL, 0);
+		}
+	}
+
+	return rc;
+}
+
 static int cam_icp_set_dbg_default_clk(void *data, u64 val)
 {
 	icp_hw_mgr.icp_debug_clk = val;
@@ -1786,27 +1855,31 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr)
 	ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
 	bps_dev_intf = hw_mgr->bps_dev_intf;
 
-	rc = bps_dev_intf->hw_ops.process_cmd(
-		bps_dev_intf->hw_priv,
-		CAM_ICP_BPS_CMD_RESET,
-		NULL, 0);
-	if (rc)
-		CAM_ERR(CAM_ICP, "bps reset failed");
+	if (hw_mgr->bps_ctxt_cnt) {
+		rc = bps_dev_intf->hw_ops.process_cmd(
+			bps_dev_intf->hw_priv,
+			CAM_ICP_BPS_CMD_RESET,
+			NULL, 0);
+		if (rc)
+			CAM_ERR(CAM_ICP, "bps reset failed");
+	}
 
-	rc = ipe0_dev_intf->hw_ops.process_cmd(
-		ipe0_dev_intf->hw_priv,
-		CAM_ICP_IPE_CMD_RESET,
-		NULL, 0);
-	if (rc)
-		CAM_ERR(CAM_ICP, "ipe0 reset failed");
-
-	if (ipe1_dev_intf) {
-		rc = ipe1_dev_intf->hw_ops.process_cmd(
-			ipe1_dev_intf->hw_priv,
+	if (hw_mgr->ipe_ctxt_cnt) {
+		rc = ipe0_dev_intf->hw_ops.process_cmd(
+			ipe0_dev_intf->hw_priv,
 			CAM_ICP_IPE_CMD_RESET,
 			NULL, 0);
 		if (rc)
-			CAM_ERR(CAM_ICP, "ipe1 reset failed");
+			CAM_ERR(CAM_ICP, "ipe0 reset failed");
+
+		if (ipe1_dev_intf) {
+			rc = ipe1_dev_intf->hw_ops.process_cmd(
+				ipe1_dev_intf->hw_priv,
+				CAM_ICP_IPE_CMD_RESET,
+				NULL, 0);
+			if (rc)
+				CAM_ERR(CAM_ICP, "ipe1 reset failed");
+		}
 	}
 
 	return 0;
@@ -1827,6 +1900,7 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr)
 	sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva;
 	CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg);
 
+	cam_icp_mgr_ipe_bps_get_gdsc_control(hw_mgr);
 	cam_icp_ipebps_reset(hw_mgr);
 
 	atomic_set(&hw_mgr->recovery, 1);
@@ -1854,6 +1928,10 @@ static int cam_icp_mgr_process_fatal_error(
 
 	if (event_notify->event_id == HFI_EVENT_SYS_ERROR) {
 		CAM_INFO(CAM_ICP, "received HFI_EVENT_SYS_ERROR");
+		if (event_notify->event_data1 == HFI_ERR_SYS_FATAL) {
+			CAM_ERR(CAM_ICP, "received HFI_ERR_SYS_FATAL");
+			BUG();
+		}
 		rc = cam_icp_mgr_trigger_recovery(hw_mgr);
 		cam_icp_mgr_process_dbg_buf(icp_hw_mgr.a5_dbg_lvl);
 	}
@@ -3445,6 +3523,17 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
 				goto rel_cmd_buf;
 			}
 			*fw_cmd_buf_iova_addr = addr;
+
+			if (cmd_desc[i].offset >= len ||
+				((len - cmd_desc[i].offset) <
+				cmd_desc[i].size)){
+				CAM_ERR(CAM_ICP,
+					"Invalid offset/length, i %d offset 0x%x len 0x%x size 0x%x",
+					i, cmd_desc[i].offset,
+					len, cmd_desc[i].size);
+				goto rel_cmd_buf;
+			}
+
 			*fw_cmd_buf_iova_addr =
 				(*fw_cmd_buf_iova_addr + cmd_desc[i].offset);
 			rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
@@ -4048,8 +4137,12 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
 
 	packet = prepare_args->packet;
 
-	if (cam_packet_util_validate_packet(packet, prepare_args->remain_len))
+	if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) {
+		mutex_unlock(&ctx_data->ctx_mutex);
+		CAM_ERR(CAM_ICP, "ctx id: %u packet req id %lld validate fail",
+			ctx_data->ctx_id, packet->header.request_id);
 		return -EINVAL;
+	}
 
 	rc = cam_icp_mgr_pkt_validation(packet);
 	if (rc) {
@@ -4670,6 +4763,8 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 	rc = cam_icp_mgr_send_config_io(ctx_data, io_buf_addr);
 	if (rc) {
 		CAM_ERR(CAM_ICP, "IO Config command failed %d", rc);
+		cam_icp_dump_io_cfg(ctx_data,
+			icp_dev_acquire_info->io_config_cmd_handle);
 		goto ioconfig_failed;
 	}
 
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index ff2f68d..5f23e87 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -2984,6 +2984,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
 		}
 	}
 
+	ctx->dual_ife_irq_mismatch_cnt = 0;
 	/* Start IFE root node: do nothing */
 	CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index);
 
@@ -3066,6 +3067,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
 	ctx->is_rdi_only_context = 0;
 	ctx->cdm_handle = 0;
 	ctx->cdm_ops = NULL;
+	ctx->dual_ife_irq_mismatch_cnt = 0;
 	atomic_set(&ctx->overflow_pending, 0);
 	for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
 		ctx->sof_cnt[i] = 0;
@@ -4078,6 +4080,36 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
 	}
 }
 
+static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx)
+{
+	struct cam_ife_hw_mgr_res        *hw_mgr_res;
+	struct cam_hw_intf               *hw_intf;
+	struct cam_isp_hw_get_cmd_update  cmd_update;
+	int i = 0;
+
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
+		if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT)
+			continue;
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+			switch (hw_mgr_res->hw_res[i]->res_id) {
+			case CAM_ISP_HW_VFE_IN_CAMIF:
+				hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+				cmd_update.res = hw_mgr_res->hw_res[i];
+				cmd_update.cmd_type =
+					CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP;
+				hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+					CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
+					&cmd_update, sizeof(cmd_update));
+				break;
+			default:
+				break;
+			}
+		}
+	}
+}
+
 static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 {
 	int rc = 0;
@@ -4748,11 +4780,26 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe(
 		(event_cnt[core_idx1] &&
 		(event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) {
 
+		if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) {
+			rc = -1;
+			return rc;
+		}
+
 		CAM_ERR_RATE_LIMIT(CAM_ISP,
 			"One of the VFE could not generate hw event %d",
 			hw_event_type);
-		rc = -1;
-		return rc;
+		if (event_cnt[core_idx0] >= 2) {
+			event_cnt[core_idx0]--;
+			ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
+		}
+		if (event_cnt[core_idx1] >= 2) {
+			event_cnt[core_idx1]--;
+			ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
+		}
+
+		if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1)
+			cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx);
+		rc = 0;
 	}
 
 	CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d",
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
index bf5f152..0e6d79b 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
@@ -102,38 +102,42 @@ struct cam_ife_hw_mgr_debug {
 /**
  * struct cam_vfe_hw_mgr_ctx - IFE HW manager Context object
  *
- * @list:                   used by the ctx list.
- * @common:                 common acquired context data
- * @ctx_index:              acquired context id.
- * @hw_mgr:                 IFE hw mgr which owns this context
- * @ctx_in_use:             flag to tell whether context is active
- * @res_list_ife_in:        Starting resource(TPG,PHY0, PHY1...) Can only be
- *                          one.
- * @res_list_csid:          CSID resource list
- * @res_list_ife_src:       IFE input resource list
- * @res_list_ife_in_rd      IFE input resource list for read path
- * @res_list_ife_out:       IFE output resoruces array
- * @free_res_list:          Free resources list for the branch node
- * @res_pool:               memory storage for the free resource list
- * @irq_status0_mask:       irq_status0_mask for the context
- * @irq_status1_mask:       irq_status1_mask for the context
- * @base                    device base index array contain the all IFE HW
- *                          instance associated with this context.
- * @num_base                number of valid base data in the base array
- * @cdm_handle              cdm hw acquire handle
- * @cdm_ops                 cdm util operation pointer for building
- *                          cdm commands
- * @cdm_cmd                 cdm base and length request pointer
- * @sof_cnt                 sof count value per core, used for dual VFE
- * @epoch_cnt               epoch count value per core, used for dual VFE
- * @eof_cnt                 eof count value per core, used for dual VFE
- * @overflow_pending        flat to specify the overflow is pending for the
- *                          context
- * @is_rdi_only_context     flag to specify the context has only rdi resource
- * @config_done_complete    indicator for configuration complete
- * @init_done               indicate whether init hw is done
- * @is_fe_enable            indicate whether fetch engine\read path is enabled
- * @res_bitmap              fill resource bitmap for which rup to be set
+ * @list:                       used by the ctx list.
+ * @common:                     common acquired context data
+ * @ctx_index:                  acquired context id.
+ * @hw_mgr:                     IFE hw mgr which owns this context
+ * @ctx_in_use:                 flag to tell whether context is active
+ * @res_list_ife_in:            Starting resource(TPG,PHY0, PHY1...) Can only be
+ *                              one.
+ * @res_list_csid:              CSID resource list
+ * @res_list_ife_src:           IFE input resource list
+ * @res_list_ife_in_rd          IFE input resource list for read path
+ * @res_list_ife_out:           IFE output resoruces array
+ * @free_res_list:              Free resources list for the branch node
+ * @res_pool:                   memory storage for the free resource list
+ * @irq_status0_mask:           irq_status0_mask for the context
+ * @irq_status1_mask:           irq_status1_mask for the context
+ * @base                        device base index array contain the all IFE HW
+ *                              instance associated with this context.
+ * @num_base                    number of valid base data in the base array
+ * @cdm_handle                  cdm hw acquire handle
+ * @cdm_ops                     cdm util operation pointer for building
+ *                              cdm commands
+ * @cdm_cmd                     cdm base and length request pointer
+ * @sof_cnt                     sof count value per core, used for dual VFE
+ * @epoch_cnt                   epoch count value per core, used for dual VFE
+ * @eof_cnt                     eof count value per core, used for dual VFE
+ * @overflow_pending            flat to specify the overflow is pending
+ *                              for the context
+ * @is_rdi_only_context         flag to specify the context has only rdi
+ *                              resource
+ * @config_done_complete        indicator for configuration complete
+ * @init_done                   indicate whether init hw is done
+ * @is_fe_enable                indicate whether fetch engine\read path
+ *                              is enabled
+ * @res_bitmap                  fill resource bitmap for which rup to be set
+ * @dual_ife_irq_mismatch_cnt   irq mismatch count value per core, used for
+ *                              dual VFE
  */
 struct cam_ife_hw_mgr_ctx {
 	struct list_head                list;
@@ -171,6 +175,7 @@ struct cam_ife_hw_mgr_ctx {
 	bool                            init_done;
 	bool                            is_fe_enable;
 	unsigned long                   res_bitmap;
+	uint32_t                        dual_ife_irq_mismatch_cnt;
 };
 
 /**
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index cd91334..ea0b01f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -46,7 +46,7 @@
 #define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12
 
 /* Max CSI Rx irq error count threshold value */
-#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT               100
+#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT               5
 
 static int cam_ife_csid_is_ipp_ppp_format_supported(
 	uint32_t in_format)
@@ -1479,15 +1479,13 @@ static void cam_ife_csid_halt_csi2(
 
 	csid_reg = csid_hw->csid_info->csid_reg;
 	soc_info = &csid_hw->hw_info->soc_info;
-	CAM_INFO(CAM_ISP, "CSID: %d cnt: %d Halt csi2 rx",
-		csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
 
 	/* Disable the CSI2 rx inerrupts */
-	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+	cam_io_w(0, soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
 
 	/* Reset the Rx CFG registers */
-	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+	cam_io_w(0, soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
 	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
@@ -3093,13 +3091,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_irq_cmd_addr);
 
-	CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", irq_status_top);
-	CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
-	CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
-	CAM_DBG(CAM_ISP, "irq_status_ppp = 0x%x", irq_status_ppp);
-	CAM_DBG(CAM_ISP, "irq_status_rdi0= 0x%x", irq_status_rdi[0]);
-	CAM_DBG(CAM_ISP, "irq_status_rdi1= 0x%x", irq_status_rdi[1]);
-	CAM_DBG(CAM_ISP, "irq_status_rdi2= 0x%x", irq_status_rdi[2]);
+	CAM_DBG(CAM_ISP,
+		"CSID %d irq status 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+		csid_hw->hw_intf->hw_idx, irq_status_top,
+		irq_status_rx, irq_status_ipp, irq_status_ppp,
+		irq_status_rdi[0], irq_status_rdi[1], irq_status_rdi[2]);
 
 	if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
 		CAM_DBG(CAM_ISP, "csi rx reset complete");
@@ -3109,71 +3105,38 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 	spin_lock_irqsave(&csid_hw->lock_state, flags);
 	if (csid_hw->device_enabled == 1) {
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
-				 csid_hw->hw_intf->hw_idx);
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
-				 csid_hw->hw_intf->hw_idx);
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
-				 csid_hw->hw_intf->hw_idx);
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
-				 csid_hw->hw_intf->hw_idx);
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
-				 csid_hw->hw_intf->hw_idx);
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"CSID:%d CPHY_EOT_RECEPTION",
-				 csid_hw->hw_intf->hw_idx);
 			csid_hw->error_irq_count++;
 		}
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"CSID:%d CPHY_SOT_RECEPTION",
-				 csid_hw->hw_intf->hw_idx);
 			csid_hw->error_irq_count++;
 		}
-		if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PH_CRC",
-				 csid_hw->hw_intf->hw_idx);
-		}
-		if (irq_status_rx & CSID_CSI2_RX_ERROR_CRC) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC",
-				 csid_hw->hw_intf->hw_idx);
-		}
-		if (irq_status_rx & CSID_CSI2_RX_ERROR_ECC) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC",
-				 csid_hw->hw_intf->hw_idx);
-		}
-		if (irq_status_rx & CSID_CSI2_RX_ERROR_MMAPPED_VC_DT) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d MMAPPED_VC_DT",
-				 csid_hw->hw_intf->hw_idx);
-		}
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"CSID:%d ERROR_STREAM_UNDERFLOW",
-				 csid_hw->hw_intf->hw_idx);
 			csid_hw->error_irq_count++;
 		}
 		if (irq_status_rx & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME",
-				 csid_hw->hw_intf->hw_idx);
 			csid_hw->error_irq_count++;
 		}
 	}
-	spin_unlock_irqrestore(&csid_hw->lock_state, flags);
 
 	if (csid_hw->error_irq_count >
 		CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT) {
@@ -3181,8 +3144,15 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 		csid_hw->error_irq_count = 0;
 	}
 
-	if (fatal_err_detected)
+handle_fatal_error:
+	spin_unlock_irqrestore(&csid_hw->lock_state, flags);
+	if (fatal_err_detected) {
+		CAM_INFO(CAM_ISP,
+			"CSID: %d cnt: %d Halt csi2 rx irq_status_rx:0x%x",
+			csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt,
+			irq_status_rx);
 		cam_ife_csid_halt_csi2(csid_hw);
+	}
 
 	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
 		if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
@@ -3283,7 +3253,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 		/* IPP reset done bit */
 		if (irq_status_ipp &
 			BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
-			CAM_DBG(CAM_ISP, "CSID IPP reset complete");
 			complete(&csid_hw->csid_ipp_complete);
 		}
 
@@ -3300,19 +3269,17 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 			CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received",
 				csid_hw->hw_intf->hw_idx);
 
-		if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION))
-			CAM_INFO_RATE_LIMIT(CAM_ISP,
-				"CSID:%d IPP CCIF violation",
-				csid_hw->hw_intf->hw_idx);
-
-		if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+		if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+			(irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
 			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"CSID:%d IPP fifo over flow",
-				csid_hw->hw_intf->hw_idx);
-			/* Stop IPP path immediately */
-			cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
-				soc_info->reg_map[0].mem_base +
-				csid_reg->ipp_reg->csid_pxl_ctrl_addr);
+				"CSID:%d irq_status_ipp:0x%x",
+				csid_hw->hw_intf->hw_idx, irq_status_ipp);
+			if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+				/* Stop IPP path immediately */
+				cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
+					soc_info->reg_map[0].mem_base +
+					csid_reg->ipp_reg->csid_pxl_ctrl_addr);
+			}
 		}
 	}
 
@@ -3321,7 +3288,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 		/* PPP reset done bit */
 		if (irq_status_ppp &
 			BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
-			CAM_DBG(CAM_ISP, "CSID PPP reset complete");
 			complete(&csid_hw->csid_ppp_complete);
 		}
 
@@ -3338,26 +3304,23 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 			CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received",
 				csid_hw->hw_intf->hw_idx);
 
-		if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION))
-			CAM_INFO_RATE_LIMIT(CAM_ISP,
-				"CSID:%d PPP CCIF violation",
-				csid_hw->hw_intf->hw_idx);
-
-		if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+		if ((irq_status_ppp & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+			(irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
 			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"CSID:%d PPP fifo over flow",
-				csid_hw->hw_intf->hw_idx);
-			/* Stop PPP path immediately */
-			cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
-				soc_info->reg_map[0].mem_base +
-				csid_reg->ppp_reg->csid_pxl_ctrl_addr);
+				"CSID:%d irq_status_ppp:0x%x",
+				csid_hw->hw_intf->hw_idx, irq_status_ppp);
+			if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+				/* Stop PPP path immediately */
+				cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
+					soc_info->reg_map[0].mem_base +
+					csid_reg->ppp_reg->csid_pxl_ctrl_addr);
+			}
 		}
 	}
 
 	for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
 		if (irq_status_rdi[i] &
 			BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
-			CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
 			complete(&csid_hw->csid_rdin_complete[i]);
 		}
 
@@ -3374,14 +3337,14 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 			CAM_INFO_RATE_LIMIT(CAM_ISP,
 				"CSID RDI:%d EOF received", i);
 
-		if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION))
-			CAM_INFO_RATE_LIMIT(CAM_ISP,
-			"CSIDi RDI :%d CCIF violation", i);
-
-		if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+		if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+			(irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
 			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"CSID:%d RDI fifo over flow",
-				csid_hw->hw_intf->hw_idx);
+				"CSID:%d irq_status_rdi[%d]:0x%x",
+				csid_hw->hw_intf->hw_idx, i,
+				irq_status_rdi[i]);
+		}
+		if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
 			/* Stop RDI path immediately */
 			cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
 				soc_info->reg_map[0].mem_base +
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index 6154256..b230147 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -104,6 +104,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE,
 	CAM_ISP_HW_CMD_FE_UPDATE_IN_RD,
 	CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD,
+	CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
 	CAM_ISP_HW_CMD_MAX,
 };
 
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index 6b123c8..a26c112 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -760,6 +760,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_CLOCK_UPDATE:
 	case CAM_ISP_HW_CMD_BW_UPDATE:
 	case CAM_ISP_HW_CMD_BW_CONTROL:
+	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
 		rc = core_info->vfe_top->hw_ops.process_cmd(
 			core_info->vfe_top->top_priv, cmd_type, cmd_args,
 			arg_size);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index 13b588f..3ed45ee 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -422,6 +422,40 @@ static int cam_vfe_camif_reg_dump_bh(
 	return 0;
 }
 
+static int cam_vfe_camif_irq_reg_dump(
+	struct cam_isp_resource_node *camif_res)
+{
+	struct cam_vfe_mux_camif_data *camif_priv;
+	struct cam_vfe_soc_private *soc_private;
+	int rc = 0;
+
+	if (!camif_res) {
+		CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n");
+		return -EINVAL;
+	}
+
+	if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) ||
+		(camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) {
+		CAM_ERR(CAM_ISP, "Error! Invalid state\n");
+		return 0;
+	}
+
+	camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv;
+	soc_private = camif_priv->soc_info->soc_private;
+
+	CAM_INFO(CAM_ISP,
+		"Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x",
+		camif_priv->hw_intf->hw_idx,
+		0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c),
+		0x60, cam_io_r_mb(camif_priv->mem_base + 0x60));
+	CAM_INFO(CAM_ISP,
+		"Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x",
+		camif_priv->hw_intf->hw_idx,
+		0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c),
+		0x70, cam_io_r_mb(camif_priv->mem_base + 0x70));
+	return rc;
+}
+
 static int cam_vfe_camif_resource_stop(
 	struct cam_isp_resource_node        *camif_res)
 {
@@ -509,6 +543,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node,
 			(struct cam_vfe_mux_camif_data *)rsrc_node->res_priv;
 		camif_priv->camif_debug = *((uint32_t *)cmd_args);
 		break;
+	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
+		rc = cam_vfe_camif_irq_reg_dump(rsrc_node);
+		break;
 	default:
 		CAM_ERR(CAM_ISP,
 			"unsupported process command:%d", cmd_type);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index 4dcad9c..d512128 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -438,6 +438,19 @@ static int cam_vfe_top_mux_get_reg_update(
 	return -EINVAL;
 }
 
+static int cam_vfe_get_irq_register_dump(
+	struct cam_vfe_top_ver2_priv *top_priv,
+	void *cmd_args, uint32_t arg_size)
+{
+	struct cam_isp_hw_get_cmd_update  *cmd_update = cmd_args;
+
+	if (cmd_update->res->process_cmd)
+		cmd_update->res->process_cmd(cmd_update->res,
+		CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, cmd_args, arg_size);
+
+	return 0;
+}
+
 int cam_vfe_top_get_hw_caps(void *device_priv,
 	void *get_hw_cap_args, uint32_t arg_size)
 {
@@ -723,6 +736,10 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_BW_CONTROL:
 		rc = cam_vfe_top_bw_control(top_priv, cmd_args, arg_size);
 		break;
+	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
+		rc = cam_vfe_get_irq_register_dump(top_priv,
+				cmd_args, arg_size);
+		break;
 	default:
 		rc = -EINVAL;
 		CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type);
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index 9e4578d..9ea8e3f 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -157,6 +157,12 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
 
 	cmd_buf_kaddr = (uint32_t *)kaddr;
 
+	if ((p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset /
+			sizeof(uint32_t)) >= cmd_buf_len) {
+		CAM_ERR(CAM_JPEG, "Not enough buf");
+		return -EINVAL;
+	}
+
 	cmd_buf_kaddr =
 		(cmd_buf_kaddr +
 		(p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
index cbb908c..35aa907 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
@@ -683,6 +683,7 @@ static int __cam_req_mgr_check_sync_for_mslave(
 	struct cam_req_mgr_slot      *sync_slot = NULL;
 	int sync_slot_idx = 0, prev_idx, next_idx, rd_idx, sync_rd_idx, rc = 0;
 	int64_t req_id = 0, sync_req_id = 0;
+	int32_t sync_num_slots = 0;
 
 	if (!link->sync_link) {
 		CAM_ERR(CAM_CRM, "Sync link null");
@@ -691,6 +692,7 @@ static int __cam_req_mgr_check_sync_for_mslave(
 
 	sync_link = link->sync_link;
 	req_id = slot->req_id;
+	sync_num_slots = sync_link->req.in_q->num_slots;
 	sync_rd_idx = sync_link->req.in_q->rd_idx;
 
 	CAM_DBG(CAM_CRM,
@@ -768,7 +770,8 @@ static int __cam_req_mgr_check_sync_for_mslave(
 
 			if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
 				CRM_SLOT_STATUS_REQ_APPLIED) &&
-				((sync_slot_idx - rd_idx) >= 1) &&
+				(((sync_slot_idx - rd_idx + sync_num_slots) %
+				sync_num_slots) >= 1) &&
 				(sync_link->req.in_q->slot[rd_idx].status !=
 				CRM_SLOT_STATUS_REQ_APPLIED)) {
 				CAM_DBG(CAM_CRM,
@@ -834,7 +837,8 @@ static int __cam_req_mgr_check_sync_for_mslave(
 
 			if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
 				CRM_SLOT_STATUS_REQ_APPLIED) &&
-				((sync_slot_idx - rd_idx) >= 1) &&
+				(((sync_slot_idx - rd_idx + sync_num_slots) %
+				sync_num_slots) >= 1) &&
 				(sync_link->req.in_q->slot[rd_idx].status !=
 				CRM_SLOT_STATUS_REQ_APPLIED)) {
 				CAM_DBG(CAM_CRM,
@@ -891,6 +895,7 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 	struct cam_req_mgr_core_link *sync_link = NULL;
 	int64_t req_id = 0;
 	int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0;
+	int32_t sync_num_slots = 0;
 
 	if (!link->sync_link) {
 		CAM_ERR(CAM_CRM, "Sync link null");
@@ -899,6 +904,7 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 
 	sync_link = link->sync_link;
 	req_id = slot->req_id;
+	sync_num_slots = sync_link->req.in_q->num_slots;
 
 	CAM_DBG(CAM_REQ,
 		"link_hdl %x req %lld frame_skip_flag %d ",
@@ -943,7 +949,8 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 	sync_rd_idx = sync_link->req.in_q->rd_idx;
 	if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
 		CRM_SLOT_STATUS_REQ_APPLIED) &&
-		((sync_slot_idx - sync_rd_idx) >= 1) &&
+		(((sync_slot_idx - sync_rd_idx + sync_num_slots) %
+		sync_num_slots) >= 1) &&
 		(sync_link->req.in_q->slot[sync_rd_idx].status !=
 		CRM_SLOT_STATUS_REQ_APPLIED)) {
 		CAM_DBG(CAM_CRM,
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 1908e9d..5304b46 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -232,13 +232,18 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
 	csiphy_dev->csiphy_info.csiphy_3phase =
 		cam_cmd_csiphy_info->csiphy_3phase;
 	csiphy_dev->csiphy_info.combo_mode |= cam_cmd_csiphy_info->combo_mode;
-	if (cam_cmd_csiphy_info->combo_mode == 1)
+	if (cam_cmd_csiphy_info->combo_mode == 1) {
 		csiphy_dev->csiphy_info.settle_time_combo_sensor =
 			cam_cmd_csiphy_info->settle_time;
-	else
+		csiphy_dev->csiphy_info.data_rate_combo_sensor =
+			cam_cmd_csiphy_info->data_rate;
+	} else {
 		csiphy_dev->csiphy_info.settle_time =
 			cam_cmd_csiphy_info->settle_time;
-	csiphy_dev->csiphy_info.data_rate = cam_cmd_csiphy_info->data_rate;
+		csiphy_dev->csiphy_info.data_rate =
+			cam_cmd_csiphy_info->data_rate;
+	}
+
 
 	if (cam_cmd_csiphy_info->secure_mode == 1)
 		cam_csiphy_update_secure_info(csiphy_dev,
@@ -269,6 +274,65 @@ void cam_csiphy_cphy_irq_config(struct csiphy_device *csiphy_dev)
 			csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr);
 }
 
+void cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device)
+{
+	int i = 0, j = 0;
+	uint64_t phy_data_rate = 0;
+	void __iomem *csiphybase = NULL;
+	ssize_t num_table_entries = 0;
+	struct data_rate_settings_t *settings_table = NULL;
+
+	if ((csiphy_device == NULL) ||
+		(csiphy_device->ctrl_reg == NULL) ||
+		(csiphy_device->ctrl_reg->data_rates_settings_table == NULL)) {
+		CAM_DBG(CAM_CSIPHY,
+			"Data rate specific register table not found");
+		return;
+	}
+
+	phy_data_rate = csiphy_device->csiphy_info.data_rate;
+	csiphybase =
+		csiphy_device->soc_info.reg_map[0].mem_base;
+	settings_table =
+		csiphy_device->ctrl_reg->data_rates_settings_table;
+	num_table_entries =
+		settings_table->num_data_rate_settings;
+
+	CAM_DBG(CAM_CSIPHY, "required data rate : %llu", phy_data_rate);
+	for (i = 0; i < num_table_entries; i++) {
+		struct data_rate_reg_info_t *drate_settings =
+			settings_table->data_rate_settings;
+		uint64_t bandwidth =
+			drate_settings[i].bandwidth;
+		ssize_t  num_reg_entries =
+		drate_settings[i].data_rate_reg_array_size;
+
+		if (phy_data_rate > bandwidth) {
+			CAM_DBG(CAM_CSIPHY,
+					"Skipping table [%d] %llu required: %llu",
+					i, bandwidth, phy_data_rate);
+			continue;
+		}
+
+		CAM_DBG(CAM_CSIPHY,
+			"table[%d] BW : %llu Selected", i, bandwidth);
+		for (j = 0; j < num_reg_entries; j++) {
+			uint32_t reg_addr =
+			drate_settings[i].csiphy_data_rate_regs[j].reg_addr;
+
+			uint32_t reg_data =
+			drate_settings[i].csiphy_data_rate_regs[j].reg_data;
+
+			CAM_DBG(CAM_CSIPHY,
+				"writing reg : %x val : %x",
+						reg_addr, reg_data);
+			cam_io_w_mb(reg_data,
+				csiphybase + reg_addr);
+		}
+		break;
+	}
+}
+
 void cam_csiphy_cphy_irq_disable(struct csiphy_device *csiphy_dev)
 {
 	int32_t i;
@@ -476,6 +540,9 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev)
 		lane_pos++;
 	}
 
+	if (csiphy_dev->csiphy_info.csiphy_3phase)
+		cam_csiphy_cphy_data_rate_config(csiphy_dev);
+
 	cam_csiphy_cphy_irq_config(csiphy_dev);
 
 	return rc;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
index 51cf9e9..cf81924d 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
@@ -44,8 +44,10 @@
 #define MAX_CSIPHY_REG_ARRAY        70
 #define MAX_CSIPHY_CMN_REG_ARRAY    5
 
-#define MAX_LANES             5
-#define MAX_SETTINGS_PER_LANE 43
+#define MAX_LANES                   5
+#define MAX_SETTINGS_PER_LANE       43
+#define MAX_DATA_RATES              3
+#define MAX_DATA_RATE_REGS          30
 
 #define MAX_REGULATOR         5
 #define CAMX_CSIPHY_DEV_NAME "cam-csiphy-driver"
@@ -155,6 +157,32 @@ struct csiphy_reg_t {
 	uint32_t csiphy_param_type;
 };
 
+struct csiphy_device;
+
+/*
+ * struct data_rate_reg_info_t
+ * @bandwidth: max bandwidth supported by this reg settings
+ * @data_rate_reg_array_size: number of reg value pairs in the array
+ * @csiphy_data_rate_regs: array of data rate specific reg value pairs
+ */
+struct data_rate_reg_info_t {
+	uint64_t bandwidth;
+	ssize_t  data_rate_reg_array_size;
+	struct csiphy_reg_t csiphy_data_rate_regs[MAX_DATA_RATE_REGS];
+};
+
+/**
+ * struct data_rate_settings_t
+ * @num_data_rate_settings: number of valid settings
+ *                          present in the data rate settings array
+ * @data_rate_settings: array of regsettings which are specific to
+ *                      data rate
+ */
+struct data_rate_settings_t {
+	ssize_t num_data_rate_settings;
+	struct data_rate_reg_info_t data_rate_settings[MAX_DATA_RATES];
+};
+
 /**
  * struct csiphy_ctrl_t
  * @csiphy_reg: Register address
@@ -166,6 +194,12 @@ struct csiphy_reg_t {
  * @csiphy_3ph_reg: 3phase register set
  * @csiphy_2ph_3ph_mode_reg:
  *     2 phase 3phase combo register set
+ * @getclockvoting: function pointer which
+ *      is used to find the clock voting
+ *      for the sensor output data rate
+ * @data_rate_settings_table:
+ *      Table which maintains the resgister
+ *      settings specific to data rate
  */
 struct csiphy_ctrl_t {
 	struct csiphy_reg_parms_t csiphy_reg;
@@ -176,6 +210,8 @@ struct csiphy_ctrl_t {
 	struct csiphy_reg_t (*csiphy_2ph_combo_mode_reg)[MAX_SETTINGS_PER_LANE];
 	struct csiphy_reg_t (*csiphy_3ph_reg)[MAX_SETTINGS_PER_LANE];
 	struct csiphy_reg_t (*csiphy_2ph_3ph_mode_reg)[MAX_SETTINGS_PER_LANE];
+	enum   cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev);
+	struct data_rate_settings_t *data_rates_settings_table;
 };
 
 /**
@@ -190,6 +226,8 @@ struct csiphy_ctrl_t {
  * @settle_time   :  Settling time in ms
  * @settle_time_combo_sensor   :  Settling time in ms
  * @data_rate     :  Data rate in mbps
+ * @data_rate_combo_sensor: data rate of combo sensor
+ *                          in the the same phy
  *
  */
 struct cam_csiphy_param {
@@ -202,6 +240,7 @@ struct cam_csiphy_param {
 	uint64_t    settle_time;
 	uint64_t    settle_time_combo_sensor;
 	uint64_t    data_rate;
+	uint64_t    data_rate_combo_sensor;
 };
 
 /**
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
index 0902601..0bf5aac 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -17,6 +17,9 @@
 #include "include/cam_csiphy_1_2_hwreg.h"
 #include "include/cam_csiphy_2_0_hwreg.h"
 
+#define CSIPHY_3PH_DIVISOR           16
+#define CSIPHY_3PH_DIVISOR_12        32
+#define CSIPHY_2PH_DIVISOR           8
 #define BYTES_PER_REGISTER           4
 #define NUM_REGISTER_PER_LINE        4
 #define REG_OFFSET(__start, __i)    ((__start) + ((__i) * BYTES_PER_REGISTER))
@@ -79,10 +82,62 @@ int32_t cam_csiphy_mem_dmp(struct cam_hw_soc_info *soc_info)
 	return rc;
 }
 
+enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev)
+{
+	CAM_DBG(CAM_CSIPHY, "voting for SVS");
+	return CAM_SVS_VOTE;
+}
+
+enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev)
+{
+	uint32_t cam_vote_level = 0;
+	uint32_t last_valid_vote = 0;
+	struct cam_hw_soc_info *soc_info;
+	uint64_t phy_data_rate = csiphy_dev->csiphy_info.data_rate;
+
+	soc_info = &csiphy_dev->soc_info;
+
+	if (csiphy_dev->is_acquired_dev_combo_mode)
+		phy_data_rate = max(phy_data_rate,
+			csiphy_dev->csiphy_info.data_rate_combo_sensor);
+
+	if (csiphy_dev->csiphy_info.csiphy_3phase) {
+		if (csiphy_dev->is_csiphy_3phase_hw == CSI_3PHASE_HW_12)
+			do_div(phy_data_rate, CSIPHY_3PH_DIVISOR_12);
+		else
+			do_div(phy_data_rate, CSIPHY_3PH_DIVISOR);
+	} else {
+		do_div(phy_data_rate, CSIPHY_2PH_DIVISOR);
+	}
+
+	 /* round off to next integer */
+	phy_data_rate += 1;
+
+	for (cam_vote_level = 0;
+			cam_vote_level < CAM_MAX_VOTE; cam_vote_level++) {
+		if (soc_info->clk_level_valid[cam_vote_level] != true)
+			continue;
+
+		if (soc_info->clk_rate[cam_vote_level][0] >
+				phy_data_rate) {
+			CAM_DBG(CAM_CSIPHY,
+				"match detected %s : %llu:%d level : %d",
+				soc_info->clk_name[0],
+				phy_data_rate,
+				soc_info->clk_rate[cam_vote_level][0],
+				cam_vote_level);
+			return cam_vote_level;
+		}
+		last_valid_vote = cam_vote_level;
+	}
+	return last_valid_vote;
+}
+
 int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
 {
 	int32_t rc = 0;
 	struct cam_hw_soc_info   *soc_info;
+	enum cam_vote_level vote_level = CAM_SVS_VOTE;
 
 	soc_info = &csiphy_dev->soc_info;
 
@@ -92,8 +147,9 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
 		return rc;
 	}
 
+	vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev);
 	rc = cam_soc_util_enable_platform_resource(soc_info, true,
-		CAM_SVS_VOTE, ENABLE_IRQ);
+		vote_level, ENABLE_IRQ);
 	if (rc < 0) {
 		CAM_ERR(CAM_CSIPHY, "failed to enable platform resources %d",
 			rc);
@@ -174,9 +230,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
 		csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_1_0;
 		csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_1_0;
 		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_0;
+		csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
 		csiphy_dev->hw_version = CSIPHY_VERSION_V10;
 		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
 		csiphy_dev->clk_lane = 0;
+		csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
 	} else if (of_device_is_compatible(soc_info->dev->of_node,
 		"qcom,csiphy-v1.1")) {
 		csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_1_reg;
@@ -191,9 +249,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
 		csiphy_dev->ctrl_reg->csiphy_reset_reg =
 			csiphy_reset_reg_1_1;
 		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_1;
+		csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
 		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
 		csiphy_dev->hw_version = CSIPHY_VERSION_V11;
 		csiphy_dev->clk_lane = 0;
+		csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
 	} else if (of_device_is_compatible(soc_info->dev->of_node,
 		"qcom,csiphy-v1.2")) {
 		csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_2_reg;
@@ -206,10 +266,13 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
 			csiphy_common_reg_1_2;
 		csiphy_dev->ctrl_reg->csiphy_reset_reg =
 			csiphy_reset_reg_1_2;
+		csiphy_dev->ctrl_reg->getclockvoting = get_clk_voting_dynamic;
 		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_2;
-		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
+		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW_12;
 		csiphy_dev->hw_version = CSIPHY_VERSION_V12;
 		csiphy_dev->clk_lane = 0;
+		csiphy_dev->ctrl_reg->data_rates_settings_table =
+			&data_rate_delta_table;
 	} else if (of_device_is_compatible(soc_info->dev->of_node,
 		"qcom,csiphy-v2.0")) {
 		csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v2_0_reg;
@@ -221,9 +284,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
 		csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_2_0;
 		csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_2_0;
 		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v2_0;
+		csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
 		csiphy_dev->hw_version = CSIPHY_VERSION_V20;
 		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
 		csiphy_dev->clk_lane = 0;
+		csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
 	} else {
 		CAM_ERR(CAM_CSIPHY, "invalid hw version : 0x%x",
 			csiphy_dev->hw_version);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
index 68ca68c..64d0561 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -34,6 +34,7 @@
 #define CDBG(fmt, args...) pr_debug(fmt, ##args)
 
 #define CSI_3PHASE_HW                               1
+#define CSI_3PHASE_HW_12                          0x12
 #define CSIPHY_VERSION_V35                        0x35
 #define CSIPHY_VERSION_V10                        0x10
 #define CSIPHY_VERSION_V11                        0x11
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
index 945910e..67653e8 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
@@ -19,10 +19,10 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
 	.mipi_csiphy_interrupt_status0_addr = 0x8B0,
 	.mipi_csiphy_interrupt_clear0_addr = 0x858,
 	.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
-	.csiphy_common_array_size = 4,
+	.csiphy_common_array_size = 6,
 	.csiphy_reset_array_size = 5,
 	.csiphy_2ph_config_array_size = 21,
-	.csiphy_3ph_config_array_size = 31,
+	.csiphy_3ph_config_array_size = 38,
 	.csiphy_2ph_clock_lane = 0x1,
 	.csiphy_2ph_combo_ck_ln = 0x10,
 };
@@ -30,8 +30,10 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
 struct csiphy_reg_t csiphy_common_reg_1_2[] = {
 	{0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE},
 	{0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
-	{0x081C, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
-	{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+	{0x081C, 0x02, 0x00, CSIPHY_2PH_REGS},
+	{0x081C, 0x52, 0x00, CSIPHY_3PH_REGS},
+	{0x0800, 0x02, 0x00, CSIPHY_2PH_REGS},
+	{0x0800, 0x0E, 0x00, CSIPHY_3PH_REGS},
 };
 
 struct csiphy_reg_t csiphy_reset_reg_1_2[] = {
@@ -297,7 +299,7 @@ struct csiphy_reg_t
 struct
 csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 	{
-		{0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x015C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -305,10 +307,10 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 		{0x0994, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0998, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x098C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0168, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x016C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x010C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
 		{0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -321,27 +323,34 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 		{0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0144, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x09C0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x09C4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x09C8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x09B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x09B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
-		{0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x035C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0A90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0A94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0A98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0A8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A98, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A8C, 0xBF, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0368, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x036C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x030C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
 		{0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -354,16 +363,23 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 		{0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0344, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0AB0, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0AC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0AC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0AC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0A80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0AB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0AB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
-		{0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x055C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -371,10 +387,10 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 		{0x0B94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0B98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0B8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0568, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x056C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x050C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
 		{0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -387,14 +403,107 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
 		{0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0544, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0BB0, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0BC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0BC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0BC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0B84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0B80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0BB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0BB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 };
 
+struct data_rate_settings_t data_rate_delta_table = {
+	.num_data_rate_settings = 3,
+	.data_rate_settings = {
+		{
+			/* (2.5 * 10**3 * 2.28) rounded value*/
+			.bandwidth = 5700000000,
+			.data_rate_reg_array_size = 12,
+			.csiphy_data_rate_regs = {
+				{0x15C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x35C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x55C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x16C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x36C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x56C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+			}
+		},
+		{
+			/* (3.5 * 10**3 * 2.28) rounded value */
+			.bandwidth = 7980000000,
+			.data_rate_reg_array_size = 24,
+			.csiphy_data_rate_regs = {
+				{0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+			},
+		},
+		{
+			/* (4.5 * 10**3 * 2.28) rounded value */
+			.bandwidth = 10260000000,
+			.data_rate_reg_array_size = 24,
+			.csiphy_data_rate_regs = {
+				{0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x9B4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xAB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xBB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x16C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x36C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+				{0x56C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+			},
+		}
+	}
+};
 #endif /* _CAM_CSIPHY_1_2_HWREG_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
index d3f62d6..84acb71 100644
--- a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
+++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
@@ -29,6 +29,20 @@ struct sync_device *sync_dev;
  */
 static bool trigger_cb_without_switch;
 
+void cam_sync_print_fence_table(void)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < CAM_SYNC_MAX_OBJS; cnt++) {
+		CAM_INFO(CAM_SYNC, "%d, %s, %d, %d, %d",
+			sync_dev->sync_table[cnt].sync_id,
+			sync_dev->sync_table[cnt].name,
+			sync_dev->sync_table[cnt].type,
+			sync_dev->sync_table[cnt].state,
+			sync_dev->sync_table[cnt].ref_cnt);
+	}
+}
+
 int cam_sync_create(int32_t *sync_obj, const char *name)
 {
 	int rc;
@@ -37,8 +51,15 @@ int cam_sync_create(int32_t *sync_obj, const char *name)
 
 	do {
 		idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
-		if (idx >= CAM_SYNC_MAX_OBJS)
+		if (idx >= CAM_SYNC_MAX_OBJS) {
+			CAM_ERR(CAM_SYNC,
+				"Error: Unable to Create Sync Idx = %d Reached Max!!",
+				idx);
+			sync_dev->err_cnt++;
+			if (sync_dev->err_cnt == 1)
+				cam_sync_print_fence_table();
 			return -ENOMEM;
+		}
 		CAM_DBG(CAM_SYNC, "Index location available at idx: %ld", idx);
 		bit = test_and_set_bit(idx, sync_dev->bitmap);
 	} while (bit);
@@ -765,6 +786,7 @@ static int cam_sync_open(struct file *filep)
 		CAM_ERR(CAM_SYNC, "Sync device NULL");
 		return -ENODEV;
 	}
+	sync_dev->err_cnt = 0;
 
 	mutex_lock(&sync_dev->table_lock);
 	if (sync_dev->open_cnt >= 1) {
@@ -797,6 +819,7 @@ static int cam_sync_close(struct file *filep)
 		rc = -ENODEV;
 		return rc;
 	}
+	sync_dev->err_cnt = 0;
 	mutex_lock(&sync_dev->table_lock);
 	sync_dev->open_cnt--;
 	if (!sync_dev->open_cnt) {
@@ -972,6 +995,7 @@ static int cam_sync_probe(struct platform_device *pdev)
 	if (!sync_dev)
 		return -ENOMEM;
 
+	sync_dev->err_cnt = 0;
 	mutex_init(&sync_dev->table_lock);
 	spin_lock_init(&sync_dev->cam_sync_eventq_lock);
 
diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h
index eb2fb34..c3cb345 100644
--- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h
+++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -184,6 +184,7 @@ struct cam_signalable_info {
  * @work_queue      : Work queue used for dispatching kernel callbacks
  * @cam_sync_eventq : Event queue used to dispatch user payloads to user space
  * @bitmap          : Bitmap representation of all sync objects
+ * @err_cnt         : Error counter to dump fence table
  */
 struct sync_device {
 	struct video_device *vdev;
@@ -197,6 +198,7 @@ struct sync_device {
 	struct v4l2_fh *cam_sync_eventq;
 	spinlock_t cam_sync_eventq_lock;
 	DECLARE_BITMAP(bitmap, CAM_SYNC_MAX_OBJS);
+	int err_cnt;
 };
 
 
diff --git a/include/uapi/media/cam_cpas.h b/include/uapi/media/cam_cpas.h
index c5cbac8..371b74c 100644
--- a/include/uapi/media/cam_cpas.h
+++ b/include/uapi/media/cam_cpas.h
@@ -6,6 +6,40 @@
 #define CAM_FAMILY_CAMERA_SS     1
 #define CAM_FAMILY_CPAS_SS       2
 
+/* AXI BW Voting Version */
+#define CAM_AXI_BW_VOTING_V2                2
+
+/* AXI BW Voting Transaction Type */
+#define CAM_AXI_TRANSACTION_READ            0
+#define CAM_AXI_TRANSACTION_WRITE           1
+
+/* AXI BW Voting Path Data Type */
+#define CAM_AXI_PATH_DATA_IFE_START_OFFSET 0
+#define CAM_AXI_PATH_DATA_IFE_LINEAR    (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 0)
+#define CAM_AXI_PATH_DATA_IFE_VID       (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 1)
+#define CAM_AXI_PATH_DATA_IFE_DISP      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 2)
+#define CAM_AXI_PATH_DATA_IFE_STATS     (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 3)
+#define CAM_AXI_PATH_DATA_IFE_RDI0      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 4)
+#define CAM_AXI_PATH_DATA_IFE_RDI1      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 5)
+#define CAM_AXI_PATH_DATA_IFE_RDI2      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 6)
+#define CAM_AXI_PATH_DATA_IFE_RDI3      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 7)
+#define CAM_AXI_PATH_DATA_IFE_PDAF      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 8)
+#define CAM_AXI_PATH_DATA_IFE_PIXEL_RAW \
+	(CAM_AXI_PATH_DATA_IFE_START_OFFSET + 9)
+#define CAM_AXI_PATH_DATA_IFE_MAX_OFFSET \
+	(CAM_AXI_PATH_DATA_IFE_START_OFFSET + 31)
+
+#define CAM_AXI_PATH_DATA_IPE_START_OFFSET 32
+#define CAM_AXI_PATH_DATA_IPE_RD_IN     (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 0)
+#define CAM_AXI_PATH_DATA_IPE_RD_REF    (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 1)
+#define CAM_AXI_PATH_DATA_IPE_WR_VID    (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 2)
+#define CAM_AXI_PATH_DATA_IPE_WR_DISP   (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 3)
+#define CAM_AXI_PATH_DATA_IPE_WR_REF    (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 4)
+#define CAM_AXI_PATH_DATA_IPE_MAX_OFFSET \
+	(CAM_AXI_PATH_DATA_IPE_START_OFFSET + 31)
+
+#define CAM_AXI_PATH_DATA_ALL              256
+
 /**
  * struct cam_cpas_query_cap - CPAS query device capability payload
  *
@@ -22,4 +56,29 @@ struct cam_cpas_query_cap {
 	struct cam_hw_version    cpas_version;
 };
 
+/**
+ * struct cam_axi_per_path_bw_vote - Per path bandwidth vote information
+ *
+ * @usage_data               client usage data (left/right/rdi)
+ * @transac_type             Transaction type on the path (read/write)
+ * @path_data_type           Path for which vote is given (video, display, rdi)
+ * @reserved                 Reserved for alignment
+ * @camnoc_bw                CAMNOC bw for this path
+ * @mnoc_ab_bw               MNOC AB bw for this path
+ * @mnoc_ib_bw               MNOC IB bw for this path
+ * @ddr_ab_bw                DDR AB bw for this path
+ * @ddr_ib_bw                DDR IB bw for this path
+ */
+struct cam_axi_per_path_bw_vote {
+	uint32_t                      usage_data;
+	uint32_t                      transac_type;
+	uint32_t                      path_data_type;
+	uint32_t                      reserved;
+	uint64_t                      camnoc_bw;
+	uint64_t                      mnoc_ab_bw;
+	uint64_t                      mnoc_ib_bw;
+	uint64_t                      ddr_ab_bw;
+	uint64_t                      ddr_ib_bw;
+};
+
 #endif /* __UAPI_CAM_CPAS_H__ */
diff --git a/include/uapi/media/cam_icp.h b/include/uapi/media/cam_icp.h
index 5b920d5..f38aa84 100644
--- a/include/uapi/media/cam_icp.h
+++ b/include/uapi/media/cam_icp.h
@@ -2,6 +2,7 @@
 #define __UAPI_CAM_ICP_H__
 
 #include "cam_defs.h"
+#include "cam_cpas.h"
 
 /* icp, ipe, bps, cdm(ipe/bps) are used in querycap */
 #define CAM_ICP_DEV_TYPE_A5      1
@@ -67,6 +68,26 @@
 #define CAM_ICP_CMD_GENERIC_BLOB_CFG_IO         0x2
 #define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_MAP     0x3
 #define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_UNMAP   0x4
+#define CAM_ICP_CMD_GENERIC_BLOB_CLK_V2         0x5
+
+/**
+ * struct cam_icp_clk_bw_request_v2
+ *
+ * @budget_ns: Time required to process frame
+ * @frame_cycles: Frame cycles needed to process the frame
+ * @rt_flag: Flag to indicate real time stream
+ * @reserved: For memory alignment
+ * @num_paths: Number of axi paths in bw request
+ * @axi_path: Per path vote info for IPE/BPS
+ */
+struct cam_icp_clk_bw_request_v2 {
+	uint64_t                          budget_ns;
+	uint32_t                          frame_cycles;
+	uint32_t                          rt_flag;
+	uint32_t                          reserved;
+	uint32_t                          num_paths;
+	struct cam_axi_per_path_bw_vote   axi_path[1];
+};
 
 /**
  * struct cam_icp_clk_bw_request
diff --git a/include/uapi/media/cam_isp.h b/include/uapi/media/cam_isp.h
index 749d61e..de32a61 100644
--- a/include/uapi/media/cam_isp.h
+++ b/include/uapi/media/cam_isp.h
@@ -4,7 +4,7 @@
 #include "cam_defs.h"
 #include "cam_isp_vfe.h"
 #include "cam_isp_ife.h"
-
+#include "cam_cpas.h"
 
 /* ISP driver name */
 #define CAM_ISP_DEV_NAME                        "cam-isp"
@@ -92,6 +92,12 @@
 #define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG           5
 #define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2        6
 
+/* Per Path Usage Data */
+#define CAM_ISP_USAGE_INVALID     0
+#define CAM_ISP_USAGE_LEFT_PX     1
+#define CAM_ISP_USAGE_RIGHT_PX    2
+#define CAM_ISP_USAGE_RDI         3
+
 /* Query devices */
 /**
  * struct cam_isp_dev_cap_info - A cap info for particular hw type
@@ -362,7 +368,6 @@ struct cam_isp_csid_clock_config {
  * @cam_bw_bps:                 Bandwidth vote for CAMNOC
  * @ext_bw_bps:                 Bandwidth vote for path-to-DDR after CAMNOC
  */
-
 struct cam_isp_bw_vote {
 	uint32_t                       resource_id;
 	uint32_t                       reserved;
@@ -379,7 +384,6 @@ struct cam_isp_bw_vote {
  * @right_pix_vote:             Bandwidth vote for right ISP
  * @rdi_vote:                   RDI bandwidth requirements
  */
-
 struct cam_isp_bw_config {
 	uint32_t                       usage_type;
 	uint32_t                       num_rdi;
@@ -408,6 +412,19 @@ struct cam_isp_bw_config_ab {
 } __attribute__((packed));
 
 /**
+ * struct cam_isp_bw_config_v2 - Bandwidth configuration
+ *
+ * @usage_type:                 Usage type (Single/Dual)
+ * @num_paths:                  Number of axi data paths
+ * @axi_path                    Per path vote info
+ */
+struct cam_isp_bw_config_v2 {
+	uint32_t                             usage_type;
+	uint32_t                             num_paths;
+	struct cam_axi_per_path_bw_vote      axi_path[1];
+} __attribute__((packed));
+
+/**
  * struct cam_fe_config - Fetch Engine configuration
  *
  * @version:                    fetch engine veriosn