Browse Source

FF: Upto PC439: 'quic/camera-kernel.lnx.4.0' into 5.0 11/02/20

* quic/camera-kernel.lnx.4.0:
  msm: camera: jpeg: Add traces to profile jpeg processing time
  msm: camera: cpas: Removing getting clk rate in cpas dump
  msm: camera: cpas: Update jpeg qosgen settings
  msm: camera: ife: Add support for camera v680 bus
  msm: camera: vfe: Add support for new VFE hardware
  msm: camera: isp: Add UAPI changes for new VFE hardware
  msm: camera: cci: Add back mutex on cci
  msm: camera: icp: Support NRT ipe clock bump-up
  msm: camera: utils: Add option to not set src clk rate
  msm: camera: reqmgr: Add protection while destroying the link
  msm: camera: icp: Tidy up hfi queue dump
  msm: camera: common: Enable flash operation at EOF
  msm: camera: sensor: Rename the dtsi entry to avoid the predefined string
  msm: camera: icp: remove the ioconfig dump during the error
  msm: camera: tfe: Correct Configuration of top tpg mux selection
  msm: camera: smmu: Fix the smmu create_handle function
  msm: camera: csid: Fix the EOT IRQ Reception for Sensors with EPD
  msm: camera: tfe: Move the CSID irq logs to bottom half
  msm: camera: tfe: TPG stop Call
  msm: camera: sync: Increase V4l2 queue size to 250
  msm: camera: sensor: Power down in case of cci init failure
  msm: camera: tfe: Enable only master interrupts in dual tfe usecase
  msm: camera: isp: Change csid stop sequence during flush
  msm: camera: isp: removed mutext lock from irq context
  msm: camera: tfe: Dont consider vbi for epoch configuration in case of tpg
  msm: camera: ife: Detect RDI only context before acquire hw
  msm: camera: common: Merge camera-kernel.3.1 changes in camera-kernel.4.0
  msm: camera: ife: Adjust epoch configuration
  msm: camera: cpas: Add cpas support for camera v680 platform
  msm: camera: cpas: Add qosgen shaping config

Change-Id: I2e7cc0d9f72729e43f98d8d769596fe475547371
Signed-off-by: Abhijit Trivedi <[email protected]>
Abhijit Trivedi 4 years ago
parent
commit
409e6debb7
88 changed files with 5694 additions and 1469 deletions
  1. 2 1
      drivers/cam_cdm/cam_cdm.h
  2. 1 4
      drivers/cam_cdm/cam_cdm_core_common.c
  3. 205 117
      drivers/cam_cdm/cam_cdm_hw_core.c
  4. 37 0
      drivers/cam_cdm/cam_cdm_intf_api.h
  5. 66 12
      drivers/cam_cdm/cam_cdm_util.c
  6. 9 2
      drivers/cam_cdm/cam_cdm_virtual_core.c
  7. 1 1
      drivers/cam_core/cam_context_utils.c
  8. 5 4
      drivers/cam_core/cam_node.c
  9. 20 19
      drivers/cam_cpas/cam_cpas_hw.c
  10. 0 1
      drivers/cam_cpas/cam_cpas_soc.c
  11. 22 0
      drivers/cam_cpas/cpas_top/cam_cpastop_hw.c
  12. 84 38
      drivers/cam_cpas/cpas_top/cam_cpastop_hw.h
  13. 212 0
      drivers/cam_cpas/cpas_top/cpastop_v570_200.h
  14. 6 6
      drivers/cam_cpas/cpas_top/cpastop_v580_100.h
  15. 6 6
      drivers/cam_cpas/cpas_top/cpastop_v580_custom.h
  16. 1213 0
      drivers/cam_cpas/cpas_top/cpastop_v680_100.h
  17. 18 0
      drivers/cam_cpas/include/cam_cpas_api.h
  18. 58 29
      drivers/cam_icp/hfi.c
  19. 56 15
      drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
  20. 30 1
      drivers/cam_isp/cam_isp_context.c
  21. 45 11
      drivers/cam_isp/cam_isp_dev.c
  22. 7 3
      drivers/cam_isp/cam_isp_dev.h
  23. 357 271
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
  24. 5 6
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
  25. 292 209
      drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c
  26. 11 8
      drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h
  27. 3 2
      drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
  28. 8 0
      drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
  29. 104 6
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
  30. 35 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
  31. 15 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
  32. 5 5
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h
  33. 2 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
  34. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.h
  35. 293 61
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c
  36. 27 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h
  37. 14 10
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c
  38. 18 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c
  39. 1 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
  40. 8 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h
  41. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h
  42. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170_150.h
  43. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h
  44. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h
  45. 100 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h
  46. 1328 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h
  47. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h
  48. 20 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h
  49. 314 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h
  50. 13 8
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
  51. 2 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h
  52. 237 510
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c
  53. 26 3
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h
  54. 4 3
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
  55. 4 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c
  56. 3 3
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.c
  57. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include/cam_vfe_top.h
  58. 3 0
      drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
  59. 1 0
      drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
  60. 4 4
      drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c
  61. 95 31
      drivers/cam_req_mgr/cam_req_mgr_core.c
  62. 10 1
      drivers/cam_req_mgr/cam_req_mgr_debug.c
  63. 5 1
      drivers/cam_req_mgr/cam_req_mgr_debug.h
  64. 2 1
      drivers/cam_req_mgr/cam_req_mgr_dev.c
  65. 25 4
      drivers/cam_req_mgr/cam_req_mgr_util.c
  66. 5 1
      drivers/cam_req_mgr/cam_req_mgr_util.h
  67. 24 0
      drivers/cam_req_mgr/cam_req_mgr_workq.c
  68. 24 8
      drivers/cam_req_mgr/cam_req_mgr_workq.h
  69. 9 1
      drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c
  70. 6 0
      drivers/cam_sensor_module/cam_cci/cam_cci_core.c
  71. 2 0
      drivers/cam_sensor_module/cam_cci/cam_cci_dev.h
  72. 2 1
      drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
  73. 7 1
      drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
  74. 3 6
      drivers/cam_sensor_module/cam_flash/cam_flash_core.c
  75. 1 0
      drivers/cam_sensor_module/cam_flash/cam_flash_dev.c
  76. 9 1
      drivers/cam_sensor_module/cam_ois/cam_ois_core.c
  77. 6 6
      drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c
  78. 10 1
      drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c
  79. 7 7
      drivers/cam_smmu/cam_smmu_api.c
  80. 2 0
      drivers/cam_sync/cam_sync.c
  81. 9 7
      drivers/cam_sync/cam_sync_private.h
  82. 3 0
      drivers/cam_sync/cam_sync_util.c
  83. 3 0
      drivers/cam_utils/cam_packet_util.c
  84. 11 1
      drivers/cam_utils/cam_soc_util.c
  85. 2 1
      drivers/cam_utils/cam_soc_util.h
  86. 35 0
      drivers/cam_utils/cam_trace.h
  87. 8 3
      include/uapi/camera/media/cam_isp_ife.h
  88. 1 0
      include/uapi/camera/media/cam_req_mgr.h

+ 2 - 1
drivers/cam_cdm/cam_cdm.h

@@ -440,6 +440,7 @@ struct cam_cdm_work_payload {
 	uint32_t irq_status;
 	uint32_t irq_data;
 	int fifo_idx;
+	ktime_t workq_scheduled_ts;
 	struct work_struct work;
 };
 
@@ -476,7 +477,7 @@ struct cam_cdm_bl_fifo {
 	uint8_t bl_tag;
 	uint32_t bl_depth;
 	uint8_t last_bl_tag_done;
-	uint32_t work_record;
+	atomic_t work_record;
 };
 
 /**

+ 1 - 4
drivers/cam_cdm/cam_cdm_core_common.c

@@ -206,6 +206,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
 	} else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE ||
 			status == CAM_CDM_CB_STATUS_HW_FLUSH ||
 			status == CAM_CDM_CB_STATUS_HW_RESUBMIT ||
+			status == CAM_CDM_CB_STATUS_INVALID_BL_CMD ||
 			status == CAM_CDM_CB_STATUS_HW_ERROR) {
 		int client_idx;
 		struct cam_cdm_bl_cb_request_entry *node =
@@ -800,13 +801,11 @@ int cam_cdm_process_cmd(void *hw_priv,
 		}
 
 		idx = CAM_CDM_GET_CLIENT_IDX(*handle);
-		mutex_lock(&cdm_hw->hw_mutex);
 		client = core->clients[idx];
 		if (!client) {
 			CAM_ERR(CAM_CDM,
 				"Client not present for handle %d",
 				*handle);
-			mutex_unlock(&cdm_hw->hw_mutex);
 			break;
 		}
 
@@ -814,12 +813,10 @@ int cam_cdm_process_cmd(void *hw_priv,
 			CAM_ERR(CAM_CDM,
 				"handle mismatch, client handle %d index %d received handle %d",
 				client->handle, idx, *handle);
-			mutex_unlock(&cdm_hw->hw_mutex);
 			break;
 		}
 
 		rc = cam_hw_cdm_hang_detect(cdm_hw, *handle);
-		mutex_unlock(&cdm_hw->hw_mutex);
 		break;
 	}
 	case CAM_CDM_HW_INTF_DUMP_DBG_REGS:

+ 205 - 117
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -25,6 +25,7 @@
 #include "cam_cdm_hw_reg_2_1.h"
 #include "camera_main.h"
 #include "cam_trace.h"
+#include "cam_req_mgr_workq.h"
 
 #define CAM_CDM_BL_FIFO_WAIT_TIMEOUT 2000
 #define CAM_CDM_DBG_GEN_IRQ_USR_DATA 0xff
@@ -569,7 +570,7 @@ int cam_hw_cdm_wait_for_bl_fifo(
 			CAM_DBG(CAM_CDM,
 				"BL slot available_cnt=%d requested=%d",
 				(available_bl_slots - 1), bl_count);
-				rc = bl_count;
+				rc = available_bl_slots - 1;
 				break;
 		} else if (0 == (available_bl_slots - 1)) {
 			rc = cam_hw_cdm_enable_bl_done_irq(cdm_hw,
@@ -595,7 +596,7 @@ int cam_hw_cdm_wait_for_bl_fifo(
 			if (cam_hw_cdm_enable_bl_done_irq(cdm_hw,
 					false, fifo_idx))
 				CAM_ERR(CAM_CDM, "Disable BL done irq failed");
-			rc = 0;
+			rc = 1;
 			CAM_DBG(CAM_CDM, "CDM HW is ready for data");
 		} else {
 			rc = (bl_count - (available_bl_slots - 1));
@@ -702,6 +703,7 @@ int cam_hw_cdm_submit_gen_irq(
 			core->bl_fifo[fifo_idx].bl_tag);
 		list_del_init(&node->entry);
 		kfree(node);
+		node = NULL;
 		rc = -EIO;
 		goto end;
 	}
@@ -712,6 +714,7 @@ int cam_hw_cdm_submit_gen_irq(
 			core->bl_fifo[fifo_idx].bl_tag);
 		list_del_init(&node->entry);
 		kfree(node);
+		node = NULL;
 		rc = -EIO;
 	}
 
@@ -922,8 +925,6 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
 				rc = -EIO;
 				break;
 			}
-		} else {
-			write_count--;
 		}
 
 		if (req->data->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE) {
@@ -1026,27 +1027,58 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
 					rc = -EIO;
 					break;
 				}
+				write_count--;
 				CAM_DBG(CAM_CDM, "commit success BL %d tag=%d",
 					i, core->bl_fifo[fifo_idx].bl_tag);
 			}
 			core->bl_fifo[fifo_idx].bl_tag++;
 
 			if (cdm_cmd->cmd[i].enable_debug_gen_irq) {
+				if (write_count == 0) {
+					write_count =
+						cam_hw_cdm_wait_for_bl_fifo(
+						cdm_hw, 1, fifo_idx);
+					if (write_count < 0) {
+						CAM_ERR(CAM_CDM,
+						"wait for bl fifo failed %d:%d",
+						i, req->data->cmd_arrary_count);
+						rc = -EIO;
+						break;
+					}
+				}
+
 				rc = cam_hw_cdm_submit_debug_gen_irq(cdm_hw,
 					fifo_idx);
-				if (rc == 0)
+				if (rc == 0) {
+					write_count--;
 					core->bl_fifo[fifo_idx].bl_tag++;
+				}
 				if (core->bl_fifo[fifo_idx].bl_tag >=
 						(bl_fifo->bl_depth -
 						1))
 					core->bl_fifo[fifo_idx].bl_tag = 0;
 			}
 
-			if ((req->data->flag == true) &&
+			if ((!rc) && (req->data->flag == true) &&
 				(i == (req->data->cmd_arrary_count -
 				1))) {
+
+				if (write_count == 0) {
+					write_count =
+						cam_hw_cdm_wait_for_bl_fifo(
+						cdm_hw, 1, fifo_idx);
+					if (write_count < 0) {
+						CAM_ERR(CAM_CDM,
+						"wait for bl fifo failed %d:%d",
+						i, req->data->cmd_arrary_count);
+						rc = -EIO;
+						break;
+					}
+				}
+
 				if (core->arbitration !=
 					CAM_CDM_ARBITRATION_PRIORITY_BASED) {
+
 					rc = cam_hw_cdm_submit_gen_irq(
 						cdm_hw, req, fifo_idx,
 						cdm_cmd->gen_irq_arb);
@@ -1080,7 +1112,8 @@ static void cam_hw_cdm_reset_cleanup(
 	struct cam_cdm_bl_cb_request_entry *node, *tnode;
 	bool flush_hw = false;
 
-	if (test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status))
+	if (test_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status) ||
+		test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status))
 		flush_hw = true;
 
 	for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) {
@@ -1104,10 +1137,11 @@ static void cam_hw_cdm_reset_cleanup(
 			}
 			list_del_init(&node->entry);
 			kfree(node);
+			node = NULL;
 		}
 		core->bl_fifo[i].bl_tag = 0;
 		core->bl_fifo[i].last_bl_tag_done = -1;
-		core->bl_fifo[i].work_record = 0;
+		atomic_set(&core->bl_fifo[i].work_record, 0);
 	}
 }
 
@@ -1116,121 +1150,165 @@ static void cam_hw_cdm_work(struct work_struct *work)
 	struct cam_cdm_work_payload *payload;
 	struct cam_hw_info *cdm_hw;
 	struct cam_cdm *core;
-	int i;
+	int i, fifo_idx;
+	struct cam_cdm_bl_cb_request_entry *tnode = NULL;
+	struct cam_cdm_bl_cb_request_entry *node = NULL;
 
 	payload = container_of(work, struct cam_cdm_work_payload, work);
-	if (payload) {
-		cdm_hw = payload->hw;
-		core = (struct cam_cdm *)cdm_hw->core_info;
-		if (payload->fifo_idx >= core->offsets->reg_data->num_bl_fifo) {
-			CAM_ERR(CAM_CDM, "Invalid fifo idx %d",
-				payload->fifo_idx);
+	if (!payload) {
+		CAM_ERR(CAM_CDM, "NULL payload");
+		return;
+	}
+
+	cdm_hw = payload->hw;
+	core = (struct cam_cdm *)cdm_hw->core_info;
+	fifo_idx = payload->fifo_idx;
+	if (fifo_idx >= core->offsets->reg_data->num_bl_fifo) {
+		CAM_ERR(CAM_CDM, "Invalid fifo idx %d",
+			fifo_idx);
+		kfree(payload);
+		payload = NULL;
+		return;
+	}
+
+	cam_req_mgr_thread_switch_delay_detect(
+		payload->workq_scheduled_ts);
+
+	CAM_DBG(CAM_CDM, "IRQ status=0x%x", payload->irq_status);
+	if (payload->irq_status &
+		CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK) {
+		CAM_DBG(CAM_CDM, "inline IRQ data=0x%x last tag: 0x%x",
+			payload->irq_data,
+			core->bl_fifo[payload->fifo_idx]
+				.last_bl_tag_done);
+
+		if (payload->irq_data == 0xff) {
+			CAM_INFO(CAM_CDM, "Debug genirq received");
 			kfree(payload);
+			payload = NULL;
 			return;
 		}
 
-		CAM_DBG(CAM_CDM, "IRQ status=0x%x", payload->irq_status);
-		if (payload->irq_status &
-			CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK) {
-			struct cam_cdm_bl_cb_request_entry *node, *tnode;
-
-			CAM_DBG(CAM_CDM, "inline IRQ data=0x%x last tag: 0x%x",
-				payload->irq_data,
-				core->bl_fifo[payload->fifo_idx]
-					.last_bl_tag_done);
-
-			if (payload->irq_data == 0xff) {
-				CAM_INFO(CAM_CDM, "Debug genirq received");
-				kfree(payload);
-				return;
-			}
+		mutex_lock(&core->bl_fifo[fifo_idx].fifo_lock);
 
-			mutex_lock(&core->bl_fifo[payload->fifo_idx]
-				.fifo_lock);
-
-			if (core->bl_fifo[payload->fifo_idx].work_record)
-				core->bl_fifo[payload->fifo_idx].work_record--;
-
-			if (list_empty(&core->bl_fifo[payload->fifo_idx]
-					.bl_request_list)) {
-				CAM_INFO(CAM_CDM,
-					"Fifo list empty, idx %d tag %d arb %d",
-					payload->fifo_idx, payload->irq_data,
-					core->arbitration);
-				mutex_unlock(&core->bl_fifo[payload->fifo_idx]
-						.fifo_lock);
-				return;
-			}
+		if (atomic_read(&core->bl_fifo[fifo_idx].work_record))
+			atomic_dec(&core->bl_fifo[fifo_idx].work_record);
 
-			if (core->bl_fifo[payload->fifo_idx]
-				.last_bl_tag_done !=
-				payload->irq_data) {
-				core->bl_fifo[payload->fifo_idx]
-					.last_bl_tag_done =
-					payload->irq_data;
-				list_for_each_entry_safe(node, tnode,
-					&core->bl_fifo[payload->fifo_idx]
-						.bl_request_list,
-					entry) {
-					if (node->request_type ==
-						CAM_HW_CDM_BL_CB_CLIENT) {
-						cam_cdm_notify_clients(cdm_hw,
-						CAM_CDM_CB_STATUS_BL_SUCCESS,
-						(void *)node);
-					} else if (node->request_type ==
-						CAM_HW_CDM_BL_CB_INTERNAL) {
-						CAM_ERR(CAM_CDM,
-							"Invalid node=%pK %d",
-							node,
-							node->request_type);
-					}
-					list_del_init(&node->entry);
-					if (node->bl_tag == payload->irq_data) {
-						kfree(node);
-						break;
-					}
+		if (list_empty(&core->bl_fifo[fifo_idx]
+				.bl_request_list)) {
+			CAM_INFO(CAM_CDM,
+				"Fifo list empty, idx %d tag %d arb %d",
+				fifo_idx, payload->irq_data,
+				core->arbitration);
+			mutex_unlock(&core->bl_fifo[fifo_idx]
+					.fifo_lock);
+			return;
+		}
+
+		if (core->bl_fifo[fifo_idx].last_bl_tag_done !=
+			payload->irq_data) {
+			core->bl_fifo[fifo_idx].last_bl_tag_done =
+				payload->irq_data;
+			list_for_each_entry_safe(node, tnode,
+				&core->bl_fifo[fifo_idx].bl_request_list,
+				entry) {
+				if (node->request_type ==
+					CAM_HW_CDM_BL_CB_CLIENT) {
+					cam_cdm_notify_clients(cdm_hw,
+					CAM_CDM_CB_STATUS_BL_SUCCESS,
+					(void *)node);
+				} else if (node->request_type ==
+					CAM_HW_CDM_BL_CB_INTERNAL) {
+					CAM_ERR(CAM_CDM,
+						"Invalid node=%pK %d",
+						node,
+						node->request_type);
 				}
-			} else {
-				CAM_INFO(CAM_CDM,
-					"Skip GenIRQ, tag 0x%x fifo %d",
-					payload->irq_data, payload->fifo_idx);
+				list_del_init(&node->entry);
+				if (node->bl_tag == payload->irq_data) {
+					kfree(node);
+					node = NULL;
+					break;
+				}
+				kfree(node);
+				node = NULL;
 			}
-			mutex_unlock(&core->bl_fifo[payload->fifo_idx]
-				.fifo_lock);
+		} else {
+			CAM_INFO(CAM_CDM,
+				"Skip GenIRQ, tag 0x%x fifo %d",
+				payload->irq_data, payload->fifo_idx);
+		}
+		mutex_unlock(&core->bl_fifo[payload->fifo_idx]
+			.fifo_lock);
+	}
+
+	if (payload->irq_status &
+		CAM_CDM_IRQ_STATUS_BL_DONE_MASK) {
+		if (test_bit(payload->fifo_idx, &core->cdm_status)) {
+			CAM_DBG(CAM_CDM, "CDM HW BL done IRQ");
+			complete(&core->bl_fifo[payload->fifo_idx]
+				.bl_complete);
 		}
+	}
+	if (payload->irq_status &
+		CAM_CDM_IRQ_STATUS_ERRORS) {
+		int reset_hw_hdl = 0x0;
+
+		CAM_ERR_RATE_LIMIT(CAM_CDM,
+			"CDM Error IRQ status %d\n",
+			payload->irq_status);
+		set_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
+		mutex_lock(&cdm_hw->hw_mutex);
+		for (i = 0; i < core->offsets->reg_data->num_bl_fifo;
+				i++)
+			mutex_lock(&core->bl_fifo[i].fifo_lock);
+		/*
+		 * First pause CDM, If it fails still proceed
+		 * to dump debug info
+		 */
+		cam_hw_cdm_pause_core(cdm_hw, true);
+		cam_hw_cdm_dump_core_debug_registers(cdm_hw, true);
 
 		if (payload->irq_status &
-			CAM_CDM_IRQ_STATUS_BL_DONE_MASK) {
-			if (test_bit(payload->fifo_idx, &core->cdm_status)) {
-				CAM_DBG(CAM_CDM, "CDM HW BL done IRQ");
-				complete(&core->bl_fifo[payload->fifo_idx]
-					.bl_complete);
+		CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK) {
+			node = list_first_entry_or_null(
+			&core->bl_fifo[payload->fifo_idx].bl_request_list,
+			struct cam_cdm_bl_cb_request_entry, entry);
+
+			if (node != NULL) {
+				if (node->request_type ==
+					CAM_HW_CDM_BL_CB_CLIENT) {
+					cam_cdm_notify_clients(cdm_hw,
+					CAM_CDM_CB_STATUS_INVALID_BL_CMD,
+						(void *)node);
+				} else if (node->request_type ==
+					CAM_HW_CDM_BL_CB_INTERNAL) {
+					CAM_ERR(CAM_CDM,
+						"Invalid node=%pK %d", node,
+						node->request_type);
+				}
+				list_del_init(&node->entry);
+				kfree(node);
 			}
 		}
+		/* Resume CDM back */
+		cam_hw_cdm_pause_core(cdm_hw, false);
+		for (i = 0; i < core->offsets->reg_data->num_bl_fifo;
+				i++)
+			mutex_unlock(&core->bl_fifo[i].fifo_lock);
+
 		if (payload->irq_status &
-				CAM_CDM_IRQ_STATUS_ERRORS) {
-			CAM_ERR_RATE_LIMIT(CAM_CDM,
-				"CDM Error IRQ status %d\n",
-				payload->irq_status);
-			set_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
-			mutex_lock(&cdm_hw->hw_mutex);
-			for (i = 0; i < core->offsets->reg_data->num_bl_fifo;
-					i++)
-				mutex_lock(&core->bl_fifo[i].fifo_lock);
-			cam_hw_cdm_dump_core_debug_registers(cdm_hw, true);
-			for (i = 0; i < core->offsets->reg_data->num_bl_fifo;
-					i++)
-				mutex_unlock(&core->bl_fifo[i].fifo_lock);
-			mutex_unlock(&cdm_hw->hw_mutex);
-			if (!(payload->irq_status &
-					CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK))
-				clear_bit(CAM_CDM_ERROR_HW_STATUS,
-					&core->cdm_status);
-		}
-		kfree(payload);
-	} else {
-		CAM_ERR(CAM_CDM, "NULL payload");
+			CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK)
+			cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl);
+
+		mutex_unlock(&cdm_hw->hw_mutex);
+		if (!(payload->irq_status &
+				CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK))
+			clear_bit(CAM_CDM_ERROR_HW_STATUS,
+				&core->cdm_status);
 	}
+	kfree(payload);
+	payload = NULL;
 
 }
 
@@ -1369,7 +1447,9 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
 			return IRQ_HANDLED;
 		}
 
-		cdm_core->bl_fifo[i].work_record++;
+		atomic_inc(&cdm_core->bl_fifo[i].work_record);
+		payload[i]->workq_scheduled_ts = ktime_get();
+
 		work_status = queue_work(
 			cdm_core->bl_fifo[i].work_queue,
 			&payload[i]->work);
@@ -1379,6 +1459,7 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
 				"Failed to queue work for FIFO: %d irq=0x%x",
 				i, payload[i]->irq_status);
 			kfree(payload[i]);
+			payload[i] = NULL;
 		}
 	}
 	if (rst_done_cnt == cdm_core->offsets->reg_data->num_bl_fifo_irq) {
@@ -1629,6 +1710,7 @@ int cam_hw_cdm_handle_error_info(
 		}
 		list_del_init(&node->entry);
 		kfree(node);
+		node = NULL;
 	}
 
 	cam_hw_cdm_reset_cleanup(cdm_hw, reset_hw_hdl);
@@ -1679,20 +1761,14 @@ int cam_hw_cdm_hang_detect(
 	cdm_core = (struct cam_cdm *)cdm_hw->core_info;
 
 	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
-		mutex_lock(&cdm_core->bl_fifo[i].fifo_lock);
-
-	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
-		if (cdm_core->bl_fifo[i].work_record) {
+		if (atomic_read(&cdm_core->bl_fifo[i].work_record)) {
 			CAM_WARN(CAM_CDM,
-				"workqueue got delayed, bl_fifo: %d, work_record :%u",
-				i, cdm_core->bl_fifo[i].work_record);
+				"workqueue got delayed, work_record :%u",
+				atomic_read(&cdm_core->bl_fifo[i].work_record));
 			rc = 0;
 			break;
 		}
 
-	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
-		mutex_unlock(&cdm_core->bl_fifo[i].fifo_lock);
-
 	return rc;
 }
 
@@ -1797,7 +1873,7 @@ int cam_hw_cdm_init(void *hw_priv,
 	}
 	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) {
 		cdm_core->bl_fifo[i].last_bl_tag_done = -1;
-		cdm_core->bl_fifo[i].work_record = 0;
+		atomic_set(&cdm_core->bl_fifo[i].work_record, 0);
 	}
 
 	rc = cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl);
@@ -1856,6 +1932,7 @@ int cam_hw_cdm_deinit(void *hw_priv,
 			&cdm_core->bl_fifo[i].bl_request_list, entry) {
 			list_del_init(&node->entry);
 			kfree(node);
+			node = NULL;
 		}
 	}
 
@@ -1931,13 +2008,16 @@ static int cam_hw_cdm_component_bind(struct device *dev,
 	cdm_hw = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
 	if (!cdm_hw) {
 		kfree(cdm_hw_intf);
+		cdm_hw_intf = NULL;
 		return -ENOMEM;
 	}
 
 	cdm_hw->core_info = kzalloc(sizeof(struct cam_cdm), GFP_KERNEL);
 	if (!cdm_hw->core_info) {
 		kfree(cdm_hw);
+		cdm_hw = NULL;
 		kfree(cdm_hw_intf);
+		cdm_hw_intf = NULL;
 		return -ENOMEM;
 	}
 
@@ -2174,11 +2254,15 @@ unlock_release_mem:
 	mutex_unlock(&cdm_hw->hw_mutex);
 release_private_mem:
 	kfree(cdm_hw->soc_info.soc_private);
+	cdm_hw->soc_info.soc_private = NULL;
 release_mem:
 	mutex_destroy(&cdm_hw->hw_mutex);
 	kfree(cdm_hw_intf);
+	cdm_hw_intf = NULL;
 	kfree(cdm_hw->core_info);
+	cdm_hw->core_info = NULL;
 	kfree(cdm_hw);
+	cdm_hw = NULL;
 	return rc;
 }
 
@@ -2256,9 +2340,13 @@ static void cam_hw_cdm_component_unbind(struct device *dev,
 
 	mutex_destroy(&cdm_hw->hw_mutex);
 	kfree(cdm_hw->soc_info.soc_private);
+	cdm_hw->soc_info.soc_private = NULL;
 	kfree(cdm_hw_intf);
+	cdm_hw_intf = NULL;
 	kfree(cdm_hw->core_info);
+	cdm_hw->core_info = NULL;
 	kfree(cdm_hw);
+	cdm_hw = NULL;
 }
 
 const static struct component_ops cam_hw_cdm_component_ops = {

+ 37 - 0
drivers/cam_cdm/cam_cdm_intf_api.h

@@ -10,6 +10,8 @@
 #include "cam_cdm_util.h"
 #include "cam_soc_util.h"
 
+#define CAM_CDM_BL_CMD_MAX  25
+
 /* enum cam_cdm_id - Enum for possible CAM CDM hardwares */
 enum cam_cdm_id {
 	CAM_CDM_VIRTUAL,
@@ -151,6 +153,41 @@ struct cam_cdm_bl_request {
 	struct cam_cdm_bl_cmd cmd[1];
 };
 
+/**
+ * struct cam_cdm_bl_data - last submiited CDM BL data
+ *
+ * @mem_handle : Input mem handle of bl cmd
+ * @hw_addr    : Hw address of submitted Bl command
+ * @offset     : Input offset of the actual bl cmd in the memory pointed
+ *               by mem_handle
+ * @len        : length of submitted Bl command to CDM.
+ * @input_len  : Input length of the BL command, Cannot be more than 1MB and
+ *           this is will be validated with offset+size of the memory pointed
+ *           by mem_handle
+ * @type       :  CDM bl cmd addr types.
+ */
+struct cam_cdm_bl_data {
+	int32_t mem_handle;
+	dma_addr_t hw_addr;
+	uint32_t offset;
+	size_t len;
+	uint32_t  input_len;
+	enum cam_cdm_bl_cmd_addr_type type;
+};
+
+/**
+ * struct cam_cdm_bl_info
+ *
+ * @bl_count   : No. of Bl commands submiited to CDM.
+ * @cmd        : payload holding the BL cmd's arrary
+ *               that is sumbitted.
+ *
+ */
+struct cam_cdm_bl_info {
+	int32_t bl_count;
+	struct cam_cdm_bl_data cmd[CAM_CDM_BL_CMD_MAX];
+};
+
 /**
  * @brief : API to get the CDM capabilities for a camera device type
  *

+ 66 - 12
drivers/cam_cdm/cam_cdm_util.c

@@ -689,25 +689,53 @@ int cam_cdm_util_cmd_buf_write(void __iomem **current_device_base,
 	return ret;
 }
 
-static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr)
+static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr,
+	uint32_t *cmd_buf_addr_end)
 {
 	long ret = 0;
+	struct cdm_dmi_cmd *p_dmi_cmd;
+	uint32_t *temp_ptr = cmd_buf_addr;
 
+	p_dmi_cmd = (struct cdm_dmi_cmd *)cmd_buf_addr;
+	temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
 	ret += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
-	CAM_INFO(CAM_CDM, "DMI");
+
+	if (temp_ptr > cmd_buf_addr_end)
+		CAM_ERR(CAM_CDM,
+			"Invalid cmd start addr:%pK end addr:%pK",
+			temp_ptr, cmd_buf_addr_end);
+
+	CAM_INFO(CAM_CDM,
+		"DMI: LEN: %u DMIAddr: 0x%X DMISel: 0x%X LUT_addr: 0x%X",
+		p_dmi_cmd->length, p_dmi_cmd->DMIAddr,
+		p_dmi_cmd->DMISel, p_dmi_cmd->addr);
 	return ret;
 }
 
-static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr)
+static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr,
+	uint32_t *cmd_buf_addr_end)
 {
 	long ret = 0;
+	struct cdm_indirect_cmd *p_indirect_cmd;
+	uint32_t *temp_ptr = cmd_buf_addr;
 
+	p_indirect_cmd = (struct cdm_indirect_cmd *)cmd_buf_addr;
+	temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
 	ret += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
-	CAM_INFO(CAM_CDM, "Buff Indirect");
+
+	if (temp_ptr > cmd_buf_addr_end)
+		CAM_ERR(CAM_CDM,
+			"Invalid cmd start addr:%pK end addr:%pK",
+			temp_ptr, cmd_buf_addr_end);
+
+	CAM_INFO(CAM_CDM,
+		"Buff Indirect: LEN: %u addr: 0x%X",
+		p_indirect_cmd->length, p_indirect_cmd->addr);
 	return ret;
 }
 
-static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr)
+static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr,
+	uint32_t *cmd_buf_addr_end)
 {
 	long ret = 0;
 	struct cdm_regcontinuous_cmd *p_regcont_cmd;
@@ -722,6 +750,12 @@ static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr)
 		p_regcont_cmd->count, p_regcont_cmd->offset);
 
 	for (i = 0; i < p_regcont_cmd->count; i++) {
+		if (temp_ptr > cmd_buf_addr_end) {
+			CAM_ERR(CAM_CDM,
+				"Invalid cmd(%d) start addr:%pK end addr:%pK",
+				i, temp_ptr, cmd_buf_addr_end);
+			break;
+		}
 		CAM_INFO(CAM_CDM, "DATA_%d: 0x%X", i,
 			*temp_ptr);
 		temp_ptr++;
@@ -731,7 +765,8 @@ static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr)
 	return ret;
 }
 
-static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr)
+static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr,
+	uint32_t *cmd_buf_addr_end)
 {
 	struct cdm_regrandom_cmd *p_regrand_cmd;
 	uint32_t *temp_ptr = cmd_buf_addr;
@@ -746,6 +781,12 @@ static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr)
 		p_regrand_cmd->count);
 
 	for (i = 0; i < p_regrand_cmd->count; i++) {
+		if (temp_ptr > cmd_buf_addr_end) {
+			CAM_ERR(CAM_CDM,
+				"Invalid cmd(%d) start addr:%pK end addr:%pK",
+				i, temp_ptr, cmd_buf_addr_end);
+			break;
+		}
 		CAM_INFO(CAM_CDM, "OFFSET_%d: 0x%X DATA_%d: 0x%X",
 			i, *temp_ptr & CAM_CDM_REG_OFFSET_MASK, i,
 			*(temp_ptr + 1));
@@ -778,15 +819,22 @@ static long cam_cdm_util_dump_wait_event_cmd(uint32_t *cmd_buf_addr)
 	return ret;
 }
 
-static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr)
+static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr,
+	uint32_t *cmd_buf_addr_end)
 {
 	long ret = 0;
 	struct cdm_changebase_cmd *p_cbase_cmd;
 	uint32_t *temp_ptr = cmd_buf_addr;
 
 	p_cbase_cmd = (struct cdm_changebase_cmd *)temp_ptr;
+	temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];
 	ret += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];
 
+	if (temp_ptr > cmd_buf_addr_end)
+		CAM_ERR(CAM_CDM,
+			"Invalid cmd start addr:%pK end addr:%pK",
+			temp_ptr, cmd_buf_addr_end);
+
 	CAM_INFO(CAM_CDM, "CHANGE_BASE: 0x%X",
 		p_cbase_cmd->base);
 
@@ -819,6 +867,7 @@ void cam_cdm_util_dump_cmd_buf(
 	uint32_t *cmd_buf_start, uint32_t *cmd_buf_end)
 {
 	uint32_t *buf_now = cmd_buf_start;
+	uint32_t *buf_end = cmd_buf_end;
 	uint32_t cmd = 0;
 
 	if (!cmd_buf_start || !cmd_buf_end) {
@@ -834,16 +883,20 @@ void cam_cdm_util_dump_cmd_buf(
 		case CAM_CDM_CMD_DMI:
 		case CAM_CDM_CMD_DMI_32:
 		case CAM_CDM_CMD_DMI_64:
-			buf_now += cam_cdm_util_dump_dmi_cmd(buf_now);
+			buf_now += cam_cdm_util_dump_dmi_cmd(buf_now,
+				buf_end);
 			break;
 		case CAM_CDM_CMD_REG_CONT:
-			buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now);
+			buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now,
+				buf_end);
 			break;
 		case CAM_CDM_CMD_REG_RANDOM:
-			buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now);
+			buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now,
+				buf_end);
 			break;
 		case CAM_CDM_CMD_BUFF_INDIRECT:
-			buf_now += cam_cdm_util_dump_buff_indirect(buf_now);
+			buf_now += cam_cdm_util_dump_buff_indirect(buf_now,
+				buf_end);
 			break;
 		case CAM_CDM_CMD_GEN_IRQ:
 			buf_now += cam_cdm_util_dump_gen_irq_cmd(buf_now);
@@ -852,7 +905,8 @@ void cam_cdm_util_dump_cmd_buf(
 			buf_now += cam_cdm_util_dump_wait_event_cmd(buf_now);
 			break;
 		case CAM_CDM_CMD_CHANGE_BASE:
-			buf_now += cam_cdm_util_dump_change_base_cmd(buf_now);
+			buf_now += cam_cdm_util_dump_change_base_cmd(buf_now,
+				buf_end);
 			break;
 		case CAM_CDM_CMD_PERF_CTRL:
 			buf_now += cam_cdm_util_dump_perf_ctrl_cmd(buf_now);

+ 9 - 2
drivers/cam_cdm/cam_cdm_virtual_core.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/delay.h>
@@ -19,6 +19,7 @@
 #include "cam_cdm_core_common.h"
 #include "cam_cdm_soc.h"
 #include "cam_io_util.h"
+#include "cam_req_mgr_workq.h"
 
 #define CAM_CDM_VIRTUAL_NAME "qcom,cam_virtual_cdm"
 
@@ -32,6 +33,10 @@ static void cam_virtual_cdm_work(struct work_struct *work)
 	if (payload) {
 		cdm_hw = payload->hw;
 		core = (struct cam_cdm *)cdm_hw->core_info;
+
+		cam_req_mgr_thread_switch_delay_detect(
+			payload->workq_scheduled_ts);
+
 		if (payload->irq_status & 0x2) {
 			struct cam_cdm_bl_cb_request_entry *node;
 
@@ -183,9 +188,11 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw,
 					INIT_WORK((struct work_struct *)
 						&payload->work,
 						cam_virtual_cdm_work);
+					payload->workq_scheduled_ts =
+						ktime_get();
 					queue_work(core->work_queue,
 						&payload->work);
-					}
+				}
 			}
 			core->bl_tag++;
 			CAM_DBG(CAM_CDM,

+ 1 - 1
drivers/cam_core/cam_context_utils.c

@@ -573,7 +573,7 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx,
 	req_hdl_param.media_entity_flag = 0;
 	req_hdl_param.priv = ctx;
 	req_hdl_param.ops = ctx->crm_ctx_intf;
-
+	req_hdl_param.dev_id = ctx->dev_id;
 	ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
 	if (ctx->dev_hdl <= 0) {
 		rc = -EFAULT;

+ 5 - 4
drivers/cam_core/cam_node.c

@@ -96,8 +96,9 @@ static int __cam_node_handle_acquire_dev(struct cam_node *node,
 
 	ctx = cam_node_get_ctxt_from_free_list(node);
 	if (!ctx) {
-		CAM_ERR(CAM_CORE, "No free ctx in free list node %s",
-			node->name);
+		CAM_ERR(CAM_CORE,
+			"No free ctx in free list node %s with size:%d",
+			node->name, node->ctx_size);
 		cam_node_print_ctx_state(node);
 
 		rc = -ENOMEM;
@@ -818,14 +819,14 @@ int cam_node_handle_ioctl(struct cam_node *node, struct cam_control *cmd)
 			rc = __cam_node_handle_acquire_hw_v1(node, acquire_ptr);
 			if (rc) {
 				CAM_ERR(CAM_CORE,
-					"acquire device failed(rc = %d)", rc);
+					"acquire hw failed(rc = %d)", rc);
 				goto acquire_kfree;
 			}
 		} else if (api_version == 2) {
 			rc = __cam_node_handle_acquire_hw_v2(node, acquire_ptr);
 			if (rc) {
 				CAM_ERR(CAM_CORE,
-					"acquire device failed(rc = %d)", rc);
+					"acquire hw failed(rc = %d)", rc);
 				goto acquire_kfree;
 			}
 		}

+ 20 - 19
drivers/cam_cpas/cam_cpas_hw.c

@@ -1041,7 +1041,7 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw,
 {
 	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
 	struct cam_cpas_client *cpas_client = NULL;
-	struct cam_axi_vote axi_vote = {0};
+	struct cam_axi_vote *axi_vote = NULL;
 	uint32_t client_indx = CAM_CPAS_GET_CLIENT_IDX(client_handle);
 	int rc = 0;
 
@@ -1051,16 +1051,24 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw,
 		return -EINVAL;
 	}
 
-	memcpy(&axi_vote, client_axi_vote, sizeof(struct cam_axi_vote));
-
 	if (!CAM_CPAS_CLIENT_VALID(client_indx))
 		return -EINVAL;
 
-	cam_cpas_dump_axi_vote_info(cpas_core->cpas_client[client_indx],
-		"Incoming Vote", &axi_vote);
-
 	mutex_lock(&cpas_hw->hw_mutex);
 	mutex_lock(&cpas_core->client_mutex[client_indx]);
+
+	axi_vote = kmemdup(client_axi_vote, sizeof(struct cam_axi_vote),
+		GFP_KERNEL);
+	if (!axi_vote) {
+		CAM_ERR(CAM_CPAS, "Out of memory");
+		mutex_unlock(&cpas_core->client_mutex[client_indx]);
+		mutex_unlock(&cpas_hw->hw_mutex);
+		return -ENOMEM;
+	}
+
+	cam_cpas_dump_axi_vote_info(cpas_core->cpas_client[client_indx],
+		"Incoming Vote", axi_vote);
+
 	cpas_client = cpas_core->cpas_client[client_indx];
 
 	if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) {
@@ -1071,7 +1079,7 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw,
 		goto unlock_client;
 	}
 
-	rc = cam_cpas_util_translate_client_paths(&axi_vote);
+	rc = cam_cpas_util_translate_client_paths(axi_vote);
 	if (rc) {
 		CAM_ERR(CAM_CPAS,
 			"Unable to translate per path votes rc: %d", rc);
@@ -1079,19 +1087,21 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw,
 	}
 
 	cam_cpas_dump_axi_vote_info(cpas_core->cpas_client[client_indx],
-		"Translated Vote", &axi_vote);
+		"Translated Vote", axi_vote);
 
 	/* Log an entry whenever there is an AXI update - before updating */
 	cam_cpas_update_monitor_array(cpas_hw, "CPAS AXI pre-update",
 		client_indx);
 
 	rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
-		cpas_core->cpas_client[client_indx], &axi_vote);
+		cpas_core->cpas_client[client_indx], axi_vote);
 
 	/* Log an entry whenever there is an AXI update - after updating */
 	cam_cpas_update_monitor_array(cpas_hw, "CPAS AXI post-update",
 		client_indx);
 unlock_client:
+	kzfree(axi_vote);
+	axi_vote = NULL;
 	mutex_unlock(&cpas_core->client_mutex[client_indx]);
 	mutex_unlock(&cpas_hw->hw_mutex);
 	return rc;
@@ -1194,7 +1204,7 @@ static int cam_cpas_util_apply_client_ahb_vote(struct cam_hw_info *cpas_hw,
 
 	if (cpas_core->streamon_clients) {
 		rc = cam_soc_util_set_clk_rate_level(&cpas_hw->soc_info,
-			highest_level);
+			highest_level, true);
 		if (rc) {
 			CAM_ERR(CAM_CPAS,
 				"Failed in scaling clock rate level %d for AHB",
@@ -1905,15 +1915,6 @@ static int cam_cpas_log_vote(struct cam_hw_info *cpas_hw)
 			curr_node->mnoc_ab_bw, curr_node->mnoc_ib_bw);
 	}
 
-	if (cpas_core->streamon_clients > 0) {
-		/*
-		 * Means, cpas has clocks turned on, so we can query clk freq.
-		 * Print clk frequencies that cpas enables - this will print
-		 * camcc_ahb, camcc_axi, gcc_hf, gcc_sf as well.
-		 */
-		cam_soc_util_print_clk_freq(&cpas_hw->soc_info);
-	}
-
 	cam_cpas_dump_monitor_array(cpas_core);
 
 	return 0;

+ 0 - 1
drivers/cam_cpas/cam_cpas_soc.c

@@ -933,7 +933,6 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
 		CAM_DBG(CAM_CPAS, "RPMH BCM info not available in DT, count=%d",
 			count);
 	}
-
 	return 0;
 
 cleanup_tree:

+ 22 - 0
drivers/cam_cpas/cpas_top/cam_cpastop_hw.c

@@ -29,6 +29,8 @@
 #include "cpastop_v520_100.h"
 #include "cpastop_v545_100.h"
 #include "cpastop_v570_200.h"
+#include "cpastop_v680_100.h"
+#include "cam_req_mgr_workq.h"
 
 struct cam_camnoc_info *camnoc_info;
 
@@ -175,6 +177,10 @@ static int cam_cpas_translate_camera_cpas_version_id(
 		*cam_version_id = CAM_CPAS_CAMERA_VERSION_ID_570;
 		break;
 
+	case CAM_CPAS_CAMERA_VERSION_680:
+		*cam_version_id = CAM_CPAS_CAMERA_VERSION_ID_680;
+		break;
+
 	default:
 		CAM_ERR(CAM_CPAS, "Invalid cam version %u",
 			cam_version);
@@ -566,6 +572,9 @@ static void cam_cpastop_work(struct work_struct *work)
 		return;
 	}
 
+	cam_req_mgr_thread_switch_delay_detect(
+			payload->workq_scheduled_ts);
+
 	cpas_hw = payload->hw;
 	cpas_core = (struct cam_cpas *) cpas_hw->core_info;
 	soc_info = &cpas_hw->soc_info;
@@ -665,6 +674,7 @@ static irqreturn_t cam_cpastop_handle_irq(int irq_num, void *data)
 
 	cam_cpastop_reset_irq(cpas_hw);
 
+	payload->workq_scheduled_ts = ktime_get();
 	queue_work(cpas_core->work_queue, &payload->work);
 done:
 	atomic_dec(&cpas_core->irq_count);
@@ -810,6 +820,9 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
 	case CAM_CPAS_TITAN_570_V200:
 		camnoc_info = &cam570_cpas200_camnoc_info;
 		break;
+	case CAM_CPAS_TITAN_680_V100:
+		camnoc_info = &cam680_cpas100_camnoc_info;
+		break;
 	default:
 		CAM_ERR(CAM_CPAS, "Camera Version not supported %d.%d.%d",
 			hw_caps->camera_version.major,
@@ -853,6 +866,15 @@ static int cam_cpastop_setup_qos_settings(struct cam_hw_info *cpas_hw,
 				"Invalid selection mask 0x%x for hw 0x%x",
 				selection_mask, soc_info->hw_version);
 		break;
+	case CAM_CPAS_TITAN_680_V100:
+		if ((selection_mask & CAM_CPAS_QOS_CUSTOM_SETTINGS_MASK) ||
+			(selection_mask & CAM_CPAS_QOS_DEFAULT_SETTINGS_MASK))
+			camnoc_info = &cam680_cpas100_camnoc_info;
+		else
+			CAM_ERR(CAM_CPAS,
+				"Invalid selection mask 0x%x for hw 0x%x",
+				selection_mask, soc_info->hw_version);
+		break;
 	default:
 		CAM_WARN(CAM_CPAS, "QoS selection not supported for 0x%x",
 			soc_info->hw_version);

+ 84 - 38
drivers/cam_cpas/cpas_top/cam_cpastop_hw.h

@@ -12,49 +12,65 @@
 /**
  * enum cam_camnoc_hw_irq_type - Enum for camnoc error types
  *
- * @CAM_CAMNOC_HW_IRQ_SLAVE_ERROR: Each slave port in CAMNOC (3 QSB ports and
- *                                 1 QHB port) has an error logger. The error
- *                                 observed at any slave port is logged into
- *                                 the error logger register and an IRQ is
- *                                 triggered
- * @CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_ENCODE_ERROR: Triggered if any error
- *                                                 detected in the IFE UBWC-
- *                                                 Stats encoder instance
+ * @CAM_CAMNOC_HW_IRQ_SLAVE_ERROR                  : Each slave port in CAMNOC
+ *                                                  (3 QSB ports and 1 QHB port)
+ *                                                   has an error logger. The
+ *                                                   error observed at any slave
+ *                                                   port is logged into the
+ *                                                   error logger register and
+ *                                                   an IRQ is triggered
+ * @CAM_CAMNOC_HW_IRQ_IFE_UBWC_ENCODE_ERROR        : Triggered if any error
+ *                                                   detected in the IFE UBWC
+ *                                                   encoder instance
+ * @CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_ENCODE_ERROR  : Triggered if any error
+ *                                                   detected in the IFE UBWC-
+ *                                                   Stats encoder instance
  * @CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_1_ENCODE_ERROR: Triggered if any error
- *                                                 detected in the IFE UBWC-
- *                                                 Stats 1 encoder instance
- * @CAM_CAMNOC_HW_IRQ_IFE02_UBWC_ENCODE_ERROR  : Triggered if any error
- *                                               detected in the IFE0 UBWC
- *                                               encoder instance
- * @CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR  : Triggered if any error
- *                                               detected in the IFE1 or IFE3
- *                                               UBWC encoder instance
- * @CAM_CAMNOC_HW_IRQ_IPE1_BPS_UBWC_DECODE_ERROR: Triggered if any error
- *                                                detected in the IPE1/BPS read
- *                                                path decoder instance
- * @CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR   : Triggered if any error detected
- *                                               in the IPE0 read path decoder
- *                                               instance
- * @CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR: Triggered if any error
- *                                               detected in the IPE/BPS
- *                                               UBWC decoder instance
- * @CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR: Triggered if any error
- *                                               detected in the IPE/BPS UBWC
- *                                               encoder instance
- * @CAM_CAMNOC_HW_IRQ_IFE0_UBWC_ENCODE_ERROR:    Triggered if any UBWC error
- *                                               is detected in IFE0 write path
- * @CAM_CAMNOC_HW_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR:  Triggered if any UBWC error
- *                                               is detected in IFE1 write path
- * @CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT              : Triggered when the QHS_ICP
- *                                               slave  times out after 4000
- *                                               AHB cycles
- * @CAM_CAMNOC_HW_IRQ_RESERVED1                : Reserved
- * @CAM_CAMNOC_HW_IRQ_RESERVED2                : Reserved
- * @CAM_CAMNOC_HW_IRQ_CAMNOC_TEST              : To test the IRQ logic
+ *                                                   detected in the IFE UBWC-
+ *                                                   Stats 1 encoder instance
+ * @CAM_CAMNOC_HW_IRQ_IFE02_UBWC_ENCODE_ERROR      : Triggered if any error
+ *                                                   detected in the IFE0 UBWC
+ *                                                   encoder instance
+ * @CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR      : Triggered if any error
+ *                                                   detected in the IFE1 or
+ *                                                   IFE3 UBWC encoder instance
+ * @CAM_CAMNOC_HW_IRQ_IFE0_UBWC_ENCODE_ERROR       : Triggered if any UBWC error
+ *                                                   is detected in IFE0 write
+ *                                                   path
+ * @CAM_CAMNOC_HW_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR : Triggered if any UBWC error
+ *                                                   is detected in IFE1 write
+ *                                                   path slave  times out after
+ *                                                   4000 AHB cycles
+ * @CAM_CAMNOC_HW_IRQ_IPE_UBWC_ENCODE_ERROR        : Triggered if any error
+ *                                                   detected in the IPE
+ *                                                   UBWC encoder instance
+ * @CAM_CAMNOC_HW_IRQ_BPS_UBWC_ENCODE_ERROR        : Triggered if any error
+ *                                                   detected in the BPS
+ *                                                   UBWC encoder instance
+ * @CAM_CAMNOC_HW_IRQ_IPE1_BPS_UBWC_DECODE_ERROR   : Triggered if any error
+ *                                                   detected in the IPE1/BPS
+ *                                                   read path decoder instance
+ * @CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR       : Triggered if any error
+ *                                                   detected in the IPE0 read
+ *                                                   path decoder instance
+ * @CAM_CAMNOC_HW_IRQ_IPE1_UBWC_DECODE_ERROR       : Triggered if any error
+ *                                                   detected in the IPE1 read
+ *                                                   path decoder instance
+ * @CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR    : Triggered if any error
+ *                                                   detected in the IPE/BPS
+ *                                                   UBWC decoder instance
+ * @CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR    : Triggered if any error
+ *                                                   detected in the IPE/BPS
+ *                                                   UBWC encoder instance
+ * @CAM_CAMNOC_HW_IRQ_RESERVED1                    : Reserved
+ * @CAM_CAMNOC_HW_IRQ_RESERVED2                    : Reserved
+ * @CAM_CAMNOC_HW_IRQ_CAMNOC_TEST                  : To test the IRQ logic
  */
 enum cam_camnoc_hw_irq_type {
 	CAM_CAMNOC_HW_IRQ_SLAVE_ERROR =
 		CAM_CAMNOC_IRQ_SLAVE_ERROR,
+	CAM_CAMNOC_HW_IRQ_IFE_UBWC_ENCODE_ERROR =
+		CAM_CAMNOC_IRQ_IFE_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_ENCODE_ERROR =
 		CAM_CAMNOC_IRQ_IFE_UBWC_STATS_ENCODE_ERROR,
 	CAM_CAMNOC_HW_IRQ_IFE_UBWC_STATS_1_ENCODE_ERROR =
@@ -67,10 +83,16 @@ enum cam_camnoc_hw_irq_type {
 		CAM_CAMNOC_IRQ_IFE0_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_HW_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR =
 		CAM_CAMNOC_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR,
+	CAM_CAMNOC_HW_IRQ_IPE_UBWC_ENCODE_ERROR =
+		CAM_CAMNOC_IRQ_IPE_UBWC_ENCODE_ERROR,
+	CAM_CAMNOC_HW_IRQ_BPS_UBWC_ENCODE_ERROR =
+		CAM_CAMNOC_IRQ_BPS_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_HW_IRQ_IPE1_BPS_UBWC_DECODE_ERROR =
 		CAM_CAMNOC_IRQ_IPE1_BPS_UBWC_DECODE_ERROR,
 	CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR =
 		CAM_CAMNOC_IRQ_IPE0_UBWC_DECODE_ERROR,
+	CAM_CAMNOC_HW_IRQ_IPE1_UBWC_DECODE_ERROR =
+		CAM_CAMNOC_IRQ_IPE1_UBWC_DECODE_ERROR,
 	CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR =
 		CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
 	CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR =
@@ -88,9 +110,17 @@ enum cam_camnoc_hw_irq_type {
  *         each of these ports.
  *
  * @CAM_CAMNOC_CDM: Indicates CDM HW connection to camnoc
+ * @CAM_CAMNOC_SFE_RD: Indicates read data from all SFEs to cammnoc
  * @CAM_CAMNOC_IFE02: Indicates IFE0, IFE2 HW connection to camnoc
  * @CAM_CAMNOC_IFE13: Indicates IFE1, IFE3 HW connection to camnoc
+ * @CAM_CAMNOC_IFE_LITE: Indicates all IFE lites connection to camnoc
  * @CAM_CAMNOC_IFE_LINEAR: Indicates linear data from all IFEs to cammnoc
+ * @CAM_CAMNOC_IFE_LINEAR_STATS: Indicates linear and stats data from certan
+ *         IFEs to cammnoc
+ * @CAM_CAMNOC_IFE_LINEAR_STATS_1: Indicates linear and stats data from certan
+ *         IFEs to cammnoc
+ * @CAM_CAMNOC_IFE_PDAF: Indicates pdaf data from all IFEs to cammnoc
+ * @CAM_CAMNOC_IFE_UBWC: Indicates ubwc from all IFEs to cammnoc
  * @CAM_CAMNOC_IFE_UBWC_STATS: Indicates ubwc+stats from certain IFEs to cammnoc
  * @CAM_CAMNOC_IFE_UBWC_STATS_1: Indicates ubwc+stats from certain
  *         IFEs to cammnoc
@@ -108,10 +138,14 @@ enum cam_camnoc_hw_irq_type {
  *         connection to camnoc
  * @CAM_CAMNOC_IPE_VID_DISP_WRITE: Indicates IPE's VID/DISP Wrire HW
  *         connection to camnoc
+ * @CAM_CAMNOC_IPE_WR: Indicates IPE HW's write connection to camnoc
  * @CAM_CAMNOC_IPE0_RD: Indicates IPE's Read0 HW connection to camnoc
+ * @CAM_CAMNOC_IPE1_RD: Indicates IPE's Read1 HW connection to camnoc
  * @CAM_CAMNOC_IPE1_BPS_RD: Indicates IPE's Read1 + BPS Read HW connection
  *         to camnoc
  * @CAM_CAMNOC_IPE_BPS_WR: Indicates IPE+BPS Write HW connection to camnoc
+ * @CAM_CAMNOC_BPS_WR: Indicates BPS HW's write connection to camnoc
+ * @CAM_CAMNOC_BPS_RD: Indicates BPS HW's read connection to camnoc
  * @CAM_CAMNOC_JPEG: Indicates JPEG HW connection to camnoc
  * @CAM_CAMNOC_FD: Indicates FD HW connection to camnoc
  * @CAM_CAMNOC_ICP: Indicates ICP HW connection to camnoc
@@ -122,9 +156,15 @@ enum cam_camnoc_hw_irq_type {
  */
 enum cam_camnoc_port_type {
 	CAM_CAMNOC_CDM,
+	CAM_CAMNOC_SFE_RD,
 	CAM_CAMNOC_IFE02,
 	CAM_CAMNOC_IFE13,
+	CAM_CAMNOC_IFE_LITE,
 	CAM_CAMNOC_IFE_LINEAR,
+	CAM_CAMNOC_IFE_LINEAR_STATS,
+	CAM_CAMNOC_IFE_LINEAR_STATS_1,
+	CAM_CAMNOC_IFE_PDAF,
+	CAM_CAMNOC_IFE_UBWC,
 	CAM_CAMNOC_IFE_UBWC_STATS,
 	CAM_CAMNOC_IFE_UBWC_STATS_1,
 	CAM_CAMNOC_IFE_RDI_WR,
@@ -137,9 +177,13 @@ enum cam_camnoc_port_type {
 	CAM_CAMNOC_IPE_BPS_LRME_READ,
 	CAM_CAMNOC_IPE_BPS_LRME_WRITE,
 	CAM_CAMNOC_IPE_VID_DISP_WRITE,
+	CAM_CAMNOC_IPE_WR,
 	CAM_CAMNOC_IPE0_RD,
+	CAM_CAMNOC_IPE1_RD,
 	CAM_CAMNOC_IPE1_BPS_RD,
 	CAM_CAMNOC_IPE_BPS_WR,
+	CAM_CAMNOC_BPS_WR,
+	CAM_CAMNOC_BPS_RD,
 	CAM_CAMNOC_JPEG,
 	CAM_CAMNOC_FD,
 	CAM_CAMNOC_ICP,
@@ -297,6 +341,7 @@ struct cam_camnoc_info {
  * @hw: Pointer to HW info
  * @irq_status: IRQ status value
  * @irq_data: IRQ data
+ * @workq_scheduled_ts: workqueue scheduled timestamp
  * @work: Work handle
  *
  */
@@ -304,6 +349,7 @@ struct cam_cpas_work_payload {
 	struct cam_hw_info *hw;
 	uint32_t irq_status;
 	uint32_t irq_data;
+	ktime_t workq_scheduled_ts;
 	struct work_struct work;
 };
 

+ 212 - 0
drivers/cam_cpas/cpas_top/cpastop_v570_200.h

@@ -240,6 +240,27 @@ static struct cam_camnoc_specific
 		.ubwc_ctl = {
 			.enable = false,
 		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x408, /* CDM_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x420, /* CDM_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x424, /* CDM_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_IFE_LINEAR,
@@ -285,6 +306,27 @@ static struct cam_camnoc_specific
 			 */
 			.enable = false,
 		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0xE08, /* IFE_LINEAR_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0xE20, /* IFE_LINEAR_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0xE24, /* IFE_LINEAR_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_IFE_RDI_RD,
@@ -330,6 +372,27 @@ static struct cam_camnoc_specific
 			 */
 			.enable = false,
 		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0xF08, /* IFE_RDI_RD_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0xF20, /* IFE_RDI_RD_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0xF24, /* IFE_RDI_RD_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_IFE_RDI_WR,
@@ -375,6 +438,27 @@ static struct cam_camnoc_specific
 			 */
 			.enable = false,
 		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x1808, /* IFE_RDI_WR_0_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x1820, /* IFE_RDI_WR_0_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x1824, /* IFE_RDI_WR_0_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_IFE_UBWC_STATS,
@@ -425,6 +509,29 @@ static struct cam_camnoc_specific
 			.offset = 0x1B88, /* IFE_UBWC_STATS_0_ENCCTL_LOW */
 			.value = 1,
 		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x1908, /* IFE_UBWC_STATS_0_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x1920,
+			/* IFE_UBWC_STATS_0_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x1924,
+			/* IFE_UBWC_STATS_0_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_IPE0_RD,
@@ -476,6 +583,27 @@ static struct cam_camnoc_specific
 			.offset = 0x1F08, /* IPE0_RD_DECCTL_LOW */
 			.value = 1,
 		},
+		.qosgen_mainctl = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2208, /* IPE0_RD_QOSGEN_MAINCTL */
+			.value = 0x2,
+		},
+		.qosgen_shaping_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2220, /* IPE0_RD_QOSGEN_SHAPING_LOW */
+			.value = 0x13131313,
+		},
+		.qosgen_shaping_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2224, /* IPE0_RD_QOSGEN_SHAPING_HIGH */
+			.value = 0x13131313,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_IPE1_BPS_RD,
@@ -527,6 +655,27 @@ static struct cam_camnoc_specific
 			.offset = 0x2508, /* IPE1_BPS_RD_DECCTL_LOW */
 			.value = 1,
 		},
+		.qosgen_mainctl = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2308, /* IPE1_BPS_RD_QOSGEN_MAINCTL */
+			.value = 0x2,
+		},
+		.qosgen_shaping_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2320, /* IPE1_BPS_RD_QOSGEN_SHAPING_LOW */
+			.value = 0x24242424,
+		},
+		.qosgen_shaping_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2324, /* IPE1_BPS_RD_QOSGEN_SHAPING_HIGH */
+			.value = 0x24242424,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_IPE_BPS_WR,
@@ -578,6 +727,27 @@ static struct cam_camnoc_specific
 			.offset = 0x2988, /* IPE_BPS_WR_ENCCTL_LOW */
 			.value = 1,
 		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2C08, /* IPE_BPS_WR_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2C20, /* IPE_BPS_WR_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2C24, /* IPE_BPS_WR_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_JPEG,
@@ -620,6 +790,27 @@ static struct cam_camnoc_specific
 		.ubwc_ctl = {
 			.enable = false,
 		},
+		.qosgen_mainctl = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2D08, /* JPEG_QOSGEN_MAINCTL */
+			.value = 0x2,
+		},
+		.qosgen_shaping_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2D20, /* JPEG_QOSGEN_SHAPING_LOW */
+			.value = 0x05050505,
+		},
+		.qosgen_shaping_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x2D24, /* JPEG_QOSGEN_SHAPING_HIGH */
+			.value = 0x05050505,
+		},
 	},
 	{
 		.port_type = CAM_CAMNOC_ICP,
@@ -631,6 +822,27 @@ static struct cam_camnoc_specific
 			.offset = 0x3888,
 			.value = 0x100000,
 		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3488, /* ICP_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x34A0, /* ICP_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x34A4, /* ICP_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
 	},
 };
 

+ 6 - 6
drivers/cam_cpas/cpas_top/cpastop_v580_100.h

@@ -953,25 +953,25 @@ static struct cam_camnoc_specific
 			.enable = false,
 		},
 		.qosgen_mainctl = {
-			.enable = false,
+			.enable = true,
 			.access_type = CAM_REG_TYPE_READ_WRITE,
 			.masked_value = 0,
 			.offset = 0x2D08, /* JPEG_QOSGEN_MAINCTL */
-			.value = 0x0,
+			.value = 0x2,
 		},
 		.qosgen_shaping_low = {
-			.enable = false,
+			.enable = true,
 			.access_type = CAM_REG_TYPE_READ_WRITE,
 			.masked_value = 0,
 			.offset = 0x2D20, /* JPEG_QOSGEN_SHAPING_LOW */
-			.value = 0x0,
+			.value = 0x10101010,
 		},
 		.qosgen_shaping_high = {
-			.enable = false,
+			.enable = true,
 			.access_type = CAM_REG_TYPE_READ_WRITE,
 			.masked_value = 0,
 			.offset = 0x2D24, /* JPEG_QOSGEN_SHAPING_HIGH */
-			.value = 0x0,
+			.value = 0x10101010,
 		},
 	},
 	{

+ 6 - 6
drivers/cam_cpas/cpas_top/cpastop_v580_custom.h

@@ -953,25 +953,25 @@ static struct cam_camnoc_specific
 			.enable = false,
 		},
 		.qosgen_mainctl = {
-			.enable = false,
+			.enable = true,
 			.access_type = CAM_REG_TYPE_READ_WRITE,
 			.masked_value = 0,
 			.offset = 0x2D08, /* JPEG_QOSGEN_MAINCTL */
-			.value = 0x0,
+			.value = 0x2,
 		},
 		.qosgen_shaping_low = {
-			.enable = false,
+			.enable = true,
 			.access_type = CAM_REG_TYPE_READ_WRITE,
 			.masked_value = 0,
 			.offset = 0x2D20, /* JPEG_QOSGEN_SHAPING_LOW */
-			.value = 0x0,
+			.value = 0x10101010,
 		},
 		.qosgen_shaping_high = {
-			.enable = false,
+			.enable = true,
 			.access_type = CAM_REG_TYPE_READ_WRITE,
 			.masked_value = 0,
 			.offset = 0x2D24, /* JPEG_QOSGEN_SHAPING_HIGH */
-			.value = 0x0,
+			.value = 0x10101010,
 		},
 	},
 	{

+ 1213 - 0
drivers/cam_cpas/cpas_top/cpastop_v680_100.h

@@ -0,0 +1,1213 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _CPASTOP_V680_100_H_
+#define _CPASTOP_V680_100_H_
+
+#define TEST_IRQ_ENABLE 0
+
+static struct cam_camnoc_irq_sbm cam_cpas_v680_100_irq_sbm = {
+	.sbm_enable = {
+		.access_type = CAM_REG_TYPE_READ_WRITE,
+		.enable = true,
+		.offset = 0x2240, /* CAM_NOC_SBM_FAULTINEN0_LOW */
+		.value = 0x2 |    /* SBM_FAULTINEN0_LOW_PORT1_MASK */
+			0x04 |     /* SBM_FAULTINEN0_LOW_PORT2_MASK */
+			0x08 |     /* SBM_FAULTINEN0_LOW_PORT3_MASK */
+			0x10 |    /* SBM_FAULTINEN0_LOW_PORT4_MASK */
+			0x20 |    /* SBM_FAULTINEN0_LOW_PORT5_MASK */
+			(TEST_IRQ_ENABLE ?
+			0x80 :    /* SBM_FAULTINEN0_LOW_PORT7_MASK */
+			0x0),
+	},
+	.sbm_status = {
+		.access_type = CAM_REG_TYPE_READ,
+		.enable = true,
+		.offset = 0x2248, /* CAM_NOC_SBM_FAULTINSTATUS0_LOW */
+	},
+	.sbm_clear = {
+		.access_type = CAM_REG_TYPE_WRITE,
+		.enable = true,
+		.offset = 0x2280, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
+		.value = TEST_IRQ_ENABLE ? 0x5 : 0x1,
+	}
+};
+
+static struct cam_camnoc_irq_err
+	cam_cpas_v680_100_irq_err[] = {
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
+		.enable = false,
+		.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
+		.err_enable = {
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.enable = true,
+			.offset = 0x2008, /* CAM_NOC_ERL_MAINCTL_LOW */
+			.value = 1,
+		},
+		.err_status = {
+			.access_type = CAM_REG_TYPE_READ,
+			.enable = true,
+			.offset = 0x2010, /* CAM_NOC_ERL_ERRVLD_LOW */
+		},
+		.err_clear = {
+			.access_type = CAM_REG_TYPE_WRITE,
+			.enable = true,
+			.offset = 0x2018, /* CAM_NOC_ERL_ERRCLR_LOW */
+			.value = 1,
+		},
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_IFE_UBWC_ENCODE_ERROR,
+		.enable = true,
+		.sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
+		.err_enable = {
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.enable = true,
+			.offset = 0x59A0, /* IFE_UBWC_NIU_ENCERREN_LOW */
+			.value = 0xF,
+		},
+		.err_status = {
+			.access_type = CAM_REG_TYPE_READ,
+			.enable = true,
+			.offset = 0x5990, /* IFE_UBWC_NIU_ENCERRSTATUS_LOW */
+		},
+		.err_clear = {
+			.access_type = CAM_REG_TYPE_WRITE,
+			.enable = true,
+			.offset = 0x5998, /* IFE_UBWC_NIU_ENCERRCLR_LOW */
+			.value = 0X1,
+		},
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_BPS_UBWC_ENCODE_ERROR,
+		.enable = true,
+		.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
+		.err_enable = {
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.enable = true,
+			.offset = 0x7A0, /* CAM_NOC_BPS_WR_NIU_ENCERREN_LOW */
+			.value = 0XF,
+		},
+		.err_status = {
+			.access_type = CAM_REG_TYPE_READ,
+			.enable = true,
+			.offset = 0x790, /* CAM_NOC_BPS_WR_NIU_ENCERRSTATUS_LOW */
+		},
+		.err_clear = {
+			.access_type = CAM_REG_TYPE_WRITE,
+			.enable = true,
+			.offset = 0x798, /* CAM_NOC_BPS_WR_NIU_ENCERRCLR_LOW */
+			.value = 0X1,
+		},
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_IPE0_UBWC_DECODE_ERROR,
+		.enable = true,
+		.sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
+		.err_enable = {
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.enable = true,
+			.offset = 0x5F20, /* CAM_NOC_IPE_0_RD_NIU_DECERREN_LOW */
+			.value = 0xFF,
+		},
+		.err_status = {
+			.access_type = CAM_REG_TYPE_READ,
+			.enable = true,
+			.offset = 0x5F10, /* CAM_NOC_IPE_0_RD_NIU_DECERRSTATUS_LOW */
+		},
+		.err_clear = {
+			.access_type = CAM_REG_TYPE_WRITE,
+			.enable = true,
+			.offset = 0x5F18, /* CAM_NOC_IPE_0_RD_NIU_DECERRCLR_LOW */
+			.value = 0X1,
+		},
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_IPE1_UBWC_DECODE_ERROR,
+		.enable = true,
+		.sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
+		.err_enable = {
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.enable = true,
+			.offset = 0x6520, /* CAM_NOC_IPE_1_RD_NIU_DECERREN_LOW */
+			.value = 0XFF,
+		},
+		.err_status = {
+			.access_type = CAM_REG_TYPE_READ,
+			.enable = true,
+			.offset = 0x6510, /* CAM_NOC_IPE_1_RD_NIU_DECERRSTATUS_LOW */
+		},
+		.err_clear = {
+			.access_type = CAM_REG_TYPE_WRITE,
+			.enable = true,
+			.offset = 0x6518, /* CAM_NOC_IPE_1_RD_NIU_DECERRCLR_LOW */
+			.value = 0X1,
+		},
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_IPE_UBWC_ENCODE_ERROR,
+		.enable = true,
+		.sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
+		.err_enable = {
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.enable = true,
+			.offset = 0x6BA0, /* CAM_NOC_IPE_WR_NIU_ENCERREN_LOW */
+			.value = 0XF,
+		},
+		.err_status = {
+			.access_type = CAM_REG_TYPE_READ,
+			.enable = true,
+			.offset = 0x6B90, /* CAM_NOC_IPE_WR_NIU_ENCERRSTATUS_LOW */
+		},
+		.err_clear = {
+			.access_type = CAM_REG_TYPE_WRITE,
+			.enable = true,
+			.offset = 0x6B98, /* CAM_NOC_IPE_WR_NIU_ENCERRCLR_LOW */
+			.value = 0x1,
+		},
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
+		.enable = false,
+		.sbm_port = 0x40, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
+		.err_enable = {
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.enable = true,
+			.offset = 0x2288, /* CAM_NOC_SBM_FLAGOUTSET0_LOW */
+			.value = 0x1,
+		},
+		.err_status = {
+			.access_type = CAM_REG_TYPE_READ,
+			.enable = true,
+			.offset = 0x2290, /* CAM_NOC_SBM_FLAGOUTSTATUS0_LOW */
+		},
+		.err_clear = {
+			.enable = false, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
+		},
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
+		.enable = false,
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
+		.enable = false,
+	},
+	{
+		.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
+		.enable = TEST_IRQ_ENABLE ? true : false,
+		.sbm_port = 0x80, /* SBM_FAULTINSTATUS0_LOW_PORT7_MASK */
+		.err_enable = {
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.enable = true,
+			.offset = 0x2288, /* CAM_NOC_SBM_FLAGOUTSET0_LOW */
+			.value = 0x5,
+		},
+		.err_status = {
+			.access_type = CAM_REG_TYPE_READ,
+			.enable = true,
+			.offset = 0x2290, /* CAM_NOC_SBM_FLAGOUTSTATUS0_LOW */
+		},
+		.err_clear = {
+			.enable = false, /* CAM_NOC_SBM_FLAGOUTCLR0_LOW */
+		},
+	},
+};
+
+static struct cam_camnoc_specific
+	cam_cpas_v680_100_camnoc_specific[] = {
+	{
+		.port_type = CAM_CAMNOC_IFE_UBWC,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5830, /* IFE_UBWC_PRIORITYLUT_LOW */
+			.value = 0x66665433,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5834, /* IFE_UBWC_PRIORITYLUT_HIGH */
+			.value = 0x66666666,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5838, /* IFE_UBWC_URGENCY_LOW */
+			.value = 0x1B30,
+		},
+		.danger_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5840, /* IFE_UBWC_DANGERLUT_LOW */
+			.value = 0xffffff00,
+		},
+		.safe_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5848, /* IFE_UBWC_SAFELUT_LOW */
+			.value = 0x000f,
+		},
+		.ubwc_ctl = {
+			/*
+			 * Do not explicitly set ubwc config register.
+			 * Power on default values are taking care of required
+			 * register settings.
+			 */
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5A08, /* IFE_UBWC_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5A20, /* IFE_UBWC_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5A24, /* IFE_UBWC_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_IFE_RDI_WR,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5230, /* IFE_RDI_WR_PRIORITYLUT_LOW */
+			.value = 0x66665433,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5234, /* IFE_RDI_WR_PRIORITYLUT_HIGH */
+			.value = 0x66666666,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5238, /* IFE_RDI_WR_URGENCY_LOW */
+			.value = 0x1B30,
+		},
+		.danger_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5240, /* IFE_RDI_WR_DANGERLUT_LOW */
+			.value = 0xffffff00,
+		},
+		.safe_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5248, /* IFE_RDI_WR_SAFELUT_LOW */
+			.value = 0x000f,
+		},
+		.ubwc_ctl = {
+			/*
+			 * Do not explicitly set ubwc config register.
+			 * Power on default values are taking care of required
+			 * register settings.
+			 */
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5408, /* IFE_RDI_WR_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5420, /* IFE_RDI_WR_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5424, /* IFE_RDI_WR_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_IFE_PDAF,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4c30, /* IFE_PDAF_PRIORITYLUT_LOW */
+			.value = 0x66665433,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4c34, /* IFE_PDAF_PRIORITYLUT_HIGH */
+			.value = 0x66666666,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4c38, /* IFE_PDAF_URGENCY_LOW */
+			.value = 0x1B30,
+		},
+		.danger_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4c40, /* IFE_PDAF_DANGERLUT_LOW */
+			.value = 0xffffff00,
+		},
+		.safe_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4c48, /* IFE_PDAF_SAFELUT_LOW */
+			.value = 0x000f,
+		},
+		.ubwc_ctl = {
+			/*
+			 * Do not explicitly set ubwc config register.
+			 * Power on default values are taking care of required
+			 * register settings.
+			 */
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4e08, /* IFE_PDAF_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4e20, /* IFE_PDAF_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4e24, /* IFE_PDAF_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_IFE_LINEAR_STATS,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4030, /* IFE_LINEAR_PRIORITYLUT_LOW */
+			.value = 0x66665433,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4034, /* IFE_LINEAR_PRIORITYLUT_HIGH */
+			.value = 0x66666666,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4038, /* IFE_LINEAR_URGENCY_LOW */
+			.value = 0x1B30,
+		},
+		.danger_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4040, /* IFE_LINEAR_DANGERLUT_LOW */
+			.value = 0xffffff00,
+		},
+		.safe_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4048, /* IFE_LINEAR_SAFELUT_LOW */
+			.value = 0x000f,
+		},
+		.ubwc_ctl = {
+			/*
+			 * Do not explicitly set ubwc config register.
+			 * Power on default values are taking care of required
+			 * register settings.
+			 */
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4208, /* IFE_LINEAR_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4220, /* IFE_LINEAR_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4224, /* IFE_LINEAR_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_IFE_LINEAR_STATS_1,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x8230, /* IFE_LINEAR_1_PRIORITYLUT_LOW */
+			.value = 0x66665433,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x8234, /* IFE_LINEAR_1_PRIORITYLUT_HIGH */
+			.value = 0x66666666,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x8238, /* IFE_LINEAR_1_URGENCY_LOW */
+			.value = 0x1B30,
+		},
+		.danger_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x8240, /* IFE_LINEAR_1_DANGERLUT_LOW */
+			.value = 0xffffff00,
+		},
+		.safe_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x8248, /* IFE_LINEAR_1_SAFELUT_LOW */
+			.value = 0x000f,
+		},
+		.ubwc_ctl = {
+			/*
+			 * Do not explicitly set ubwc config register.
+			 * Power on default values are taking care of required
+			 * register settings.
+			 */
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x8408, /* IFE_LINEAR_1_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x8420, /* IFE_LINEAR_1_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x8424, /* IFE_LINEAR_1_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_IFE_LITE,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4630, /* IFE_LITE_PRIORITYLUT_LOW */
+			.value = 0x66665433,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4634, /* IFE_LITE_PRIORITYLUT_HIGH */
+			.value = 0x66666666,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4638, /* IFE_LITE_URGENCY_LOW */
+			.value = 0x1B30,
+		},
+		.danger_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4640, /* IFE_LITE_DANGERLUT_LOW */
+			.value = 0xffffff00,
+		},
+		.safe_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4648, /* IFE_LITE_SAFELUT_LOW */
+			.value = 0x000f,
+		},
+		.ubwc_ctl = {
+			/*
+			 * Do not explicitly set ubwc config register.
+			 * Power on default values are taking care of required
+			 * register settings.
+			 */
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4808, /* IFE_LITE_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4820, /* IFE_LITE_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x4824, /* IFE_LITE_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_SFE_RD,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7030, /* SFE_RD_PRIORITYLUT_LOW */
+			.value = 0x0,
+		},
+		.priority_lut_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7034, /* SFE_RD_PRIORITYLUT_HIGH */
+			.value = 0x0,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7038, /* SFE_RD_URGENCY_LOW */
+			.value = 0x3,
+		},
+		.danger_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7040, /* SFE_RD_DANGERLUT_LOW */
+			.value = 0x0,
+		},
+		.safe_lut = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7048, /* SFE_RD_SAFELUT_LOW */
+			.value = 0x0,
+		},
+		.ubwc_ctl = {
+			/*
+			 * Do not explicitly set ubwc config register.
+			 * Power on default values are taking care of required
+			 * register settings.
+			 */
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7208, /* SFE_RD_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7220, /* SFE_RD_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7224, /* SFE_RD_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_IPE_WR,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6a30, /* IPE_WR_PRIORITYLUT_LOW */
+			.value = 0x33333333,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6a34, /* IPE_WR_PRIORITYLUT_HIGH */
+			.value = 0x33333333,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6a38, /* IPE_WR_URGENCY_LOW */
+			.value = 0x30,
+		},
+		.danger_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6a40, /* IPE_WR_DANGERLUT_LOW */
+			.value = 0x0,
+		},
+		.safe_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6a48, /* IPE_WR_SAFELUT_LOW */
+			.value = 0xffff,
+		},
+		.ubwc_ctl = {
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6c08, /* IPE_WR_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6c20, /* IPE_WR_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6c24, /* IPE_WR_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_BPS_WR,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x630, /* BPS_WR_PRIORITYLUT_LOW */
+			.value = 0x33333333,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x634, /* BPS_WR_PRIORITYLUT_HIGH */
+			.value = 0x33333333,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x638, /* BPS_WR_URGENCY_LOW */
+			.value = 0x30,
+		},
+		.danger_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x640, /* BPS_WR_DANGERLUT_LOW */
+			.value = 0x0,
+		},
+		.safe_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x648, /* BPS_WR_SAFELUT_LOW */
+			.value = 0xffff,
+		},
+		.ubwc_ctl = {
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x808, /* BPS_WR_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x820, /* BPS_WR_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x824, /* BPS_WR_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_BPS_RD,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x30, /* BPS_RD_PRIORITYLUT_LOW */
+			.value = 0x0,
+		},
+		.priority_lut_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x34, /* BPS_RD_PRIORITYLUT_HIGH */
+			.value = 0x0,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x38, /* BPS_RD_URGENCY_LOW */
+			.value = 0x3,
+		},
+		.danger_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x40, /* BPS_RD_DANGERLUT_LOW */
+			.value = 0x0,
+		},
+		.safe_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x48, /* BPS_RD_SAFELUT_LOW */
+			.value = 0xffff,
+		},
+		.ubwc_ctl = {
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x208, /* BPS_RD_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x220, /* BPS_RD_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x224, /* BPS_RD_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_JPEG,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7c30, /* JPEG_PRIORITYLUT_LOW */
+			.value = 0x22222222,
+		},
+		.priority_lut_high = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7c34, /* JPEG_PRIORITYLUT_HIGH */
+			.value = 0x22222222,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7c38, /* JPEG_URGENCY_LOW */
+			.value = 0x22,
+		},
+		.danger_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7c40, /* JPEG_DANGERLUT_LOW */
+			.value = 0x0,
+		},
+		.safe_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7c48, /* JPEG_SAFELUT_LOW */
+			.value = 0xffff,
+		},
+		.ubwc_ctl = {
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7e08, /* JPEG_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7e20, /* JPEG_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7e24, /* JPEG_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_IPE0_RD,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5E30, /* IPE0_RD_PRIORITYLUT_LOW */
+			.value = 0x0,
+		},
+		.priority_lut_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5E34, /* IPE0_RD_PRIORITYLUT_HIGH */
+			.value = 0x0,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5E38, /* IPE0_RD_URGENCY_LOW */
+			.value = 0x3,
+		},
+		.danger_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5E40, /* IPE0_RD_DANGERLUT_LOW */
+			.value = 0x0,
+		},
+		.safe_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5E48, /* IPE0_RD_SAFELUT_LOW */
+			.value = 0xffff,
+		},
+		.ubwc_ctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x5F08, /* IPE0_RD_DECCTL_LOW */
+			.value = 1,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6008, /* IPE0_RD_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6020, /* IPE0_RD_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6024, /* IPE0_RD_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_IPE1_RD,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6430, /* IPE1_RD_PRIORITYLUT_LOW */
+			.value = 0x0,
+		},
+		.priority_lut_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6434, /* IPE1_RD_PRIORITYLUT_HIGH */
+			.value = 0x0,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6438, /* IPE1_RD_URGENCY_LOW */
+			.value = 0x3,
+		},
+		.danger_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6440, /* IPE1_RD_DANGERLUT_LOW */
+			.value = 0x0,
+		},
+		.safe_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6448, /* IPE1_RD_SAFELUT_LOW */
+			.value = 0xffff,
+		},
+		.ubwc_ctl = {
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6608, /* IPE1_RD_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6620, /* IPE1_RD_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x6624, /* IPE1_RD_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_CDM,
+		.enable = true,
+		.priority_lut_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3830, /* CDM_PRIORITYLUT_LOW */
+			.value = 0x0,
+		},
+		.priority_lut_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3834, /* CDM_PRIORITYLUT_HIGH */
+			.value = 0x0,
+		},
+		.urgency = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3838, /* CDM_URGENCY_LOW */
+			.value = 0x3,
+		},
+		.danger_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3840, /* CDM_DANGERLUT_LOW */
+			.value = 0x0,
+		},
+		.safe_lut = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3848, /* CDM_SAFELUT_LOW */
+			.value = 0xffff,
+		},
+		.ubwc_ctl = {
+			.enable = false,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3a08, /* CDM_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3a20, /* CDM_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x3a24, /* CDM_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+	{
+		.port_type = CAM_CAMNOC_ICP,
+		.enable = true,
+		.flag_out_set0_low = {
+			.enable = true,
+			.access_type = CAM_REG_TYPE_WRITE,
+			.masked_value = 0,
+			.offset = 0x2288,
+			.value = 0x100000,
+		},
+		.qosgen_mainctl = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x7688, /* ICP_QOSGEN_MAINCTL */
+			.value = 0x0,
+		},
+		.qosgen_shaping_low = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x76A0, /* ICP_QOSGEN_SHAPING_LOW */
+			.value = 0x0,
+		},
+		.qosgen_shaping_high = {
+			.enable = false,
+			.access_type = CAM_REG_TYPE_READ_WRITE,
+			.masked_value = 0,
+			.offset = 0x76A4, /* ICP_QOSGEN_SHAPING_HIGH */
+			.value = 0x0,
+		},
+	},
+};
+
+static struct cam_camnoc_err_logger_info cam680_cpas100_err_logger_offsets = {
+	.mainctrl     =  0x2008, /* ERRLOGGER_MAINCTL_LOW */
+	.errvld       =  0x2010, /* ERRLOGGER_ERRVLD_LOW */
+	.errlog0_low  =  0x2020, /* ERRLOGGER_ERRLOG0_LOW */
+	.errlog0_high =  0x2024, /* ERRLOGGER_ERRLOG0_HIGH */
+	.errlog1_low  =  0x2028, /* ERRLOGGER_ERRLOG1_LOW */
+	.errlog1_high =  0x202c, /* ERRLOGGER_ERRLOG1_HIGH */
+	.errlog2_low  =  0x2030, /* ERRLOGGER_ERRLOG2_LOW */
+	.errlog2_high =  0x2034, /* ERRLOGGER_ERRLOG2_HIGH */
+	.errlog3_low  =  0x2038, /* ERRLOGGER_ERRLOG3_LOW */
+	.errlog3_high =  0x203c, /* ERRLOGGER_ERRLOG3_HIGH */
+};
+
+static struct cam_cpas_hw_errata_wa_list cam680_cpas100_errata_wa_list = {
+	.camnoc_flush_slave_pending_trans = {
+		.enable = false,
+		.data.reg_info = {
+			.access_type = CAM_REG_TYPE_READ,
+			.offset = 0x2300, /* sbm_SenseIn0_Low */
+			.mask = 0xE0000, /* Bits 17, 18, 19 */
+			.value = 0, /* expected to be 0 */
+		},
+	},
+};
+
+static struct cam_camnoc_info cam680_cpas100_camnoc_info = {
+	.specific = &cam_cpas_v680_100_camnoc_specific[0],
+	.specific_size = ARRAY_SIZE(cam_cpas_v680_100_camnoc_specific),
+	.irq_sbm = &cam_cpas_v680_100_irq_sbm,
+	.irq_err = &cam_cpas_v680_100_irq_err[0],
+	.irq_err_size = ARRAY_SIZE(cam_cpas_v680_100_irq_err),
+	.err_logger = &cam680_cpas100_err_logger_offsets,
+	.errata_wa_list = &cam680_cpas100_errata_wa_list,
+};
+
+#endif /* _CPASTOP_V680_100_H_ */
+

+ 18 - 0
drivers/cam_cpas/include/cam_cpas_api.h

@@ -67,6 +67,7 @@ enum cam_cpas_camera_version {
 	CAM_CPAS_CAMERA_VERSION_580  = 0x00050800,
 	CAM_CPAS_CAMERA_VERSION_545  = 0x00050405,
 	CAM_CPAS_CAMERA_VERSION_570  = 0x00050700,
+	CAM_CPAS_CAMERA_VERSION_680  = 0x00060800,
 	CAM_CPAS_CAMERA_VERSION_MAX
 };
 
@@ -98,6 +99,7 @@ enum cam_cpas_camera_version_map_id {
 	CAM_CPAS_CAMERA_VERSION_ID_540  = 0x6,
 	CAM_CPAS_CAMERA_VERSION_ID_545  = 0x7,
 	CAM_CPAS_CAMERA_VERSION_ID_570  = 0x8,
+	CAM_CPAS_CAMERA_VERSION_ID_680  = 0x9,
 	CAM_CPAS_CAMERA_VERSION_ID_MAX
 };
 
@@ -135,6 +137,7 @@ enum cam_cpas_hw_version {
 	CAM_CPAS_TITAN_520_V100 = 0x520100,
 	CAM_CPAS_TITAN_545_V100 = 0x545100,
 	CAM_CPAS_TITAN_570_V200 = 0x570200,
+	CAM_CPAS_TITAN_680_V100 = 0x680100,
 	CAM_CPAS_TITAN_MAX
 };
 
@@ -146,6 +149,8 @@ enum cam_cpas_hw_version {
  *                              observed at any slave port is logged into
  *                              the error logger register and an IRQ is
  *                              triggered
+ * @CAM_CAMNOC_IRQ_IFE_UBWC_ENCODE_ERROR      : Triggered if any error detected
+ *                                              in the IFE UBWC encoder instance
  * @CAM_CAMNOC_IRQ_IFE_UBWC_STATS_ENCODE_ERROR: Triggered if any error detected
  *                                              in the IFE UBWC-Stats encoder
  *                                              instance
@@ -159,12 +164,21 @@ enum cam_cpas_hw_version {
  * @CAM_CAMNOC_IRQ_IFE1_WR_UBWC_ENCODE_ERROR  : Triggered if any error detected
  *                                            in the IFE1 UBWC encoder
  *                                            instance
+ * @CAM_CAMNOC_IRQ_IPE_UBWC_ENCODE_ERROR    : Triggered if any error detected
+ *                                            in the IPE write path encoder
+ *                                            instance
+ * @CAM_CAMNOC_IRQ_BPS_UBWC_ENCODE_ERROR    : Triggered if any error detected
+ *                                            in the BPS write path encoder
+ *                                            instance
  * @CAM_CAMNOC_IRQ_IPE1_BPS_UBWC_DECODE_ERROR: Triggered if any error detected
  *                                             in the IPE1/BPS read path decoder
  *                                             instance
  * @CAM_CAMNOC_IRQ_IPE0_UBWC_DECODE_ERROR    : Triggered if any error detected
  *                                             in the IPE0 read path decoder
  *                                             instance
+ * @CAM_CAMNOC_IRQ_IPE1_UBWC_DECODE_ERROR    : Triggered if any error detected
+ *                                             in the IPE1 read path decoder
+ *                                             instance
  * @CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR: Triggered if any error detected
  *                                            in the IPE/BPS UBWC decoder
  *                                            instance
@@ -176,14 +190,18 @@ enum cam_cpas_hw_version {
  */
 enum cam_camnoc_irq_type {
 	CAM_CAMNOC_IRQ_SLAVE_ERROR,
+	CAM_CAMNOC_IRQ_IFE_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_IRQ_IFE_UBWC_STATS_ENCODE_ERROR,
 	CAM_CAMNOC_IRQ_IFE_UBWC_STATS_1_ENCODE_ERROR,
 	CAM_CAMNOC_IRQ_IFE02_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_IRQ_IFE13_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_IRQ_IFE0_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR,
+	CAM_CAMNOC_IRQ_IPE_UBWC_ENCODE_ERROR,
+	CAM_CAMNOC_IRQ_BPS_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_IRQ_IPE1_BPS_UBWC_DECODE_ERROR,
 	CAM_CAMNOC_IRQ_IPE0_UBWC_DECODE_ERROR,
+	CAM_CAMNOC_IRQ_IPE1_UBWC_DECODE_ERROR,
 	CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
 	CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
 	CAM_CAMNOC_IRQ_AHB_TIMEOUT,

+ 58 - 29
drivers/cam_icp/hfi.c

@@ -61,47 +61,76 @@ static void __iomem *hfi_iface_addr(struct hfi_info *hfi)
 	return IS_ERR_OR_NULL(ret) ? NULL : ret;
 }
 
+static void hfi_queue_dump(uint32_t *dwords, int count)
+{
+	int i;
+	int rows;
+	int remaining;
+
+	rows = count / 4;
+	remaining = count % 4;
+
+	for (i = 0; i < rows; i++, dwords += 4)
+		CAM_DBG(CAM_HFI,
+			"word[%04d]: 0x%08x 0x%08x 0x%08x 0x%08x",
+			i * 4, dwords[0], dwords[1], dwords[2], dwords[3]);
+
+	if (remaining == 1)
+		CAM_DBG(CAM_HFI, "word[%04d]: 0x%08x", rows * 4, dwords[0]);
+	else if (remaining == 2)
+		CAM_DBG(CAM_HFI, "word[%04d]: 0x%08x 0x%08x",
+			rows * 4, dwords[0], dwords[1]);
+	else if (remaining == 3)
+		CAM_DBG(CAM_HFI, "word[%04d]: 0x%08x 0x%08x 0x%08x",
+			rows * 4, dwords[0], dwords[1], dwords[2]);
+}
+
 void cam_hfi_queue_dump(void)
 {
+	struct hfi_mem_info *hfi_mem = &g_hfi->map;
 	struct hfi_qtbl *qtbl;
-	struct hfi_qtbl_hdr *qtbl_hdr;
-	struct hfi_q_hdr *cmd_q_hdr, *msg_q_hdr;
-	struct hfi_mem_info *hfi_mem = NULL;
-	uint32_t *read_q, *read_ptr;
-	int i;
+	struct hfi_q_hdr *q_hdr;
+	uint32_t *dwords;
+	int num_dwords;
 
-	hfi_mem = &g_hfi->map;
 	if (!hfi_mem) {
-		CAM_ERR(CAM_HFI, "Unable to dump queues hfi memory is NULL");
+		CAM_ERR(CAM_HFI, "hfi mem info NULL... unable to dump queues");
 		return;
 	}
 
 	qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva;
-	qtbl_hdr = &qtbl->q_tbl_hdr;
 	CAM_DBG(CAM_HFI,
-		"qtbl: version = %x size = %u num q = %u qhdr_size = %u",
-		qtbl_hdr->qtbl_version, qtbl_hdr->qtbl_size,
-		qtbl_hdr->qtbl_num_q, qtbl_hdr->qtbl_qhdr_size);
+		"qtbl header: version=0x%08x tbl_size=%u numq=%u qhdr_size=%u",
+		qtbl->q_tbl_hdr.qtbl_version,
+		qtbl->q_tbl_hdr.qtbl_size,
+		qtbl->q_tbl_hdr.qtbl_num_q,
+		qtbl->q_tbl_hdr.qtbl_qhdr_size);
 
-	cmd_q_hdr = &qtbl->q_hdr[Q_CMD];
-	CAM_DBG(CAM_HFI, "cmd: size = %u r_idx = %u w_idx = %u addr = %x",
-		cmd_q_hdr->qhdr_q_size, cmd_q_hdr->qhdr_read_idx,
-		cmd_q_hdr->qhdr_write_idx, hfi_mem->cmd_q.iova);
-	read_q = (uint32_t *)g_hfi->map.cmd_q.kva;
-	read_ptr = (uint32_t *)(read_q + 0);
-	CAM_DBG(CAM_HFI, "CMD Q START");
-	for (i = 0; i < ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; i++)
-		CAM_DBG(CAM_HFI, "Word: %d Data: 0x%08x ", i, read_ptr[i]);
+	q_hdr = &qtbl->q_hdr[Q_CMD];
+	CAM_DBG(CAM_HFI,
+		"cmd_q: addr=0x%08x size=%u read_idx=%u write_idx=%u",
+		hfi_mem->cmd_q.iova,
+		q_hdr->qhdr_q_size,
+		q_hdr->qhdr_read_idx,
+		q_hdr->qhdr_write_idx);
 
-	msg_q_hdr = &qtbl->q_hdr[Q_MSG];
-	CAM_DBG(CAM_HFI, "msg: size = %u r_idx = %u w_idx = %u addr = %x",
-		msg_q_hdr->qhdr_q_size, msg_q_hdr->qhdr_read_idx,
-		msg_q_hdr->qhdr_write_idx, hfi_mem->msg_q.iova);
-	read_q = (uint32_t *)g_hfi->map.msg_q.kva;
-	read_ptr = (uint32_t *)(read_q + 0);
-	CAM_DBG(CAM_HFI, "MSG Q START");
-	for (i = 0; i < ICP_MSG_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; i++)
-		CAM_DBG(CAM_HFI, "Word: %d Data: 0x%08x ", i, read_ptr[i]);
+	dwords = (uint32_t *)hfi_mem->cmd_q.kva;
+	num_dwords = ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
+
+	hfi_queue_dump(dwords, num_dwords);
+
+	q_hdr = &qtbl->q_hdr[Q_MSG];
+	CAM_DBG(CAM_HFI,
+		"msg_q: addr=0x%08x size=%u read_idx=%u write_idx=%u",
+		hfi_mem->msg_q.iova,
+		q_hdr->qhdr_q_size,
+		q_hdr->qhdr_read_idx,
+		q_hdr->qhdr_write_idx);
+
+	dwords = (uint32_t *)hfi_mem->msg_q.kva;
+	num_dwords = ICP_MSG_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT;
+
+	hfi_queue_dump(dwords, num_dwords);
 }
 
 int hfi_write_cmd(void *cmd_ptr)

+ 56 - 15
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -64,10 +64,11 @@ 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)
+	int32_t buf_handle, uint32_t size)
 {
 	uintptr_t vaddr_ptr;
 	uint32_t  *ptr;
+	uint32_t  io_size;
 	size_t    len;
 	int       rc, i;
 	char      buf[512];
@@ -80,13 +81,13 @@ static int cam_icp_dump_io_cfg(struct cam_icp_hw_ctx_data *ctx_data,
 		return rc;
 	}
 
-	len = len / sizeof(uint32_t);
+	io_size = size / sizeof(uint32_t);
 	ptr = (uint32_t *)vaddr_ptr;
-	for (i = 0; i < len; i++) {
+	for (i = 0; i < io_size; i++) {
 		used += snprintf(buf + used,
 			sizeof(buf) - used, "0X%08X-", ptr[i]);
 		if (!(i % 8)) {
-			CAM_INFO(CAM_ICP, "%s: %s", __func__, buf);
+			CAM_DBG(CAM_ICP, "%s: %s", __func__, buf);
 			used = 0;
 		}
 	}
@@ -1349,11 +1350,17 @@ static bool cam_icp_check_clk_update(struct cam_icp_hw_mgr *hw_mgr,
 	if (!clk_info->frame_cycles)
 		return cam_icp_default_clk_update(hw_mgr_clk_info);
 
-	/* Calculate base clk rate */
-	base_clk = cam_icp_mgr_calc_base_clk(
-		clk_info->frame_cycles, clk_info->budget_ns);
 	ctx_data->clk_info.rt_flag = clk_info->rt_flag;
 
+	/* Override base clock to max or calculate base clk rate */
+	if (!ctx_data->clk_info.rt_flag &&
+		(ctx_data->icp_dev_acquire_info->dev_type !=
+		CAM_ICP_RES_TYPE_BPS))
+		base_clk = ctx_data->clk_info.clk_rate[CAM_MAX_VOTE-1];
+	else
+		base_clk = cam_icp_mgr_calc_base_clk(clk_info->frame_cycles,
+				clk_info->budget_ns);
+
 	if (busy)
 		rc = cam_icp_update_clk_busy(hw_mgr, ctx_data,
 			hw_mgr_clk_info, clk_info, base_clk);
@@ -3936,8 +3943,14 @@ static int cam_icp_mgr_send_config_io(struct cam_icp_hw_ctx_data *ctx_data,
 	uint32_t size_in_words;
 
 	task = cam_req_mgr_workq_get_task(icp_hw_mgr.cmd_work);
-	if (!task)
+	if (!task) {
+		CAM_ERR_RATE_LIMIT(CAM_ICP,
+			"No free task ctx id:%d dev hdl:0x%x session hdl:0x%x dev_type:%d",
+			ctx_data->ctx_id, ctx_data->acquire_dev_cmd.dev_handle,
+			ctx_data->acquire_dev_cmd.session_handle,
+			ctx_data->icp_dev_acquire_info->dev_type);
 		return -ENOMEM;
+	}
 
 	ioconfig_cmd.size = sizeof(struct hfi_cmd_ipebps_async);
 	ioconfig_cmd.pkt_type = HFI_CMD_IPEBPS_ASYNC_COMMAND_INDIRECT;
@@ -3962,14 +3975,26 @@ static int cam_icp_mgr_send_config_io(struct cam_icp_hw_ctx_data *ctx_data,
 	CAM_DBG(CAM_ICP, "size_in_words %u", size_in_words);
 	rc = cam_req_mgr_workq_enqueue_task(task, &icp_hw_mgr,
 		CRM_TASK_PRIORITY_0);
-	if (rc)
+	if (rc) {
+		CAM_ERR_RATE_LIMIT(CAM_ICP,
+			"Enqueue task failed ctx id:%d dev hdl:0x%x session hdl:0x%x dev_type:%d",
+			ctx_data->ctx_id, ctx_data->acquire_dev_cmd.dev_handle,
+			ctx_data->acquire_dev_cmd.session_handle,
+			ctx_data->icp_dev_acquire_info->dev_type);
 		return rc;
+	}
 
 	rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete,
 		msecs_to_jiffies((timeout)));
 	if (!rem_jiffies) {
-		rc = -ETIMEDOUT;
-		CAM_ERR(CAM_ICP, "FW response timed out %d", rc);
+		/* send specific error for io config failure */
+		rc = -EREMOTEIO;
+		CAM_ERR(CAM_ICP,
+			"FW response timed out %d ctx id:%d dev hdl:0x%x session hdl:0x%x dev_type:%d",
+			rc,
+			ctx_data->ctx_id, ctx_data->acquire_dev_cmd.dev_handle,
+			ctx_data->acquire_dev_cmd.session_handle,
+			ctx_data->icp_dev_acquire_info->dev_type);
 		cam_icp_mgr_process_dbg_buf(icp_hw_mgr.icp_dbg_lvl);
 		cam_hfi_queue_dump();
 	}
@@ -5683,9 +5708,12 @@ 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_ERR_RATE_LIMIT(CAM_ICP,
+			"IO Config command failed %d size:%d",
+			rc, icp_dev_acquire_info->io_config_cmd_size);
 		cam_icp_dump_io_cfg(ctx_data,
-			icp_dev_acquire_info->io_config_cmd_handle);
+			icp_dev_acquire_info->io_config_cmd_handle,
+			icp_dev_acquire_info->io_config_cmd_size);
 		goto ioconfig_failed;
 	}
 
@@ -5703,16 +5731,29 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 	bitmap_size = BITS_TO_LONGS(CAM_FRAME_CMD_MAX) * sizeof(long);
 	ctx_data->hfi_frame_process.bitmap =
 			kzalloc(bitmap_size, GFP_KERNEL);
-	if (!ctx_data->hfi_frame_process.bitmap)
+	if (!ctx_data->hfi_frame_process.bitmap) {
+		CAM_ERR_RATE_LIMIT(CAM_ICP,
+			"hfi frame bitmap failed ctx id:%d dev hdl:0x%x session hdl:0x%x dev type %d",
+			ctx_data->ctx_id, ctx_data->acquire_dev_cmd.dev_handle,
+			ctx_data->acquire_dev_cmd.session_handle,
+			ctx_data->icp_dev_acquire_info->dev_type);
 		goto ioconfig_failed;
+	}
 
 	ctx_data->hfi_frame_process.bits = bitmap_size * BITS_PER_BYTE;
 	hw_mgr->ctx_data[ctx_id].ctxt_event_cb = args->event_cb;
 	icp_dev_acquire_info->scratch_mem_size = ctx_data->scratch_mem_size;
 
 	if (copy_to_user((void __user *)args->acquire_info,
-		icp_dev_acquire_info, sizeof(struct cam_icp_acquire_dev_info)))
+		icp_dev_acquire_info,
+		sizeof(struct cam_icp_acquire_dev_info))) {
+		CAM_ERR_RATE_LIMIT(CAM_ICP,
+			"copy from user failed ctx id:%d dev hdl:0x%x session hdl:0x%x dev type %d",
+			ctx_data->ctx_id, ctx_data->acquire_dev_cmd.dev_handle,
+			ctx_data->acquire_dev_cmd.session_handle,
+			ctx_data->icp_dev_acquire_info->dev_type);
 		goto copy_to_user_failed;
+	}
 
 	cam_icp_ctx_clk_info_init(ctx_data);
 	ctx_data->state = CAM_ICP_CTX_STATE_ACQUIRED;

+ 30 - 1
drivers/cam_isp/cam_isp_context.c

@@ -19,6 +19,7 @@
 #include "cam_cdm_util.h"
 #include "cam_isp_context.h"
 #include "cam_common_util.h"
+#include "cam_req_mgr_debug.h"
 
 static const char isp_dev_name[] = "cam-isp";
 
@@ -568,6 +569,20 @@ static const char *__cam_isp_resource_handle_id_to_type(
 		return "RDI_RD";
 	case CAM_ISP_IFE_OUT_RES_LCR:
 		return "LCR";
+	case CAM_ISP_IFE_OUT_RES_AWB_BFW:
+		return "AWB_BFW";
+	case CAM_ISP_IFE_OUT_RES_2PD_STATS:
+		return "2PD_STATS";
+	case CAM_ISP_IFE_OUT_RES_STATS_AEC_BE:
+		return "STATS_AEC_BE";
+	case CAM_ISP_IFE_OUT_RES_LTM_STATS:
+		return "LTM_STATS";
+	case CAM_ISP_IFE_OUT_RES_STATS_GTM_BHIST:
+		return "STATS_GTM_BHIST";
+	case CAM_ISP_IFE_LITE_OUT_RES_STATS_BE:
+		return "STATS_BE";
+	case CAM_ISP_IFE_LITE_OUT_RES_GAMMA:
+		return "GAMMA";
 	default:
 		return "CAM_ISP_Invalid_Resource_Type";
 	}
@@ -1832,6 +1847,12 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
 	CAM_DBG(CAM_ISP, "next Substate[%s]",
 		__cam_isp_ctx_substate_val_to_type(
 		ctx_isp->substate_activated));
+
+	cam_req_mgr_debug_delay_detect();
+	trace_cam_delay_detect("ISP",
+		"bubble epoch_in_applied", req->request_id,
+		ctx->ctx_id, ctx->link_hdl, ctx->session_hdl,
+		CAM_DEFAULT_VALUE);
 end:
 	if (request_id == 0) {
 		req = list_last_entry(&ctx->active_req_list,
@@ -2048,6 +2069,13 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
 	CAM_DBG(CAM_ISP, "next Substate[%s]",
 		__cam_isp_ctx_substate_val_to_type(
 		ctx_isp->substate_activated));
+
+	cam_req_mgr_debug_delay_detect();
+	trace_cam_delay_detect("ISP",
+		"bubble epoch_in_bubble_applied",
+		req->request_id, ctx->ctx_id,
+		ctx->link_hdl, ctx->session_hdl,
+		CAM_DEFAULT_VALUE);
 end:
 	req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request,
 		list);
@@ -4223,6 +4251,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
 	req_isp->num_fence_map_in = cfg.num_in_map_entries;
 	req_isp->num_acked = 0;
 	req_isp->bubble_detected = false;
+	req_isp->hw_update_data.packet = packet;
 
 	for (i = 0; i < req_isp->num_fence_map_out; i++) {
 		rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id);
@@ -4444,7 +4473,7 @@ get_dev_handle:
 	req_hdl_param.media_entity_flag = 0;
 	req_hdl_param.ops = ctx->crm_ctx_intf;
 	req_hdl_param.priv = ctx;
-
+	req_hdl_param.dev_id = CAM_ISP;
 	CAM_DBG(CAM_ISP, "get device handle form bridge");
 	ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
 	if (ctx->dev_hdl <= 0) {

+ 45 - 11
drivers/cam_isp/cam_isp_dev.c

@@ -96,7 +96,6 @@ static int cam_isp_dev_component_bind(struct device *dev,
 	struct cam_hw_mgr_intf         hw_mgr_intf;
 	struct cam_node               *node;
 	const char                    *compat_str = NULL;
-	uint32_t                       isp_device_type;
 	struct platform_device *pdev = to_platform_device(dev);
 
 	int iommu_hdl = -1;
@@ -109,11 +108,13 @@ static int cam_isp_dev_component_bind(struct device *dev,
 	if (strnstr(compat_str, "ife", strlen(compat_str))) {
 		rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,
 		CAM_IFE_DEVICE_TYPE);
-		isp_device_type = CAM_IFE_DEVICE_TYPE;
+		g_isp_dev.isp_device_type = CAM_IFE_DEVICE_TYPE;
+		g_isp_dev.max_context = CAM_IFE_CTX_MAX;
 	} else if (strnstr(compat_str, "tfe", strlen(compat_str))) {
 		rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,
 		CAM_TFE_DEVICE_TYPE);
-		isp_device_type = CAM_TFE_DEVICE_TYPE;
+		g_isp_dev.isp_device_type = CAM_TFE_DEVICE_TYPE;
+		g_isp_dev.max_context = CAM_TFE_CTX_MAX;
 	} else  {
 		CAM_ERR(CAM_ISP, "Invalid ISP hw type %s", compat_str);
 		rc = -EINVAL;
@@ -127,30 +128,51 @@ static int cam_isp_dev_component_bind(struct device *dev,
 	node = (struct cam_node *) g_isp_dev.sd.token;
 
 	memset(&hw_mgr_intf, 0, sizeof(hw_mgr_intf));
+	g_isp_dev.ctx = kcalloc(g_isp_dev.max_context,
+		sizeof(struct cam_context),
+		GFP_KERNEL);
+	if (!g_isp_dev.ctx) {
+		CAM_ERR(CAM_ISP,
+			"Mem Allocation failed for ISP base context");
+		goto unregister;
+	}
+
+	g_isp_dev.ctx_isp = kcalloc(g_isp_dev.max_context,
+		sizeof(struct cam_isp_context),
+		GFP_KERNEL);
+	if (!g_isp_dev.ctx_isp) {
+		CAM_ERR(CAM_ISP,
+			"Mem Allocation failed for Isp private context");
+		kfree(g_isp_dev.ctx);
+		g_isp_dev.ctx = NULL;
+		goto unregister;
+	}
+
 	rc = cam_isp_hw_mgr_init(compat_str, &hw_mgr_intf, &iommu_hdl);
 	if (rc != 0) {
 		CAM_ERR(CAM_ISP, "Can not initialized ISP HW manager!");
-		goto unregister;
+		goto kfree;
 	}
 
-	for (i = 0; i < CAM_CTX_MAX; i++) {
+	for (i = 0; i < g_isp_dev.max_context; i++) {
 		rc = cam_isp_context_init(&g_isp_dev.ctx_isp[i],
 			&g_isp_dev.ctx[i],
 			&node->crm_node_intf,
 			&node->hw_mgr_intf,
 			i,
-			isp_device_type);
+			g_isp_dev.isp_device_type);
 		if (rc) {
 			CAM_ERR(CAM_ISP, "ISP context init failed!");
-			goto unregister;
+			goto kfree;
 		}
 	}
 
-	rc = cam_node_init(node, &hw_mgr_intf, g_isp_dev.ctx, CAM_CTX_MAX,
-		CAM_ISP_DEV_NAME);
+	rc = cam_node_init(node, &hw_mgr_intf, g_isp_dev.ctx,
+			g_isp_dev.max_context, CAM_ISP_DEV_NAME);
+
 	if (rc) {
 		CAM_ERR(CAM_ISP, "ISP node init failed!");
-		goto unregister;
+		goto kfree;
 	}
 
 	cam_smmu_set_client_page_fault_handler(iommu_hdl,
@@ -161,6 +183,13 @@ static int cam_isp_dev_component_bind(struct device *dev,
 	CAM_DBG(CAM_ISP, "Component bound successfully");
 
 	return 0;
+
+kfree:
+	kfree(g_isp_dev.ctx);
+	g_isp_dev.ctx = NULL;
+	kfree(g_isp_dev.ctx_isp);
+	g_isp_dev.ctx_isp = NULL;
+
 unregister:
 	rc = cam_subdev_remove(&g_isp_dev.sd);
 err:
@@ -180,13 +209,18 @@ static void cam_isp_dev_component_unbind(struct device *dev,
 
 	cam_isp_hw_mgr_deinit(compat_str);
 	/* clean up resources */
-	for (i = 0; i < CAM_CTX_MAX; i++) {
+	for (i = 0; i < g_isp_dev.max_context; i++) {
 		rc = cam_isp_context_deinit(&g_isp_dev.ctx_isp[i]);
 		if (rc)
 			CAM_ERR(CAM_ISP, "ISP context %d deinit failed",
 				 i);
 	}
 
+	kfree(g_isp_dev.ctx);
+	g_isp_dev.ctx = NULL;
+	kfree(g_isp_dev.ctx_isp);
+	g_isp_dev.ctx_isp = NULL;
+
 	rc = cam_subdev_remove(&g_isp_dev.sd);
 	if (rc)
 		CAM_ERR(CAM_ISP, "Unregister failed rc: %d", rc);

+ 7 - 3
drivers/cam_isp/cam_isp_dev.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_ISP_DEV_H_
@@ -19,13 +19,17 @@
  * @ctx_isp:               Isp private context storage
  * @isp_mutex:             ISP dev mutex
  * @open_cnt:              Open device count
+ * @isp_device_type        ISP device type
+ * @max_context            maximum contexts for TFE is 4 and for IFE is 8
  */
 struct cam_isp_dev {
 	struct cam_subdev          sd;
-	struct cam_context         ctx[CAM_CTX_MAX];
-	struct cam_isp_context     ctx_isp[CAM_CTX_MAX];
+	struct cam_context         *ctx;
+	struct cam_isp_context     *ctx_isp;
 	struct mutex               isp_mutex;
 	int32_t                    open_cnt;
+	uint32_t                   isp_device_type;
+	int32_t                    max_context;
 };
 
 /**

File diff suppressed because it is too large
+ 357 - 271
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c


+ 5 - 6
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -17,7 +17,6 @@
 
 /* IFE resource constants */
 #define CAM_IFE_HW_IN_RES_MAX            (CAM_ISP_IFE_IN_RES_MAX & 0xFF)
-#define CAM_IFE_HW_OUT_RES_MAX           (CAM_ISP_IFE_OUT_RES_MAX & 0xFF)
 #define CAM_IFE_HW_RES_POOL_MAX          64
 
 /* IFE_HW_MGR custom config */
@@ -122,9 +121,7 @@ struct cam_ife_hw_mgr_ctx {
 	struct list_head                res_list_ife_csid;
 	struct list_head                res_list_ife_src;
 	struct list_head                res_list_ife_in_rd;
-	struct cam_isp_hw_mgr_res       res_list_ife_out[
-						CAM_IFE_HW_OUT_RES_MAX];
-
+	struct cam_isp_hw_mgr_res      *res_list_ife_out;
 	struct list_head                free_res_list;
 	struct cam_isp_hw_mgr_res       res_pool[CAM_IFE_HW_RES_POOL_MAX];
 
@@ -182,6 +179,7 @@ struct cam_ife_hw_mgr_ctx {
  * @ctx_lock               context lock
  * @support_consumed_addr  indicate whether hw supports last consumed address
  * @hw_pid_support         hw pid support for this target
+ * @max_vfe_out_res_type   max ife out res type value from hw
  */
 struct cam_ife_hw_mgr {
 	struct cam_isp_hw_mgr          mgr_common;
@@ -194,7 +192,7 @@ struct cam_ife_hw_mgr {
 	atomic_t                       active_ctx_cnt;
 	struct list_head               free_ctx_list;
 	struct list_head               used_ctx_list;
-	struct cam_ife_hw_mgr_ctx      ctx_pool[CAM_CTX_MAX];
+	struct cam_ife_hw_mgr_ctx      ctx_pool[CAM_IFE_CTX_MAX];
 
 	struct cam_ife_csid_hw_caps    ife_csid_dev_caps[
 						CAM_IFE_CSID_HW_NUM_MAX];
@@ -204,6 +202,7 @@ struct cam_ife_hw_mgr {
 	spinlock_t                     ctx_lock;
 	bool                           support_consumed_addr;
 	bool                           hw_pid_support;
+	uint32_t                       max_vfe_out_res_type;
 };
 
 /**
@@ -218,7 +217,7 @@ struct cam_ife_hw_mgr {
 struct cam_ife_hw_event_recovery_data {
 	uint32_t                   error_type;
 	uint32_t                   affected_core[CAM_ISP_HW_NUM_MAX];
-	struct cam_ife_hw_mgr_ctx *affected_ctx[CAM_CTX_MAX];
+	struct cam_ife_hw_mgr_ctx *affected_ctx[CAM_IFE_CTX_MAX];
 	uint32_t                   no_of_context;
 };
 

+ 292 - 209
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -23,9 +23,12 @@
 #include "cam_mem_mgr_api.h"
 #include "cam_common_util.h"
 #include "cam_compat.h"
+#include "cam_req_mgr_debug.h"
+#include "cam_trace.h"
 
 #define CAM_TFE_HW_ENTRIES_MAX  20
 #define CAM_TFE_HW_CONFIG_TIMEOUT 60
+#define CAM_TFE_HW_CONFIG_WAIT_MAX_TRY  3
 
 #define TZ_SVC_SMMU_PROGRAM 0x15
 #define TZ_SAFE_SYSCALL_ID  0x3
@@ -529,26 +532,30 @@ static int cam_tfe_hw_mgr_free_hw_res(
 	return 0;
 }
 
-static int cam_tfe_mgr_csid_change_halt_mode(struct list_head  *halt_list,
-	uint32_t  base_idx, enum cam_tfe_csid_halt_mode halt_mode)
+static int cam_tfe_mgr_csid_change_halt_mode(struct cam_tfe_hw_mgr_ctx *ctx,
+	enum cam_tfe_csid_halt_mode halt_mode)
 {
-	struct cam_isp_hw_mgr_res      *hw_mgr_res;
-	struct cam_isp_resource_node   *isp_res;
-	struct cam_csid_hw_halt_args    halt;
-	struct cam_hw_intf             *hw_intf;
+	struct cam_isp_hw_mgr_res        *hw_mgr_res;
+	struct cam_isp_resource_node     *isp_res;
+	struct cam_tfe_csid_hw_halt_args halt;
+	struct cam_hw_intf               *hw_intf;
 	uint32_t i;
 	int rc = 0;
 
-	list_for_each_entry(hw_mgr_res, halt_list, list) {
+	if (!ctx->is_dual)
+		return 0;
+
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
 		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (i == CAM_ISP_HW_SPLIT_LEFT)
+				continue;
+
 			if (!hw_mgr_res->hw_res[i] ||
 				(hw_mgr_res->hw_res[i]->res_state !=
 				CAM_ISP_RESOURCE_STATE_STREAMING))
 				continue;
 
 			isp_res = hw_mgr_res->hw_res[i];
-			if (isp_res->hw_intf->hw_idx != base_idx)
-				continue;
 
 			if ((isp_res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
 				(isp_res->res_id ==
@@ -560,7 +567,8 @@ static int cam_tfe_mgr_csid_change_halt_mode(struct list_head  *halt_list,
 					hw_intf->hw_priv,
 					CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
 					&halt,
-					sizeof(struct cam_csid_hw_halt_args));
+					sizeof(
+					struct cam_tfe_csid_hw_halt_args));
 				if (rc)
 					CAM_ERR(CAM_ISP, "Halt update failed");
 				break;
@@ -1497,6 +1505,8 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_rdi(
 		csid_acquire.out_port = out_port;
 		csid_acquire.sync_mode = CAM_ISP_HW_SYNC_NONE;
 		csid_acquire.node_res = NULL;
+		csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler;
+		csid_acquire.event_cb_prv = tfe_ctx;
 
 		if (tfe_ctx->is_tpg) {
 			if (tfe_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx ==
@@ -1747,16 +1757,21 @@ void cam_tfe_cam_cdm_callback(uint32_t handle, void *userdata,
 {
 	struct cam_isp_prepare_hw_update_data *hw_update_data = NULL;
 	struct cam_tfe_hw_mgr_ctx *ctx = NULL;
+	uint32_t *buf_start, *buf_end;
+	int i, rc = 0;
+	size_t len = 0;
+	uint32_t *buf_addr;
 
 	if (!userdata) {
 		CAM_ERR(CAM_ISP, "Invalid args");
 		return;
 	}
 
-	hw_update_data = (struct cam_isp_prepare_hw_update_data *)userdata;
-	ctx = (struct cam_tfe_hw_mgr_ctx *)hw_update_data->isp_mgr_ctx;
-
 	if (status == CAM_CDM_CB_STATUS_BL_SUCCESS) {
+		hw_update_data =
+			(struct cam_isp_prepare_hw_update_data *)userdata;
+		ctx =
+		(struct cam_tfe_hw_mgr_ctx *)hw_update_data->isp_mgr_ctx;
 		complete_all(&ctx->config_done_complete);
 		atomic_set(&ctx->cdm_done, 1);
 		if (g_tfe_hw_mgr.debug_cfg.per_req_reg_dump)
@@ -1768,6 +1783,40 @@ void cam_tfe_cam_cdm_callback(uint32_t handle, void *userdata,
 		CAM_DBG(CAM_ISP,
 			"Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu ctx_index=%d",
 			 handle, userdata, status, cookie, ctx->ctx_index);
+	} else if (status == CAM_CDM_CB_STATUS_PAGEFAULT ||
+		status == CAM_CDM_CB_STATUS_INVALID_BL_CMD ||
+		status == CAM_CDM_CB_STATUS_HW_ERROR) {
+		ctx = userdata;
+		CAM_INFO(CAM_ISP,
+			"req_id =%d ctx_id =%d Bl_cmd_count =%d status=%d",
+			ctx->applied_req_id, ctx->ctx_index,
+			ctx->last_submit_bl_cmd.bl_count, status);
+
+		for (i = 0; i < ctx->last_submit_bl_cmd.bl_count; i++) {
+			CAM_INFO(CAM_ISP,
+				"BL(%d) hdl=0x%x addr=0x%x len=%d input_len =%d offset=0x%x type=%d",
+				i, ctx->last_submit_bl_cmd.cmd[i].mem_handle,
+				ctx->last_submit_bl_cmd.cmd[i].hw_addr,
+				ctx->last_submit_bl_cmd.cmd[i].len,
+				ctx->last_submit_bl_cmd.cmd[i].input_len,
+				ctx->last_submit_bl_cmd.cmd[i].offset,
+				ctx->last_submit_bl_cmd.cmd[i].type);
+
+			rc = cam_packet_util_get_cmd_mem_addr(
+				ctx->last_submit_bl_cmd.cmd[i].mem_handle,
+				&buf_addr, &len);
+
+			buf_start = (uint32_t *)((uint8_t *) buf_addr +
+				ctx->last_submit_bl_cmd.cmd[i].offset);
+			buf_end = (uint32_t *)((uint8_t *) buf_start +
+				ctx->last_submit_bl_cmd.cmd[i].input_len - 1);
+
+			cam_cdm_util_dump_cmd_buf(buf_start, buf_end);
+		}
+		if (ctx->packet != NULL)
+			cam_packet_dump_patch_info(ctx->packet,
+				g_tfe_hw_mgr.mgr_common.img_iommu_hdl,
+				g_tfe_hw_mgr.mgr_common.img_iommu_hdl_secure);
 	} else {
 		CAM_WARN(CAM_ISP,
 			"Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu",
@@ -2311,7 +2360,7 @@ static int cam_isp_tfe_blob_bw_update(
 {
 	struct cam_isp_hw_mgr_res             *hw_mgr_res;
 	struct cam_hw_intf                    *hw_intf;
-	struct cam_tfe_bw_update_args          bw_upd_args;
+	struct cam_tfe_bw_update_args          *bw_upd_args = NULL;
 	int                                    rc = -EINVAL;
 	uint32_t                               i, split_idx;
 	bool                                   camif_l_bw_updated = false;
@@ -2332,32 +2381,38 @@ static int cam_isp_tfe_blob_bw_update(
 			bw_config->axi_path[i].mnoc_ib_bw);
 	}
 
+	bw_upd_args = kzalloc(sizeof(struct cam_tfe_bw_update_args),
+		GFP_KERNEL);
+	if (!bw_upd_args) {
+		CAM_ERR(CAM_ISP, "Out of memory");
+		return -ENOMEM;
+	}
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_in, list) {
 		for (split_idx = 0; split_idx < CAM_ISP_HW_SPLIT_MAX;
 			split_idx++) {
 			if (!hw_mgr_res->hw_res[split_idx])
 				continue;
 
-			memset(&bw_upd_args.isp_vote, 0,
+			memset(&bw_upd_args->isp_vote, 0,
 				sizeof(struct cam_axi_vote));
 			rc = cam_tfe_classify_vote_info(hw_mgr_res, bw_config,
-				&bw_upd_args.isp_vote, split_idx,
+				&bw_upd_args->isp_vote, split_idx,
 				&camif_l_bw_updated, &camif_r_bw_updated);
 			if (rc)
-				return rc;
+				goto end;
 
-			if (!bw_upd_args.isp_vote.num_paths)
+			if (!bw_upd_args->isp_vote.num_paths)
 				continue;
 
 			hw_intf = hw_mgr_res->hw_res[split_idx]->hw_intf;
 			if (hw_intf && hw_intf->hw_ops.process_cmd) {
-				bw_upd_args.node_res =
+				bw_upd_args->node_res =
 					hw_mgr_res->hw_res[split_idx];
 
 				rc = hw_intf->hw_ops.process_cmd(
 					hw_intf->hw_priv,
 					CAM_ISP_HW_CMD_BW_UPDATE_V2,
-					&bw_upd_args,
+					bw_upd_args,
 					sizeof(
 					struct cam_tfe_bw_update_args));
 				if (rc)
@@ -2369,6 +2424,9 @@ static int cam_isp_tfe_blob_bw_update(
 		}
 	}
 
+end:
+	kzfree(bw_upd_args);
+	bw_upd_args = NULL;
 	return rc;
 }
 
@@ -2430,21 +2488,28 @@ static int cam_tfe_mgr_config_hw(void *hw_mgr_priv,
 		"Enter ctx id:%d num_hw_upd_entries %d request id: %llu",
 		ctx->ctx_index, cfg->num_hw_update_entries, cfg->request_id);
 
-	if (cfg->num_hw_update_entries > 0) {
-		cdm_cmd                       = ctx->cdm_cmd;
-		cdm_cmd->cmd_arrary_count     = cfg->num_hw_update_entries;
-		cdm_cmd->type                 = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
-		cdm_cmd->flag                 = true;
-		cdm_cmd->userdata             = hw_update_data;
-		cdm_cmd->cookie               = cfg->request_id;
-		cdm_cmd->gen_irq_arb          = false;
-
-		for (i = 0; i < cfg->num_hw_update_entries; i++) {
-			cmd = cfg->hw_update_entries + i;
-			if (cfg->reapply && cmd->flags == CAM_ISP_IQ_BL) {
-				skip++;
-				continue;
-			}
+	if (cfg->num_hw_update_entries <= 0) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP,
+			"Enter ctx id:%d no valid hw entries:%d request id: %llu",
+			ctx->ctx_index, cfg->num_hw_update_entries,
+			cfg->request_id);
+		goto end;
+	}
+
+	cdm_cmd                       = ctx->cdm_cmd;
+	cdm_cmd->cmd_arrary_count     = cfg->num_hw_update_entries;
+	cdm_cmd->type                 = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
+	cdm_cmd->flag                 = true;
+	cdm_cmd->userdata             = hw_update_data;
+	cdm_cmd->cookie               = cfg->request_id;
+	cdm_cmd->gen_irq_arb          = false;
+
+	for (i = 0; i < cfg->num_hw_update_entries; i++) {
+		cmd = (cfg->hw_update_entries + i);
+		if (cfg->reapply && cmd->flags == CAM_ISP_IQ_BL) {
+			skip++;
+			continue;
+		}
 
 			if (cmd->flags == CAM_ISP_UNUSED_BL ||
 				cmd->flags >= CAM_ISP_BL_MAX)
@@ -2471,29 +2536,99 @@ static int cam_tfe_mgr_config_hw(void *hw_mgr_priv,
 			return rc;
 		}
 
-		if (cfg->init_packet) {
-			rc = wait_for_completion_timeout(
-				&ctx->config_done_complete,
-				msecs_to_jiffies(CAM_TFE_HW_CONFIG_TIMEOUT));
-			if (rc <= 0) {
+	ctx->packet = (struct cam_packet *)hw_update_data->packet;
+	ctx->last_submit_bl_cmd.bl_count = cdm_cmd->cmd_arrary_count;
+
+	for (i = 0; i < cdm_cmd->cmd_arrary_count; i++) {
+		if (cdm_cmd->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE) {
+			ctx->last_submit_bl_cmd.cmd[i].mem_handle =
+				cdm_cmd->cmd[i].bl_addr.mem_handle;
+
+			rc = cam_mem_get_io_buf(
+			cdm_cmd->cmd[i].bl_addr.mem_handle,
+			g_tfe_hw_mgr.mgr_common.cmd_iommu_hdl,
+			&ctx->last_submit_bl_cmd.cmd[i].hw_addr,
+			&ctx->last_submit_bl_cmd.cmd[i].len);
+		} else if (cdm_cmd->type ==
+			CAM_CDM_BL_CMD_TYPE_HW_IOVA) {
+			if (!cdm_cmd->cmd[i].bl_addr.hw_iova) {
+				CAM_ERR(CAM_CDM,
+					"Submitted Hw bl hw_iova is invalid %d:%d",
+					i, cdm_cmd->cmd_arrary_count);
+				rc = -EINVAL;
+				break;
+			}
+			rc = 0;
+			ctx->last_submit_bl_cmd.cmd[i].hw_addr =
+			(uint64_t)cdm_cmd->cmd[i].bl_addr.hw_iova;
+			ctx->last_submit_bl_cmd.cmd[i].len =
+			cdm_cmd->cmd[i].len + cdm_cmd->cmd[i].offset;
+			ctx->last_submit_bl_cmd.cmd[i].mem_handle = 0;
+		} else
+			CAM_INFO(CAM_ISP,
+				"submitted invalid bl cmd addr type :%d for Bl(%d)",
+				cdm_cmd->type, i);
+
+		ctx->last_submit_bl_cmd.cmd[i].offset =
+			cdm_cmd->cmd[i].offset;
+		ctx->last_submit_bl_cmd.cmd[i].type =
+			cdm_cmd->type;
+		ctx->last_submit_bl_cmd.cmd[i].input_len =
+		 cdm_cmd->cmd[i].len;
+	}
+
+	if (!cfg->init_packet)
+		goto end;
+
+	for (i = 0; i < CAM_TFE_HW_CONFIG_WAIT_MAX_TRY; i++) {
+		rc = wait_for_completion_timeout(
+			&ctx->config_done_complete,
+			msecs_to_jiffies(
+			CAM_TFE_HW_CONFIG_TIMEOUT));
+		if (rc <= 0) {
+			if (!cam_cdm_detect_hang_error(ctx->cdm_handle)) {
 				CAM_ERR(CAM_ISP,
-					"config done completion timeout for req_id=%llu rc=%d ctx_index %d",
+					"CDM workqueue delay detected, wait for some more time req_id=%llu rc=%d ctx_index %d",
 					cfg->request_id, rc,
 					ctx->ctx_index);
-				if (rc == 0)
-					rc = -ETIMEDOUT;
-			} else {
-				rc = 0;
-				CAM_DBG(CAM_ISP,
-					"config done Success for req_id=%llu ctx_index %d",
-					cfg->request_id,
-					ctx->ctx_index);
+				cam_req_mgr_debug_delay_detect();
+				trace_cam_delay_detect("CDM",
+					"CDM workqueue delay detected",
+					cfg->request_id, ctx->ctx_index,
+					CAM_DEFAULT_VALUE,
+					CAM_DEFAULT_VALUE, rc);
+				continue;
 			}
+
+			CAM_ERR(CAM_ISP,
+				"config done completion timeout for req_id=%llu rc=%d ctx_index %d",
+				cfg->request_id, rc,
+				ctx->ctx_index);
+
+			cam_req_mgr_debug_delay_detect();
+			trace_cam_delay_detect("ISP",
+				"config done completion timeout",
+				cfg->request_id, ctx->ctx_index,
+				CAM_DEFAULT_VALUE, CAM_DEFAULT_VALUE,
+				rc);
+
+			if (rc == 0)
+				rc = -ETIMEDOUT;
+
+			goto end;
+		} else {
+			rc = 0;
+			CAM_DBG(CAM_ISP,
+				"config done Success for req_id=%llu ctx_index %d",
+				cfg->request_id, ctx->ctx_index);
+			break;
 		}
-	} else {
-		CAM_ERR(CAM_ISP, "No commands to config");
 	}
 
+	if ((i == CAM_TFE_HW_CONFIG_WAIT_MAX_TRY) && (rc == 0))
+		rc = -ETIMEDOUT;
+
+end:
 	CAM_DBG(CAM_ISP, "Exit: Config Done: %llu",  cfg->request_id);
 
 	return rc;
@@ -2668,16 +2803,9 @@ static int cam_tfe_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
 		master_base_idx = ctx->base[0].idx;
 
 	/*Change slave mode*/
-	if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY) {
-		for (i = 0; i < ctx->num_base; i++) {
-			if (ctx->base[i].idx == master_base_idx)
-				continue;
-			cam_tfe_mgr_csid_change_halt_mode(
-				&ctx->res_list_tfe_csid,
-				ctx->base[i].idx,
-				CAM_TFE_CSID_HALT_MODE_INTERNAL);
-		}
-	}
+	if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY)
+		cam_tfe_mgr_csid_change_halt_mode(ctx,
+			CAM_TFE_CSID_HALT_MODE_INTERNAL);
 
 	CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx);
 
@@ -2716,15 +2844,15 @@ static int cam_tfe_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
 	wait_for_completion_timeout(&ctx->config_done_complete,
 		msecs_to_jiffies(5));
 
+	if (ctx->is_tpg)
+		cam_tfe_hw_mgr_stop_hw_res(&ctx->res_list_tpg);
+
 	if (stop_isp->stop_only)
 		goto end;
 
 	if (cam_cdm_stream_off(ctx->cdm_handle))
 		CAM_ERR(CAM_ISP, "CDM stream off failed %d", ctx->cdm_handle);
 
-	if (ctx->is_tpg)
-		cam_tfe_hw_mgr_stop_hw_res(&ctx->res_list_tpg);
-
 	cam_tfe_hw_mgr_deinit_hw(ctx);
 
 	CAM_DBG(CAM_ISP,
@@ -2734,6 +2862,17 @@ static int cam_tfe_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
 	atomic_dec_return(&g_tfe_hw_mgr.active_ctx_cnt);
 	mutex_unlock(&g_tfe_hw_mgr.ctx_mutex);
 
+	for (i = 0; i < ctx->last_submit_bl_cmd.bl_count; i++) {
+		ctx->last_submit_bl_cmd.cmd[i].mem_handle = 0;
+		ctx->last_submit_bl_cmd.cmd[i].hw_addr = 0;
+		ctx->last_submit_bl_cmd.cmd[i].len = 0;
+		ctx->last_submit_bl_cmd.cmd[i].offset = 0;
+		ctx->last_submit_bl_cmd.cmd[i].type = 0;
+		ctx->last_submit_bl_cmd.cmd[i].input_len = 0;
+	}
+	ctx->last_submit_bl_cmd.bl_count = 0;
+	ctx->packet = NULL;
+
 end:
 	return rc;
 }
@@ -3288,11 +3427,18 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv,
 	ctx->num_reg_dump_buf = 0;
 	ctx->res_list_tpg.res_type = CAM_ISP_RESOURCE_MAX;
 	atomic_set(&ctx->overflow_pending, 0);
-	for (i = 0; i < CAM_TFE_HW_NUM_MAX; i++) {
-		ctx->sof_cnt[i] = 0;
-		ctx->eof_cnt[i] = 0;
-		ctx->epoch_cnt[i] = 0;
+
+	for (i = 0; i < ctx->last_submit_bl_cmd.bl_count; i++) {
+		ctx->last_submit_bl_cmd.cmd[i].mem_handle = 0;
+		ctx->last_submit_bl_cmd.cmd[i].hw_addr = 0;
+		ctx->last_submit_bl_cmd.cmd[i].len = 0;
+		ctx->last_submit_bl_cmd.cmd[i].offset = 0;
+		ctx->last_submit_bl_cmd.cmd[i].type = 0;
+		ctx->last_submit_bl_cmd.cmd[i].input_len = 0;
 	}
+	ctx->last_submit_bl_cmd.bl_count = 0;
+	ctx->packet = NULL;
+
 	CAM_DBG(CAM_ISP, "Exit...ctx id:%d",
 		ctx->ctx_index);
 	cam_tfe_hw_mgr_put_ctx(&hw_mgr->free_ctx_list, &ctx);
@@ -4514,36 +4660,6 @@ outportlog:
 
 }
 
-static void cam_tfe_mgr_ctx_irq_dump(struct cam_tfe_hw_mgr_ctx *ctx)
-{
-	struct cam_isp_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_tfe_in, list) {
-		if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT)
-			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_TFE_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_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 {
 	int rc = 0;
@@ -4987,13 +5103,19 @@ static int  cam_tfe_hw_mgr_find_affected_ctx(
 			affected_core, CAM_TFE_HW_NUM_MAX))
 			continue;
 
+		if (atomic_read(&tfe_hwr_mgr_ctx->overflow_pending)) {
+			CAM_INFO(CAM_ISP, "CTX:%d already error reported",
+				tfe_hwr_mgr_ctx->ctx_index);
+			continue;
+		}
+
 		atomic_set(&tfe_hwr_mgr_ctx->overflow_pending, 1);
 		notify_err_cb = tfe_hwr_mgr_ctx->common.event_cb[event_type];
 
 		/* Add affected_context in list of recovery data */
 		CAM_DBG(CAM_ISP, "Add affected ctx %d to list",
 			tfe_hwr_mgr_ctx->ctx_index);
-		if (recovery_data->no_of_context < CAM_CTX_MAX)
+		if (recovery_data->no_of_context < CAM_TFE_CTX_MAX)
 			recovery_data->affected_ctx[
 				recovery_data->no_of_context++] =
 				tfe_hwr_mgr_ctx;
@@ -5002,8 +5124,13 @@ static int  cam_tfe_hw_mgr_find_affected_ctx(
 		 * In the call back function corresponding ISP context
 		 * will update CRM about fatal Error
 		 */
-		notify_err_cb(tfe_hwr_mgr_ctx->common.cb_priv,
+		if (notify_err_cb) {
+			notify_err_cb(tfe_hwr_mgr_ctx->common.cb_priv,
 			CAM_ISP_HW_EVENT_ERROR, error_event_data);
+		} else {
+			CAM_WARN(CAM_ISP, "Error call back is not set");
+			goto end;
+		}
 	}
 
 	/* fill the affected_core in recovery data */
@@ -5012,7 +5139,34 @@ static int  cam_tfe_hw_mgr_find_affected_ctx(
 		CAM_DBG(CAM_ISP, "tfe core %d is affected (%d)",
 			 i, recovery_data->affected_core[i]);
 	}
+end:
+	return 0;
+}
 
+static int cam_tfe_hw_mgr_handle_csid_event(
+	struct cam_isp_hw_event_info *event_info)
+{
+	struct cam_isp_hw_error_event_data  error_event_data = {0};
+	struct cam_tfe_hw_event_recovery_data     recovery_data = {0};
+
+	/* this can be extended based on the types of error
+	 * received from CSID
+	 */
+	switch (event_info->err_type) {
+	case CAM_ISP_HW_ERROR_CSID_FATAL: {
+
+		if (!g_tfe_hw_mgr.debug_cfg.enable_csid_recovery)
+			break;
+
+		error_event_data.error_type = event_info->err_type;
+		cam_tfe_hw_mgr_find_affected_ctx(&error_event_data,
+			event_info->hw_idx,
+			&recovery_data);
+		break;
+	}
+	default:
+		break;
+	}
 	return 0;
 }
 
@@ -5033,6 +5187,13 @@ static int cam_tfe_hw_mgr_handle_hw_err(
 	else if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT)
 		error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW;
 
+	spin_lock(&g_tfe_hw_mgr.ctx_lock);
+	if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) {
+		rc = cam_tfe_hw_mgr_handle_csid_event(event_info);
+		spin_unlock(&g_tfe_hw_mgr.ctx_lock);
+		return rc;
+	}
+
 	core_idx = event_info->hw_idx;
 
 	if (g_tfe_hw_mgr.debug_cfg.enable_recovery)
@@ -5042,9 +5203,13 @@ static int cam_tfe_hw_mgr_handle_hw_err(
 
 	rc = cam_tfe_hw_mgr_find_affected_ctx(&error_event_data,
 		core_idx, &recovery_data);
+	if (rc || !(recovery_data.no_of_context))
+		goto end;
 
-	if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT)
+	if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT) {
+		spin_unlock(&g_tfe_hw_mgr.ctx_lock);
 		return rc;
+	}
 
 	if (g_tfe_hw_mgr.debug_cfg.enable_recovery) {
 		/* Trigger for recovery */
@@ -5057,7 +5222,8 @@ static int cam_tfe_hw_mgr_handle_hw_err(
 		CAM_DBG(CAM_ISP, "recovery is not enabled");
 		rc = 0;
 	}
-
+end:
+	spin_unlock(&g_tfe_hw_mgr.ctx_lock);
 	return rc;
 }
 
@@ -5109,77 +5275,6 @@ static int cam_tfe_hw_mgr_handle_hw_rup(
 	return 0;
 }
 
-static int cam_tfe_hw_mgr_check_irq_for_dual_tfe(
-	struct cam_tfe_hw_mgr_ctx            *tfe_hw_mgr_ctx,
-	uint32_t                              hw_event_type)
-{
-	int32_t                               rc = -EINVAL;
-	uint32_t                             *event_cnt = NULL;
-	uint32_t                              master_hw_idx;
-	uint32_t                              slave_hw_idx;
-
-	if (!tfe_hw_mgr_ctx->is_dual)
-		return 0;
-
-	master_hw_idx = tfe_hw_mgr_ctx->master_hw_idx;
-	slave_hw_idx = tfe_hw_mgr_ctx->slave_hw_idx;
-
-	switch (hw_event_type) {
-	case CAM_ISP_HW_EVENT_SOF:
-		event_cnt = tfe_hw_mgr_ctx->sof_cnt;
-		break;
-	case CAM_ISP_HW_EVENT_EPOCH:
-		event_cnt = tfe_hw_mgr_ctx->epoch_cnt;
-		break;
-	case CAM_ISP_HW_EVENT_EOF:
-		event_cnt = tfe_hw_mgr_ctx->eof_cnt;
-		break;
-	default:
-		return 0;
-	}
-
-	if (event_cnt[master_hw_idx] == event_cnt[slave_hw_idx]) {
-
-		event_cnt[master_hw_idx] = 0;
-		event_cnt[slave_hw_idx] = 0;
-
-		return 0;
-	}
-
-	if ((event_cnt[master_hw_idx] &&
-		(event_cnt[master_hw_idx] - event_cnt[slave_hw_idx] > 1)) ||
-		(event_cnt[slave_hw_idx] &&
-		(event_cnt[slave_hw_idx] - event_cnt[master_hw_idx] > 1))) {
-
-		if (tfe_hw_mgr_ctx->dual_tfe_irq_mismatch_cnt > 10) {
-			rc = -1;
-			return rc;
-		}
-
-		CAM_ERR_RATE_LIMIT(CAM_ISP,
-			"One TFE could not generate hw event %d master id :%d slave id:%d",
-			hw_event_type, event_cnt[master_hw_idx],
-			event_cnt[slave_hw_idx]);
-		if (event_cnt[master_hw_idx] >= 2) {
-			event_cnt[master_hw_idx]--;
-			tfe_hw_mgr_ctx->dual_tfe_irq_mismatch_cnt++;
-		}
-		if (event_cnt[slave_hw_idx] >= 2) {
-			event_cnt[slave_hw_idx]--;
-			tfe_hw_mgr_ctx->dual_tfe_irq_mismatch_cnt++;
-		}
-
-		if (tfe_hw_mgr_ctx->dual_tfe_irq_mismatch_cnt == 1)
-			cam_tfe_mgr_ctx_irq_dump(tfe_hw_mgr_ctx);
-		rc = 0;
-	}
-
-	CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d",
-			hw_event_type);
-
-	return rc;
-}
-
 static int cam_tfe_hw_mgr_handle_hw_epoch(
 	void                                 *ctx,
 	void                                 *evt_info)
@@ -5188,22 +5283,16 @@ static int cam_tfe_hw_mgr_handle_hw_epoch(
 	struct cam_tfe_hw_mgr_ctx            *tfe_hw_mgr_ctx = ctx;
 	cam_hw_event_cb_func                  tfe_hw_irq_epoch_cb;
 	struct cam_isp_hw_epoch_event_data    epoch_done_event_data;
-	int                                   rc = 0;
 
 	tfe_hw_irq_epoch_cb =
 		tfe_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EPOCH];
 
 	switch (event_info->res_id) {
 	case CAM_ISP_HW_TFE_IN_CAMIF:
-		tfe_hw_mgr_ctx->epoch_cnt[event_info->hw_idx]++;
-		rc = cam_tfe_hw_mgr_check_irq_for_dual_tfe(tfe_hw_mgr_ctx,
-			CAM_ISP_HW_EVENT_EPOCH);
-		if (!rc) {
-			if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending))
-				break;
-			tfe_hw_irq_epoch_cb(tfe_hw_mgr_ctx->common.cb_priv,
-				CAM_ISP_HW_EVENT_EPOCH, &epoch_done_event_data);
-		}
+		if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending))
+			break;
+		tfe_hw_irq_epoch_cb(tfe_hw_mgr_ctx->common.cb_priv,
+			CAM_ISP_HW_EVENT_EPOCH, &epoch_done_event_data);
 		break;
 
 	case CAM_ISP_HW_TFE_IN_RDI0:
@@ -5230,27 +5319,22 @@ static int cam_tfe_hw_mgr_handle_hw_sof(
 	struct cam_tfe_hw_mgr_ctx            *tfe_hw_mgr_ctx = ctx;
 	cam_hw_event_cb_func                  tfe_hw_irq_sof_cb;
 	struct cam_isp_hw_sof_event_data      sof_done_event_data;
-	int                                   rc = 0;
 
 	tfe_hw_irq_sof_cb =
 		tfe_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_SOF];
 
 	switch (event_info->res_id) {
 	case CAM_ISP_HW_TFE_IN_CAMIF:
-		tfe_hw_mgr_ctx->sof_cnt[event_info->hw_idx]++;
-		rc = cam_tfe_hw_mgr_check_irq_for_dual_tfe(tfe_hw_mgr_ctx,
-			CAM_ISP_HW_EVENT_SOF);
-		if (!rc) {
-			cam_tfe_mgr_cmd_get_sof_timestamp(tfe_hw_mgr_ctx,
-				&sof_done_event_data.timestamp,
-				&sof_done_event_data.boot_time);
+		cam_tfe_mgr_cmd_get_sof_timestamp(tfe_hw_mgr_ctx,
+			&sof_done_event_data.timestamp,
+			&sof_done_event_data.boot_time);
 
-			if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending))
-				break;
+		if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending))
+			break;
+
+		tfe_hw_irq_sof_cb(tfe_hw_mgr_ctx->common.cb_priv,
+			CAM_ISP_HW_EVENT_SOF, &sof_done_event_data);
 
-			tfe_hw_irq_sof_cb(tfe_hw_mgr_ctx->common.cb_priv,
-				CAM_ISP_HW_EVENT_SOF, &sof_done_event_data);
-		}
 		break;
 
 	case CAM_ISP_HW_TFE_IN_RDI0:
@@ -5286,22 +5370,17 @@ static int cam_tfe_hw_mgr_handle_hw_eof(
 	struct cam_tfe_hw_mgr_ctx            *tfe_hw_mgr_ctx = ctx;
 	cam_hw_event_cb_func                  tfe_hw_irq_eof_cb;
 	struct cam_isp_hw_eof_event_data      eof_done_event_data;
-	int                                   rc = 0;
 
 	tfe_hw_irq_eof_cb =
 		tfe_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EOF];
 
 	switch (event_info->res_id) {
 	case CAM_ISP_HW_TFE_IN_CAMIF:
-		tfe_hw_mgr_ctx->eof_cnt[event_info->hw_idx]++;
-		rc = cam_tfe_hw_mgr_check_irq_for_dual_tfe(tfe_hw_mgr_ctx,
-			CAM_ISP_HW_EVENT_EOF);
-		if (!rc) {
-			if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending))
-				break;
-			tfe_hw_irq_eof_cb(tfe_hw_mgr_ctx->common.cb_priv,
-				CAM_ISP_HW_EVENT_EOF, &eof_done_event_data);
-		}
+		if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending))
+			break;
+		tfe_hw_irq_eof_cb(tfe_hw_mgr_ctx->common.cb_priv,
+			CAM_ISP_HW_EVENT_EOF, &eof_done_event_data);
+
 		break;
 
 	case CAM_ISP_HW_TFE_IN_RDI0:
@@ -5499,6 +5578,9 @@ static int cam_tfe_hw_mgr_debug_register(void)
 	dbgfileptr = debugfs_create_u32("enable_reg_dump", 0644,
 		g_tfe_hw_mgr.debug_cfg.dentry,
 		&g_tfe_hw_mgr.debug_cfg.enable_reg_dump);
+	dbgfileptr = debugfs_create_u32("enable_csid_recovery", 0644,
+		g_tfe_hw_mgr.debug_cfg.dentry,
+		&g_tfe_hw_mgr.debug_cfg.enable_csid_recovery);
 	dbgfileptr = debugfs_create_file("tfe_camif_debug", 0644,
 		g_tfe_hw_mgr.debug_cfg.dentry, NULL, &cam_tfe_camif_debug);
 	dbgfileptr = debugfs_create_u32("per_req_reg_dump", 0644,
@@ -5542,6 +5624,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 	memset(&g_tfe_hw_mgr, 0, sizeof(g_tfe_hw_mgr));
 
 	mutex_init(&g_tfe_hw_mgr.ctx_mutex);
+	spin_lock_init(&g_tfe_hw_mgr.ctx_lock);
 
 	if (CAM_TFE_HW_NUM_MAX != CAM_TFE_CSID_HW_NUM_MAX) {
 		CAM_ERR(CAM_ISP, "CSID num is different then TFE num");
@@ -5645,7 +5728,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 	}
 
 	atomic_set(&g_tfe_hw_mgr.active_ctx_cnt, 0);
-	for (i = 0; i < CAM_CTX_MAX; i++) {
+	for (i = 0; i < CAM_TFE_CTX_MAX; i++) {
 		memset(&g_tfe_hw_mgr.ctx_pool[i], 0,
 			sizeof(g_tfe_hw_mgr.ctx_pool[i]));
 		INIT_LIST_HEAD(&g_tfe_hw_mgr.ctx_pool[i].list);
@@ -5724,7 +5807,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 	return 0;
 end:
 	if (rc) {
-		for (i = 0; i < CAM_CTX_MAX; i++) {
+		for (i = 0; i < CAM_TFE_CTX_MAX; i++) {
 			cam_tasklet_deinit(
 				&g_tfe_hw_mgr.mgr_common.tasklet_pool[i]);
 			kfree(g_tfe_hw_mgr.ctx_pool[i].cdm_cmd);
@@ -5749,7 +5832,7 @@ void cam_tfe_hw_mgr_deinit(void)
 	debugfs_remove_recursive(g_tfe_hw_mgr.debug_cfg.dentry);
 	g_tfe_hw_mgr.debug_cfg.dentry = NULL;
 
-	for (i = 0; i < CAM_CTX_MAX; i++) {
+	for (i = 0; i < CAM_TFE_CTX_MAX; i++) {
 		cam_tasklet_deinit(
 			&g_tfe_hw_mgr.mgr_common.tasklet_pool[i]);
 		kfree(g_tfe_hw_mgr.ctx_pool[i].cdm_cmd);

+ 11 - 8
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h

@@ -13,6 +13,7 @@
 #include "cam_tfe_csid_hw_intf.h"
 #include "cam_top_tpg_hw_intf.h"
 #include "cam_tasklet_util.h"
+#include "cam_cdm_intf_api.h"
 
 
 
@@ -27,6 +28,7 @@
  * @dentry:                    Debugfs entry
  * @csid_debug:                csid debug information
  * @enable_recovery:           enable recovery
+ * @enable_csid_recovery:      enable csid recovery
  * @camif_debug:               enable sensor diagnosis status
  * @enable_reg_dump:           enable reg dump on error;
  * @per_req_reg_dump:          Enable per request reg dump
@@ -36,6 +38,7 @@ struct cam_tfe_hw_mgr_debug {
 	struct dentry  *dentry;
 	uint64_t       csid_debug;
 	uint32_t       enable_recovery;
+	uint32_t       enable_csid_recovery;
 	uint32_t       camif_debug;
 	uint32_t       enable_reg_dump;
 	uint32_t       per_req_reg_dump;
@@ -61,10 +64,8 @@ struct cam_tfe_hw_mgr_debug {
  * @cdm_ops                   cdm util operation pointer for building
  *                            cdm commands
  * @cdm_cmd                   cdm base and length request pointer
+ * @last_submit_bl_cmd        last submiited CDM BL command data
  * @config_done_complete      indicator for configuration complete
- * @sof_cnt                   sof count value per core, used for dual TFE
- * @epoch_cnt                 epoch count value per core, used for dual TFE
- * @eof_cnt                   eof count value per core, used for dual TFE
  * @overflow_pending          flat to specify the overflow is pending for the
  *                            context
  * @cdm_done                  flag to indicate cdm has finished writing shadow
@@ -82,6 +83,7 @@ struct cam_tfe_hw_mgr_debug {
  * @slave_hw_idx              slave hardware index in dual tfe case
  * @dual_tfe_irq_mismatch_cnt irq mismatch count value per core, used for
  *                              dual TFE
+ * packet                     CSL packet from user mode driver
  */
 struct cam_tfe_hw_mgr_ctx {
 	struct list_head                list;
@@ -105,11 +107,9 @@ struct cam_tfe_hw_mgr_ctx {
 	uint32_t                        cdm_handle;
 	struct cam_cdm_utils_ops       *cdm_ops;
 	struct cam_cdm_bl_request      *cdm_cmd;
+	struct cam_cdm_bl_info          last_submit_bl_cmd;
 	struct completion               config_done_complete;
 
-	uint32_t                        sof_cnt[CAM_TFE_HW_NUM_MAX];
-	uint32_t                        epoch_cnt[CAM_TFE_HW_NUM_MAX];
-	uint32_t                        eof_cnt[CAM_TFE_HW_NUM_MAX];
 	atomic_t                        overflow_pending;
 	atomic_t                        cdm_done;
 	uint32_t                        is_rdi_only_context;
@@ -125,6 +125,7 @@ struct cam_tfe_hw_mgr_ctx {
 	uint32_t                        master_hw_idx;
 	uint32_t                        slave_hw_idx;
 	uint32_t                        dual_tfe_irq_mismatch_cnt;
+	struct cam_packet              *packet;
 };
 
 /**
@@ -148,6 +149,7 @@ struct cam_tfe_hw_mgr_ctx {
  * @work q                 work queue for TFE hw manager
  * @debug_cfg              debug configuration
  * @support_consumed_addr  indicate whether hw supports last consumed address
+ * @ctx_lock               Spinlock for HW manager
  */
 struct cam_tfe_hw_mgr {
 	struct cam_isp_hw_mgr          mgr_common;
@@ -159,7 +161,7 @@ struct cam_tfe_hw_mgr {
 	atomic_t                       active_ctx_cnt;
 	struct list_head               free_ctx_list;
 	struct list_head               used_ctx_list;
-	struct cam_tfe_hw_mgr_ctx      ctx_pool[CAM_CTX_MAX];
+	struct cam_tfe_hw_mgr_ctx      ctx_pool[CAM_TFE_CTX_MAX];
 
 	struct cam_tfe_csid_hw_caps    tfe_csid_dev_caps[
 						CAM_TFE_CSID_HW_NUM_MAX];
@@ -167,6 +169,7 @@ struct cam_tfe_hw_mgr {
 	struct cam_req_mgr_core_workq *workq;
 	struct cam_tfe_hw_mgr_debug    debug_cfg;
 	bool                           support_consumed_addr;
+	spinlock_t                     ctx_lock;
 };
 
 /**
@@ -181,7 +184,7 @@ struct cam_tfe_hw_mgr {
 struct cam_tfe_hw_event_recovery_data {
 	uint32_t                   error_type;
 	uint32_t                   affected_core[CAM_TFE_HW_NUM_MAX];
-	struct cam_tfe_hw_mgr_ctx *affected_ctx[CAM_CTX_MAX];
+	struct cam_tfe_hw_mgr_ctx *affected_ctx[CAM_TFE_CTX_MAX];
 	uint32_t                   no_of_context;
 };
 

+ 3 - 2
drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c

@@ -132,7 +132,7 @@ static int cam_isp_update_dual_config(
 	}
 	for (i = 0; i < dual_config->num_ports; i++) {
 
-		if (i >= CAM_ISP_IFE_OUT_RES_MAX) {
+		if (i >= CAM_ISP_IFE_OUT_RES_BASE + size_isp_out) {
 			CAM_ERR(CAM_ISP,
 				"failed update for i:%d > size_isp_out:%d",
 				i, size_isp_out);
@@ -151,7 +151,8 @@ static int cam_isp_update_dual_config(
 			res = hw_mgr_res->hw_res[j];
 
 			if (res->res_id < CAM_ISP_IFE_OUT_RES_BASE ||
-				res->res_id >= CAM_ISP_IFE_OUT_RES_MAX)
+				res->res_id >= (CAM_ISP_IFE_OUT_RES_BASE +
+				size_isp_out))
 				continue;
 
 			outport_id = res->res_id & 0xFF;

+ 8 - 0
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -20,6 +20,12 @@
 #define CAM_TFE_HW_NUM_MAX   3
 #define CAM_TFE_RDI_NUM_MAX  3
 
+/* maximum context numbers for TFE */
+#define CAM_TFE_CTX_MAX      4
+
+/* maximum context numbers for IFE */
+#define CAM_IFE_CTX_MAX      8
+
 /* Appliacble vote paths for dual ife, based on no. of UAPI definitions */
 #define CAM_ISP_MAX_PER_PATH_VOTES 40
 
@@ -122,6 +128,7 @@ struct cam_isp_bw_config_internal {
  *                          is valid or not
  * @reg_dump_buf_desc:     cmd buffer descriptors for reg dump
  * @num_reg_dump_buf:      Count of descriptors in reg_dump_buf_desc
+ * @packet                 CSL packet from user mode driver
  *
  */
 struct cam_isp_prepare_hw_update_data {
@@ -137,6 +144,7 @@ struct cam_isp_prepare_hw_update_data {
 	struct cam_cmd_buf_desc               reg_dump_buf_desc[
 						CAM_REG_DUMP_MAX_BUF_ENTRIES];
 	uint32_t                              num_reg_dump_buf;
+	struct cam_packet                     *packet;
 };
 
 

+ 104 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c

@@ -689,6 +689,7 @@ int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
 	uint32_t camera_hw_version;
 	uint32_t valid_vc_dt;
 	uint32_t res_type;
+	struct cam_csid_soc_private *soc_priv;
 
 	CAM_DBG(CAM_ISP,
 		"CSID:%d res_sel:0x%x Lane type:%d lane_num:%d dt:%d vc:%d",
@@ -699,6 +700,15 @@ int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
 		cid_reserv->in_port->dt[0],
 		cid_reserv->in_port->vc[0]);
 
+	soc_priv = (struct cam_csid_soc_private *)
+		(csid_hw->hw_info->soc_info.soc_private);
+
+	if (soc_priv->is_ife_csid_lite && !cid_reserv->can_use_lite) {
+		CAM_INFO(CAM_ISP, "CSID[%u] not lite context",
+			csid_hw->hw_intf->hw_idx);
+		return -EINVAL;
+	}
+
 	if (cid_reserv->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) {
 		CAM_ERR(CAM_ISP, "CSID:%d  Invalid phy sel %d",
 			csid_hw->hw_intf->hw_idx,
@@ -2344,6 +2354,52 @@ static int cam_ife_csid_enable_pxl_path(
 	return 0;
 }
 
+
+static int cam_ife_csid_change_pxl_halt_mode(
+	struct cam_ife_csid_hw            *csid_hw,
+	struct cam_ife_csid_hw_halt_args  *csid_halt)
+{
+	uint32_t val = 0;
+	const struct cam_ife_csid_reg_offset       *csid_reg;
+	struct cam_hw_soc_info                     *soc_info;
+	const struct cam_ife_csid_pxl_reg_offset   *pxl_reg;
+	struct cam_isp_resource_node               *res;
+
+	res = csid_halt->node_res;
+
+	csid_reg = csid_hw->csid_info->csid_reg;
+	soc_info = &csid_hw->hw_info->soc_info;
+
+	if (res->res_id != CAM_IFE_PIX_PATH_RES_IPP) {
+		CAM_ERR(CAM_ISP, "CSID:%d Invalid res id %d",
+			csid_hw->hw_intf->hw_idx, res->res_id);
+		return -EINVAL;
+	}
+
+	if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
+		CAM_ERR(CAM_ISP, "CSID:%d Res:%d in invalid state:%d",
+			csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
+		return -EINVAL;
+	}
+
+	pxl_reg = csid_reg->ipp_reg;
+
+	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+		pxl_reg->csid_pxl_irq_mask_addr);
+
+	/* configure Halt for slave */
+	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+		pxl_reg->csid_pxl_ctrl_addr);
+	val &= ~0xC;
+	val |= (csid_halt->halt_mode << 2);
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+		pxl_reg->csid_pxl_ctrl_addr);
+	CAM_DBG(CAM_ISP, "CSID:%d IPP path Res halt mode:%d configured:%x",
+		csid_hw->hw_intf->hw_idx, csid_halt->halt_mode, val);
+
+	return 0;
+}
+
 static int cam_ife_csid_disable_pxl_path(
 	struct cam_ife_csid_hw          *csid_hw,
 	struct cam_isp_resource_node    *res,
@@ -3977,6 +4033,47 @@ end:
 	return rc;
 }
 
+int cam_ife_csid_halt(struct cam_ife_csid_hw *csid_hw,
+		void *halt_args)
+{
+	struct cam_isp_resource_node         *res;
+	struct cam_ife_csid_hw_halt_args     *csid_halt;
+	int rc = 0;
+
+	if (!csid_hw || !halt_args) {
+		CAM_ERR(CAM_ISP, "CSID: Invalid args");
+		return -EINVAL;
+	}
+
+	csid_halt = (struct cam_ife_csid_hw_halt_args *)halt_args;
+
+	/* Change the halt mode */
+	res = csid_halt->node_res;
+	CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d",
+		csid_hw->hw_intf->hw_idx,
+		res->res_type, res->res_id);
+
+	if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) {
+		CAM_ERR(CAM_ISP, "CSID:%d Invalid res type %d",
+			csid_hw->hw_intf->hw_idx,
+			res->res_type);
+		return -EINVAL;
+	}
+
+	switch (res->res_id) {
+	case CAM_IFE_PIX_PATH_RES_IPP:
+		rc = cam_ife_csid_change_pxl_halt_mode(csid_hw, csid_halt);
+		break;
+	default:
+		CAM_DBG(CAM_ISP, "CSID:%d res_id %d",
+			csid_hw->hw_intf->hw_idx,
+			res->res_id);
+		break;
+	}
+
+	return rc;
+}
+
 int cam_ife_csid_stop(void *hw_priv,
 	void *stop_args, uint32_t arg_size)
 {
@@ -4412,8 +4509,6 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
 	csid_hw_info = (struct cam_hw_info  *)hw_priv;
 	csid_hw = (struct cam_ife_csid_hw   *)csid_hw_info->core_info;
 
-	mutex_lock(&csid_hw->hw_info->hw_mutex);
-
 	switch (cmd_type) {
 	case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
 		rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
@@ -4450,6 +4545,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
 	case CAM_IFE_CSID_LOG_ACQUIRE_DATA:
 		rc = cam_ife_csid_log_acquire_data(csid_hw, cmd_args);
 		break;
+	case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE:
+		rc = cam_ife_csid_halt(csid_hw, cmd_args);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);
@@ -4457,8 +4555,6 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
 		break;
 	}
 
-	mutex_unlock(&csid_hw->hw_info->hw_mutex);
-
 	return rc;
 
 }
@@ -4638,6 +4734,7 @@ static int cam_csid_handle_hw_err_irq(
 			"CSID[%d] Can not get cmd for tasklet, evt_type %d",
 			csid_hw->hw_intf->hw_idx,
 			evt_type);
+		cam_csid_put_evt_payload(csid_hw, &evt_payload);
 		return rc;
 	}
 
@@ -4830,8 +4927,9 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 			fatal_err_detected = true;
 			goto handle_fatal_error;
 		}
-		if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
-			CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
+		if ((irq_status[CAM_IFE_CSID_IRQ_REG_RX] &
+			CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) &&
+			(!csid_hw->epd_supported)) {
 			CAM_ERR_RATE_LIMIT(CAM_ISP,
 				"CSID:%d CPHY_EOT_RECEPTION",
 				csid_hw->hw_intf->hw_idx);

+ 35 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h

@@ -104,6 +104,12 @@ struct cam_isp_in_port_generic_info {
 	uint32_t                        horizontal_bin;
 	uint32_t                        qcfa_bin;
 	uint32_t                        num_bytes_out;
+	uint32_t                        ipp_count;
+	uint32_t                        ppp_count;
+	uint32_t                        rdi_count;
+	uint32_t                        udi_count;
+	uint32_t                        lcr_count;
+	uint32_t                        ife_rd_count;
 	struct cam_isp_out_port_generic_info    *data;
 };
 
@@ -128,6 +134,7 @@ struct cam_isp_in_port_generic_info {
  * @priv:         private data to be sent in callback
  * @event_cb:     CSID event callback to hw manager
  * @phy_sel:      Phy selection number if tpg is enabled from userspace
+ * @can_use_lite: Flag to indicate if current call qualifies for acquire lite
  *
  */
 struct cam_csid_hw_reserve_resource_args {
@@ -144,6 +151,7 @@ struct cam_csid_hw_reserve_resource_args {
 	void                                     *priv;
 	cam_hw_mgr_event_cb_func                  event_cb;
 	uint32_t                                  phy_sel;
+	bool                                      can_use_lite;
 };
 
 /**
@@ -156,6 +164,33 @@ enum cam_ife_csid_halt_cmd {
 	CAM_CSID_HALT_MAX,
 };
 
+/**
+ *  enum cam_ife_csid_halt_mode - Specify the halt command type
+ */
+enum cam_ife_csid_halt_mode {
+	CAM_CSID_HALT_MODE_INTERNAL,
+	CAM_CSID_HALT_MODE_GLOBAL,
+	CAM_CSID_HALT_MODE_MASTER,
+	CAM_CSID_HALT_MODE_SLAVE,
+	CAM_CSID_HALT_MODE_MAX,
+};
+
+/**
+ * struct cam_ife_csid_hw_halt_args
+ * @halt_mode : Applicable only for PATH resources
+ *              0 Internal : The CSID responds to the HALT_CMD
+ *              1 Global   : The CSID responds to the GLOBAL_HALT_CMD
+ *              2 Master   : The CSID responds to the HALT_CMD
+ *              3 Slave    : The CSID responds to the external halt command
+ *                           and not the HALT_CMD register
+ * @node_res : reource pointer array( ie cid or CSID)
+ *
+ */
+struct cam_ife_csid_hw_halt_args {
+	enum cam_ife_csid_halt_mode     halt_mode;
+	struct cam_isp_resource_node   *node_res;
+};
+
 /**
  * struct cam_csid_hw_stop- stop all resources
  * @stop_cmd : Applicable only for PATH resources

+ 15 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -135,6 +135,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
 	CAM_ISP_HW_CMD_DISABLE_UBWC_COMP,
 	CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG,
+	CAM_ISP_HW_CMD_QUERY_BUS_CAP,
 	CAM_ISP_HW_CMD_MAX,
 };
 
@@ -377,4 +378,18 @@ struct cam_isp_hw_intf_data {
 	uint32_t                num_hw_pid;
 	uint32_t                hw_pid[CAM_ISP_HW_MAX_PID_VAL];
 };
+/**
+ * struct cam_isp_hw_bus_cap:
+ *
+ * @Brief:         ISP hw bus capabilities
+ *
+ * @support_consumed_addr:   Indicate whether HW has last consumed addr reg
+ * @max_vfe_out_res_type:    Maximum value of out resource type supported by hw
+ *
+ */
+struct cam_isp_hw_bus_cap {
+	bool                    support_consumed_addr;
+	uint32_t                max_vfe_out_res_type;
+};
+
 #endif /* _CAM_ISP_HW_H_ */

+ 5 - 5
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h

@@ -96,7 +96,7 @@ enum cam_tfe_csid_halt_cmd {
 };
 
 /**
- * enum cam_tfe_csid_halt_mode_cmd - Specify the halt command type
+ * enum cam_tfe_csid_halt_mode - Specify the halt command type
  */
 enum cam_tfe_csid_halt_mode {
 	CAM_TFE_CSID_HALT_MODE_INTERNAL,
@@ -107,7 +107,7 @@ enum cam_tfe_csid_halt_mode {
 };
 
 /**
- * struct cam_csid_hw_halt_args
+ * struct cam_tfe_csid_hw_halt_args
  * @halt_mode : Applicable only for PATH resources
  *              0 Internal : The CSID responds to the HALT_CMD
  *              1 Global   : The CSID responds to the GLOBAL_HALT_CMD
@@ -117,9 +117,9 @@ enum cam_tfe_csid_halt_mode {
  * @node_res : reource pointer array( ie cid or CSID)
  *
  */
-struct cam_csid_hw_halt_args {
-	enum cam_tfe_csid_halt_mode   halt_mode;
-	struct cam_isp_resource_node *node_res;
+struct cam_tfe_csid_hw_halt_args {
+	enum cam_tfe_csid_halt_mode     halt_mode;
+	struct cam_isp_resource_node   *node_res;
 };
 
 /**

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h

@@ -190,6 +190,7 @@ struct cam_vfe_hw_vfe_in_acquire_args {
  *                           with this resource.
  * @priv:                    Context data
  * @event_cb:                Callback function to hw mgr in case of hw events
+ * @buf_done_controller:     Buf done controller for isp
  * @vfe_out:                 Acquire args for VFE_OUT
  * @vfe_bus_rd               Acquire args for VFE_BUS_READ
  * @vfe_in:                  Acquire args for VFE_IN
@@ -199,6 +200,7 @@ struct cam_vfe_acquire_args {
 	void                                *tasklet;
 	void                                *priv;
 	cam_hw_mgr_event_cb_func             event_cb;
+	void                                *buf_done_controller;
 	union {
 		struct cam_vfe_hw_vfe_out_acquire_args     vfe_out;
 		struct cam_vfe_hw_vfe_bus_rd_acquire_args  vfe_bus_rd;

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.h

@@ -165,6 +165,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
 	.csi2_rx_phy_num_mask                         = 0x7,
 	.csi2_rx_long_pkt_hdr_rst_stb_shift           = 0x1,
 	.csi2_rx_short_pkt_hdr_rst_stb_shift          = 0x2,
+	.csi2_rx_cphy_pkt_hdr_rst_stb_shift           = 0x3,
 };
 
 static struct cam_tfe_csid_common_reg_offset

+ 293 - 61
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c

@@ -18,6 +18,7 @@
 #include "cam_cpas_api.h"
 #include "cam_isp_hw_mgr_intf.h"
 #include "cam_subdev.h"
+#include "cam_tasklet_util.h"
 
 /* Timeout value in msec */
 #define TFE_CSID_TIMEOUT                               1000
@@ -869,6 +870,7 @@ static int cam_tfe_csid_enable_hw(struct cam_tfe_csid_hw  *csid_hw)
 	const struct cam_tfe_csid_reg_offset      *csid_reg;
 	struct cam_hw_soc_info              *soc_info;
 	uint32_t i, val, clk_lvl;
+	unsigned long flags;
 
 	csid_reg = csid_hw->csid_info->csid_reg;
 	soc_info = &csid_hw->hw_info->soc_info;
@@ -941,6 +943,12 @@ static int cam_tfe_csid_enable_hw(struct cam_tfe_csid_hw  *csid_hw)
 	if (rc)
 		goto disable_soc;
 
+	spin_lock_irqsave(&csid_hw->spin_lock, flags);
+	csid_hw->fatal_err_detected = false;
+	csid_hw->device_enabled = 1;
+	spin_unlock_irqrestore(&csid_hw->spin_lock, flags);
+	cam_tasklet_start(csid_hw->tasklet);
+
 	return rc;
 
 disable_soc:
@@ -994,6 +1002,7 @@ static int cam_tfe_csid_disable_hw(struct cam_tfe_csid_hw *csid_hw)
 		CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
 			csid_hw->hw_intf->hw_idx);
 
+	cam_tasklet_stop(csid_hw->tasklet);
 	spin_lock_irqsave(&csid_hw->spin_lock, flags);
 	csid_hw->device_enabled = 0;
 	spin_unlock_irqrestore(&csid_hw->spin_lock, flags);
@@ -1248,48 +1257,34 @@ static int cam_tfe_csid_enable_pxl_path(
 	return 0;
 }
 
-static void cam_tfe_csid_change_pxl_halt_mode(
-	struct cam_tfe_csid_hw          *csid_hw,
-	struct cam_isp_resource_node    *res,
-	enum cam_tfe_csid_halt_mode      halt_mode)
+static int cam_tfe_csid_change_pxl_halt_mode(
+	struct cam_tfe_csid_hw            *csid_hw,
+	struct cam_tfe_csid_hw_halt_args  *csid_halt)
 {
 	uint32_t val = 0;
 	const struct cam_tfe_csid_reg_offset       *csid_reg;
 	struct cam_hw_soc_info                     *soc_info;
-	struct cam_tfe_csid_path_cfg               *path_data;
 	const struct cam_tfe_csid_pxl_reg_offset   *pxl_reg;
-	bool                                        is_ipp;
+	struct cam_isp_resource_node               *res;
+
+	res = csid_halt->node_res;
 
-	path_data = (struct cam_tfe_csid_path_cfg *) res->res_priv;
 	csid_reg = csid_hw->csid_info->csid_reg;
 	soc_info = &csid_hw->hw_info->soc_info;
 
-	if (res->res_id >= CAM_TFE_CSID_PATH_RES_MAX) {
-		CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d",
+	if (res->res_id != CAM_TFE_CSID_PATH_RES_IPP) {
+		CAM_ERR(CAM_ISP, "CSID:%d Invalid res id %d",
 			csid_hw->hw_intf->hw_idx, res->res_id);
-		goto end;
+		return -EINVAL;
 	}
 
-	if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
-		res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
-		CAM_ERR(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
+	if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
+		CAM_ERR(CAM_ISP, "CSID:%d Res:%d in invalid state:%d",
 			csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
-		goto end;
-	}
-
-	if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) {
-		is_ipp = true;
-		pxl_reg = csid_reg->ipp_reg;
-	} else {
-		goto end;
+		return -EINVAL;
 	}
 
-	if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
-		CAM_ERR(CAM_ISP, "CSID:%d %s path Res:%d Invalid state%d",
-			csid_hw->hw_intf->hw_idx, "IPP",
-			res->res_id, res->res_state);
-		goto end;
-	}
+	pxl_reg = csid_reg->ipp_reg;
 
 	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_irq_mask_addr);
@@ -1298,11 +1293,13 @@ static void cam_tfe_csid_change_pxl_halt_mode(
 	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_ctrl_addr);
 	val &= ~0xC;
-	val |= (halt_mode << 2);
+	val |= (csid_halt->halt_mode << 2);
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_ctrl_addr);
-end:
-	return;
+	CAM_DBG(CAM_ISP, "CSID:%d IPP path Res halt mode:%d configured:%x",
+		csid_hw->hw_intf->hw_idx, csid_halt->halt_mode, val);
+
+	return 0;
 }
 
 static int cam_tfe_csid_disable_pxl_path(
@@ -1933,6 +1930,9 @@ static int cam_tfe_csid_release(void *hw_priv,
 		goto end;
 	}
 
+	csid_hw->event_cb = NULL;
+	csid_hw->event_cb_priv = NULL;
+
 	if ((res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) ||
 		(res->res_state >= CAM_ISP_RESOURCE_STATE_STREAMING)) {
 		CAM_WARN(CAM_ISP,
@@ -2199,14 +2199,15 @@ int cam_tfe_csid_halt(struct cam_tfe_csid_hw *csid_hw,
 	void *halt_args)
 {
 	struct cam_isp_resource_node         *res;
-	struct cam_csid_hw_halt_args         *csid_halt;
+	struct cam_tfe_csid_hw_halt_args     *csid_halt;
+	int rc = 0;
 
 	if (!csid_hw || !halt_args) {
 		CAM_ERR(CAM_ISP, "CSID: Invalid args");
 		return -EINVAL;
 	}
 
-	csid_halt = (struct cam_csid_hw_halt_args *)halt_args;
+	csid_halt = (struct cam_tfe_csid_hw_halt_args *)halt_args;
 
 	/* Change the halt mode */
 	res = csid_halt->node_res;
@@ -2214,20 +2215,25 @@ int cam_tfe_csid_halt(struct cam_tfe_csid_hw *csid_hw,
 		csid_hw->hw_intf->hw_idx,
 		res->res_type, res->res_id);
 
-	switch (res->res_type) {
-	case CAM_ISP_RESOURCE_PIX_PATH:
-		if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP)
-			cam_tfe_csid_change_pxl_halt_mode(csid_hw, res,
-				csid_halt->halt_mode);
+	if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) {
+		CAM_ERR(CAM_ISP, "CSID:%d Invalid res type %d",
+			csid_hw->hw_intf->hw_idx,
+			res->res_type);
+		return -EINVAL;
+	}
+
+	switch (res->res_id) {
+	case CAM_TFE_CSID_PATH_RES_IPP:
+		rc = cam_tfe_csid_change_pxl_halt_mode(csid_hw, csid_halt);
 		break;
 	default:
-		CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
+		CAM_DBG(CAM_ISP, "CSID:%d res_id %d",
 			csid_hw->hw_intf->hw_idx,
-			res->res_type);
+			res->res_id);
 		break;
 	}
 
-	return 0;
+	return rc;
 }
 
 static int cam_tfe_csid_stop(void *hw_priv,
@@ -2328,7 +2334,8 @@ static int cam_tfe_csid_sof_irq_debug(
 	if (csid_hw->hw_info->hw_state ==
 		CAM_HW_STATE_POWER_DOWN) {
 		CAM_WARN(CAM_ISP,
-			"CSID powered down unable to %s sof irq",
+			"CSID:%d powered down unable to %s sof irq",
+			csid_hw->hw_intf->hw_idx,
 			sof_irq_enable ? "enable" : "disable");
 		return 0;
 	}
@@ -2372,8 +2379,10 @@ static int cam_tfe_csid_sof_irq_debug(
 		csid_hw->sof_irq_triggered = false;
 	}
 
-	CAM_INFO(CAM_ISP, "SOF freeze: CSID SOF irq %s",
-		sof_irq_enable ? "enabled" : "disabled");
+	if (!in_irq())
+		CAM_INFO(CAM_ISP, "SOF freeze: CSID:%d SOF irq %s",
+			csid_hw->hw_intf->hw_idx,
+			sof_irq_enable ? "enabled" : "disabled");
 
 	return 0;
 }
@@ -2677,6 +2686,191 @@ static int cam_tfe_csid_process_cmd(void *hw_priv,
 	return rc;
 }
 
+static int cam_tfe_csid_get_evt_payload(
+	struct cam_tfe_csid_hw *csid_hw,
+	struct cam_csid_evt_payload **evt_payload)
+{
+
+	spin_lock(&csid_hw->spin_lock);
+
+	if (list_empty(&csid_hw->free_payload_list)) {
+		*evt_payload = NULL;
+		spin_unlock(&csid_hw->spin_lock);
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "No free payload core %d",
+			csid_hw->hw_intf->hw_idx);
+		return -ENOMEM;
+	}
+
+	*evt_payload = list_first_entry(&csid_hw->free_payload_list,
+			struct cam_csid_evt_payload, list);
+	list_del_init(&(*evt_payload)->list);
+	spin_unlock(&csid_hw->spin_lock);
+
+	return 0;
+}
+
+static int cam_tfe_csid_put_evt_payload(
+	struct cam_tfe_csid_hw *csid_hw,
+	struct cam_csid_evt_payload **evt_payload)
+{
+	unsigned long flags;
+
+	if (*evt_payload == NULL) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid payload core %d",
+			csid_hw->hw_intf->hw_idx);
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&csid_hw->spin_lock, flags);
+	list_add_tail(&(*evt_payload)->list,
+		&csid_hw->free_payload_list);
+	*evt_payload = NULL;
+	spin_unlock_irqrestore(&csid_hw->spin_lock, flags);
+
+	return 0;
+}
+
+static int cam_tfe_csid_evt_bottom_half_handler(
+	void *handler_priv,
+	void *evt_payload_priv)
+{
+	struct cam_tfe_csid_hw *csid_hw;
+	struct cam_csid_evt_payload *evt_payload;
+	const struct cam_tfe_csid_reg_offset    *csid_reg;
+	struct cam_isp_hw_event_info event_info;
+	int i;
+	int rc = 0;
+
+	if (!handler_priv || !evt_payload_priv) {
+		CAM_ERR(CAM_ISP,
+			"Invalid Param handler_priv %pK evt_payload_priv %pK",
+			handler_priv, evt_payload_priv);
+		return 0;
+	}
+
+	csid_hw = (struct cam_tfe_csid_hw *)handler_priv;
+	evt_payload = (struct cam_csid_evt_payload *)evt_payload_priv;
+	csid_reg = csid_hw->csid_info->csid_reg;
+
+	if (!csid_hw->event_cb || !csid_hw->event_cb_priv) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP,
+			"hw_idx %d Invalid args %pK %pK",
+			csid_hw->hw_intf->hw_idx,
+			csid_hw->event_cb,
+			csid_hw->event_cb_priv);
+		goto end;
+	}
+
+	if (csid_hw->event_cb_priv != evt_payload->priv) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP,
+			"hw_idx %d priv mismatch %pK, %pK",
+			csid_hw->hw_intf->hw_idx,
+			csid_hw->event_cb_priv,
+			evt_payload->priv);
+		goto end;
+	}
+
+	if (csid_hw->sof_irq_triggered && (evt_payload->evt_type ==
+		CAM_ISP_HW_ERROR_NONE)) {
+		if (evt_payload->irq_status[TFE_CSID_IRQ_REG_IPP] &
+			TFE_CSID_PATH_INFO_INPUT_SOF) {
+			CAM_INFO_RATE_LIMIT(CAM_ISP,
+				"CSID:%d IPP SOF received",
+				csid_hw->hw_intf->hw_idx);
+		}
+
+		for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
+			if (evt_payload->irq_status[i] &
+				TFE_CSID_PATH_INFO_INPUT_SOF)
+				CAM_INFO_RATE_LIMIT(CAM_ISP,
+					"CSID:%d RDI:%d SOF received",
+					csid_hw->hw_intf->hw_idx, i);
+		}
+	} else {
+		CAM_ERR_RATE_LIMIT(CAM_ISP,
+			"CSID %d err %d phy %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x",
+			csid_hw->hw_intf->hw_idx,
+			evt_payload->evt_type,
+			csid_hw->csi2_rx_cfg.phy_sel,
+			evt_payload->irq_status[TFE_CSID_IRQ_REG_TOP],
+			evt_payload->irq_status[TFE_CSID_IRQ_REG_RX],
+			evt_payload->irq_status[TFE_CSID_IRQ_REG_IPP],
+			evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI0],
+			evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI1],
+			evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI2]);
+	}
+	/* this hunk can be extended to handle more cases
+	 * which we want to offload to bottom half from
+	 * irq handlers
+	 */
+	event_info.err_type = evt_payload->evt_type;
+	event_info.hw_idx = evt_payload->hw_idx;
+
+	switch (evt_payload->evt_type) {
+	case CAM_ISP_HW_ERROR_CSID_FATAL:
+		if (csid_hw->fatal_err_detected)
+			break;
+		csid_hw->fatal_err_detected = true;
+		rc = csid_hw->event_cb(NULL,
+			CAM_ISP_HW_EVENT_ERROR, (void *)&event_info);
+		break;
+
+	default:
+		CAM_DBG(CAM_ISP, "CSID[%d] error type %d",
+			csid_hw->hw_intf->hw_idx,
+			evt_payload->evt_type);
+		break;
+	}
+end:
+	cam_tfe_csid_put_evt_payload(csid_hw, &evt_payload);
+	return 0;
+}
+
+static int cam_tfe_csid_handle_hw_err_irq(
+	struct cam_tfe_csid_hw *csid_hw,
+	int                     evt_type,
+	uint32_t               *irq_status)
+{
+	int      rc = 0;
+	int      i;
+	void    *bh_cmd = NULL;
+	struct cam_csid_evt_payload *evt_payload;
+
+	CAM_DBG(CAM_ISP, "CSID[%d] error %d",
+		csid_hw->hw_intf->hw_idx, evt_type);
+
+	rc = cam_tfe_csid_get_evt_payload(csid_hw, &evt_payload);
+	if (rc) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP,
+			"No free payload core %d",
+			csid_hw->hw_intf->hw_idx);
+		return rc;
+	}
+
+	rc = tasklet_bh_api.get_bh_payload_func(csid_hw->tasklet, &bh_cmd);
+	if (rc || !bh_cmd) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP,
+			"CSID[%d] Can not get cmd for tasklet, evt_type %d",
+			csid_hw->hw_intf->hw_idx,
+			evt_type);
+		return rc;
+	}
+
+	evt_payload->evt_type = evt_type;
+	evt_payload->priv = csid_hw->event_cb_priv;
+	evt_payload->hw_idx = csid_hw->hw_intf->hw_idx;
+
+	for (i = 0; i < TFE_CSID_IRQ_REG_MAX; i++)
+		evt_payload->irq_status[i] = irq_status[i];
+
+	tasklet_bh_api.bottom_half_enqueue_func(csid_hw->tasklet,
+		bh_cmd,
+		csid_hw,
+		evt_payload,
+		cam_tfe_csid_evt_bottom_half_handler);
+
+	return rc;
+}
+
 irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 {
 	struct cam_tfe_csid_hw                         *csid_hw;
@@ -2685,7 +2879,7 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 	const struct cam_tfe_csid_csi2_rx_reg_offset   *csi2_reg;
 	uint32_t                   irq_status[TFE_CSID_IRQ_REG_MAX];
 	bool fatal_err_detected = false, is_error_irq = false;
-	uint32_t sof_irq_debug_en = 0;
+	uint32_t sof_irq_debug_en = 0, log_en = 0;
 	unsigned long flags;
 	uint32_t i, val;
 
@@ -2756,20 +2950,24 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 		if (irq_status[TFE_CSID_IRQ_REG_RX] &
 			TFE_CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 
 		if (irq_status[TFE_CSID_IRQ_REG_RX] &
 			TFE_CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 
 		if (irq_status[TFE_CSID_IRQ_REG_RX] &
 			TFE_CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 		if (irq_status[TFE_CSID_IRQ_REG_RX] &
 			TFE_CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
 			fatal_err_detected = true;
+			goto handle_fatal_error;
 		}
 
 		if (irq_status[TFE_CSID_IRQ_REG_RX] &
@@ -2800,6 +2998,7 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 			TFE_CSID_CSI2_RX_ERROR_MMAPPED_VC_DT)
 			is_error_irq = true;
 	}
+handle_fatal_error:
 	spin_unlock_irqrestore(&csid_hw->spin_lock, flags);
 
 	if (csid_hw->error_irq_count || fatal_err_detected)
@@ -2825,6 +3024,8 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 				CAM_SUBDEV_MESSAGE_IRQ_ERR,
 				(csid_hw->csi2_rx_cfg.phy_sel - 1));
 		}
+		cam_tfe_csid_handle_hw_err_irq(csid_hw,
+			CAM_ISP_HW_ERROR_CSID_FATAL, irq_status);
 	}
 
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOT_IRQ) {
@@ -2901,6 +3102,10 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 		CAM_INFO_RATE_LIMIT(CAM_ISP,
 			"CSID:%d long pkt cal CRC:%d expected CRC:%d",
 			csid_hw->hw_intf->hw_idx, (val >> 16), (val & 0xFFFF));
+		/* reset long pkt strobe to capture next long packet */
+		val = (1 << csi2_reg->csi2_rx_long_pkt_hdr_rst_stb_shift);
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			csi2_reg->csid_csi2_rx_rst_strobes_addr);
 	}
 	if ((csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) &&
 		(irq_status[TFE_CSID_IRQ_REG_RX] &
@@ -2917,6 +3122,10 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 			csi2_reg->csid_csi2_rx_captured_short_pkt_1_addr);
 		CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d short packet ECC :%d",
 			csid_hw->hw_intf->hw_idx, val);
+		/* reset short pkt strobe to capture next short packet */
+		val = (1 << csi2_reg->csi2_rx_short_pkt_hdr_rst_stb_shift);
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			csi2_reg->csid_csi2_rx_rst_strobes_addr);
 	}
 
 	if ((csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) &&
@@ -2930,6 +3139,10 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 			"CSID:%d cphy packet VC :%d DT:%d WC:%d",
 			csid_hw->hw_intf->hw_idx,
 			(val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
+		/* reset cphy pkt strobe to capture next short packet */
+		val = (1 << csi2_reg->csi2_rx_cphy_pkt_hdr_rst_stb_shift);
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			csi2_reg->csid_csi2_rx_rst_strobes_addr);
 	}
 
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_RST_IRQ_LOG) {
@@ -2961,8 +3174,13 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 		if ((irq_status[TFE_CSID_IRQ_REG_IPP] &
 			TFE_CSID_PATH_INFO_INPUT_SOF) &&
 			(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
-			CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP SOF received",
-				csid_hw->hw_intf->hw_idx);
+			if (!csid_hw->sof_irq_triggered)
+				CAM_INFO_RATE_LIMIT(CAM_ISP,
+				"CSID:%d IPP SOF received",
+					csid_hw->hw_intf->hw_idx);
+			else
+				log_en = 1;
+
 			if (csid_hw->sof_irq_triggered)
 				csid_hw->irq_debug_cnt++;
 		}
@@ -2996,18 +3214,25 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 			(csid_hw->csid_debug &
 			TFE_CSID_DEBUG_ENABLE_RST_IRQ_LOG))
 			CAM_INFO_RATE_LIMIT(CAM_ISP,
-				"CSID RDI%d reset complete", i);
+				"CSID:%d RDI%d reset complete",
+				csid_hw->hw_intf->hw_idx, i);
 
 		if (irq_status[i] &
 			BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
-			CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
+			CAM_DBG(CAM_ISP, "CSID:%d RDI%d reset complete",
+				csid_hw->hw_intf->hw_idx, i);
 			complete(&csid_hw->csid_rdin_complete[i]);
 		}
 
 		if ((irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF) &&
 			(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
-			CAM_INFO_RATE_LIMIT(CAM_ISP,
-				"CSID RDI:%d SOF received", i);
+			if (!csid_hw->sof_irq_triggered)
+				CAM_INFO_RATE_LIMIT(CAM_ISP,
+					"CSID:%d RDI:%d SOF received",
+					csid_hw->hw_intf->hw_idx, i);
+			else
+				log_en = 1;
+
 			if (csid_hw->sof_irq_triggered)
 				csid_hw->irq_debug_cnt++;
 		}
@@ -3015,7 +3240,8 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 		if ((irq_status[i] & TFE_CSID_PATH_INFO_INPUT_EOF) &&
 			(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)) {
 			CAM_INFO_RATE_LIMIT(CAM_ISP,
-				"CSID RDI:%d EOF received", i);
+				"CSID:%d RDI:%d EOF received",
+				csid_hw->hw_intf->hw_idx, i);
 		}
 
 		if (irq_status[i] & TFE_CSID_PATH_ERROR_FIFO_OVERFLOW) {
@@ -3032,16 +3258,9 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 			is_error_irq = true;
 	}
 
-	if (is_error_irq)
-		CAM_ERR_RATE_LIMIT(CAM_ISP,
-			"CSID %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x",
-			csid_hw->hw_intf->hw_idx,
-			irq_status[TFE_CSID_IRQ_REG_TOP],
-			irq_status[TFE_CSID_IRQ_REG_RX],
-			irq_status[TFE_CSID_IRQ_REG_IPP],
-			irq_status[TFE_CSID_IRQ_REG_RDI0],
-			irq_status[TFE_CSID_IRQ_REG_RDI1],
-			irq_status[TFE_CSID_IRQ_REG_RDI2]);
+	if (is_error_irq || log_en)
+		cam_tfe_csid_handle_hw_err_irq(csid_hw,
+			CAM_ISP_HW_ERROR_NONE, irq_status);
 
 	if (csid_hw->irq_debug_cnt >= CAM_TFE_CSID_IRQ_SOF_DEBUG_CNT_MAX) {
 		cam_tfe_csid_sof_irq_debug(csid_hw, &sof_irq_debug_en);
@@ -3190,6 +3409,19 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf  *csid_hw_intf,
 		tfe_csid_hw->rdi_res[i].res_priv = path_data;
 	}
 
+	rc = cam_tasklet_init(&tfe_csid_hw->tasklet, tfe_csid_hw, csid_idx);
+	if (rc) {
+		CAM_ERR(CAM_ISP, "Unable to create CSID tasklet rc %d", rc);
+		goto err;
+	}
+
+	INIT_LIST_HEAD(&tfe_csid_hw->free_payload_list);
+	for (i = 0; i < CAM_CSID_EVT_PAYLOAD_MAX; i++) {
+		INIT_LIST_HEAD(&tfe_csid_hw->evt_payload[i].list);
+		list_add_tail(&tfe_csid_hw->evt_payload[i].list,
+			&tfe_csid_hw->free_payload_list);
+	}
+
 	tfe_csid_hw->csid_debug = 0;
 	tfe_csid_hw->error_irq_count = 0;
 	tfe_csid_hw->prev_boot_timestamp = 0;

+ 27 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h

@@ -74,6 +74,8 @@
 #define TFE_CSID_DEBUG_DISABLE_EARLY_EOF              BIT(8)
 #define TFE_CSID_DEBUG_ENABLE_RST_IRQ_LOG             BIT(9)
 
+#define CAM_CSID_EVT_PAYLOAD_MAX                  10
+
 /* enum cam_csid_path_halt_mode select the path halt mode control */
 enum cam_tfe_csid_path_halt_mode {
 	TFE_CSID_HALT_MODE_INTERNAL,
@@ -199,6 +201,7 @@ struct cam_tfe_csid_csi2_rx_reg_offset {
 	uint32_t csi2_rx_phy_num_mask;
 	uint32_t csi2_rx_long_pkt_hdr_rst_stb_shift;
 	uint32_t csi2_rx_short_pkt_hdr_rst_stb_shift;
+	uint32_t csi2_rx_cphy_pkt_hdr_rst_stb_shift;
 };
 
 struct cam_tfe_csid_common_reg_offset {
@@ -354,12 +357,31 @@ struct cam_tfe_csid_path_cfg {
 	uint32_t                        sensor_vbi;
 };
 
+/**
+ * struct cam_csid_evt_payload- payload for csid hw event
+ * @list       : list head
+ * @evt_type   : Event type from CSID
+ * @irq_status : IRQ Status register
+ * @hw_idx     : Hw index
+ * @priv       : Private data of payload
+ */
+struct cam_csid_evt_payload {
+	struct list_head   list;
+	uint32_t           evt_type;
+	uint32_t           irq_status[TFE_CSID_IRQ_REG_MAX];
+	uint32_t           hw_idx;
+	void              *priv;
+};
+
 /**
  * struct cam_tfe_csid_hw- csid hw device resources data
  *
  * @hw_intf:                  contain the csid hw interface information
  * @hw_info:                  csid hw device information
  * @csid_info:                csid hw specific information
+ * @tasklet:                  tasklet to handle csid errors
+ * @free_payload_list:        list head for payload
+ * @evt_payload:              Event payload to be passed to tasklet
  * @in_res_id:                csid in resource type
  * @csi2_rx_cfg:              csi2 rx decoder configuration for csid
  * @csi2_rx_reserve_cnt:      csi2 reservations count value
@@ -382,6 +404,7 @@ struct cam_tfe_csid_path_cfg {
  * @device_enabled            Device enabled will set once CSID powered on and
  *                            initial configuration are done.
  * @lock_state                csid spin lock
+ * @fatal_err_detected        flag to indicate fatal errror is reported
  * @event_cb:                 Callback function to hw mgr in case of hw events
  * @event_cb_priv:            Context data
  * @ppi_hw_intf               interface to ppi hardware
@@ -395,6 +418,9 @@ struct cam_tfe_csid_hw {
 	struct cam_hw_intf                 *hw_intf;
 	struct cam_hw_info                 *hw_info;
 	struct cam_tfe_csid_hw_info        *csid_info;
+	void                               *tasklet;
+	struct list_head                    free_payload_list;
+	struct cam_csid_evt_payload   evt_payload[CAM_CSID_EVT_PAYLOAD_MAX];
 	uint32_t                            in_res_id;
 	struct cam_tfe_csid_csi2_rx_cfg     csi2_rx_cfg;
 	uint32_t                            csi2_reserve_cnt;
@@ -413,6 +439,7 @@ struct cam_tfe_csid_hw {
 	uint32_t                            error_irq_count;
 	uint32_t                            device_enabled;
 	spinlock_t                          spin_lock;
+	bool                                fatal_err_detected;
 	cam_hw_mgr_event_cb_func            event_cb;
 	void                               *event_cb_priv;
 	struct cam_hw_intf                 *ppi_hw_intf[CAM_CSID_PPI_HW_MAX];

+ 14 - 10
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -1821,8 +1821,11 @@ int cam_tfe_top_reserve(void *device_priv,
 					acquire_args->in_port->line_start;
 				camif_data->last_line =
 					acquire_args->in_port->line_end;
-				camif_data->vbi_value =
-					acquire_args->in_port->sensor_vbi;
+				if (acquire_args->in_port->res_id == CAM_ISP_TFE_IN_RES_TPG)
+					camif_data->vbi_value = 0;
+				else
+					camif_data->vbi_value =
+						acquire_args->in_port->sensor_vbi;
 				camif_data->hbi_value =
 					acquire_args->in_port->sensor_hbi;
 				camif_data->camif_pd_enable =
@@ -1972,10 +1975,10 @@ static int cam_tfe_camif_resource_start(
 
 	/* Epoch config */
 	epoch0_irq_mask = (((rsrc_data->last_line + rsrc_data->vbi_value) -
-			rsrc_data->first_line) / 2) +
-			rsrc_data->first_line;
-	if (epoch0_irq_mask > rsrc_data->last_line)
-		epoch0_irq_mask = rsrc_data->last_line;
+			rsrc_data->first_line) / 2);
+	if (epoch0_irq_mask > (rsrc_data->last_line - rsrc_data->first_line))
+		epoch0_irq_mask = (rsrc_data->last_line -
+					rsrc_data->first_line);
 
 	epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg &
 			0xFFFF;
@@ -2000,7 +2003,7 @@ static int cam_tfe_camif_resource_start(
 	CAM_DBG(CAM_ISP, "hw id:%d RUP val:%d", camif_res->hw_intf->hw_idx,
 		rsrc_data->reg_data->reg_update_cmd_data);
 
-	/* 
Disable sof irq debug flag */
+	/* Disable sof irq debug flag */
 	rsrc_data->enable_sof_irq_debug = false;
 	rsrc_data->irq_debug_cnt = 0;
 
@@ -2012,9 +2015,10 @@ static int cam_tfe_camif_resource_start(
 			rsrc_data->common_reg->diag_config);
 	}
 
-	/* Enable the irq */
-	cam_tfe_irq_config(core_info, rsrc_data->reg_data->subscribe_irq_mask,
-		CAM_TFE_TOP_IRQ_REG_NUM, true);
+	/* Enable the irq only for master or single tfe usecase */
+	if (rsrc_data->sync_mode != CAM_ISP_HW_SYNC_SLAVE)
+		cam_tfe_irq_config(core_info, rsrc_data->reg_data->subscribe_irq_mask,
+			CAM_TFE_TOP_IRQ_REG_NUM, true);
 
 	/* Program perf counters */
 	val = (1 << rsrc_data->reg_data->perf_cnt_start_cmd_shift) |

+ 18 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c

@@ -273,8 +273,14 @@ static int cam_top_tpg_ver1_start(
 			soc_info->reg_map[0].mem_base + tpg_reg->tpg_vbi_cfg);
 
 	/* Set the TOP tpg mux sel*/
-	cam_io_w_mb((1 << tpg_hw->hw_intf->hw_idx),
+	val = cam_io_r_mb(soc_info->reg_map[1].mem_base +
+			tpg_reg->top_mux_reg_offset);
+	val |= (1 << tpg_hw->hw_intf->hw_idx);
+
+	cam_io_w_mb(val,
 		soc_info->reg_map[1].mem_base + tpg_reg->top_mux_reg_offset);
+	CAM_DBG(CAM_ISP, "TPG:%d Set top Mux: 0x%x",
+		tpg_hw->hw_intf->hw_idx, val);
 
 	val = ((tpg_data->num_active_lanes - 1) <<
 		tpg_reg->tpg_num_active_lines_shift) |
@@ -307,6 +313,7 @@ static int cam_top_tpg_ver1_stop(
 	struct cam_isp_resource_node                 *tpg_res;
 	const struct cam_top_tpg_ver1_reg_offset     *tpg_reg;
 	struct cam_top_tpg_cfg                       *tpg_data;
+	uint32_t                                      val;
 
 	if (!hw_priv || !stop_args ||
 		(arg_size != sizeof(struct cam_isp_resource_node))) {
@@ -333,6 +340,16 @@ static int cam_top_tpg_ver1_stop(
 	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
 		tpg_reg->tpg_ctrl);
 
+	/* Reset the TOP tpg mux sel*/
+	val = cam_io_r_mb(soc_info->reg_map[1].mem_base +
+			tpg_reg->top_mux_reg_offset);
+	val &= ~(1 << tpg_hw->hw_intf->hw_idx);
+
+	cam_io_w_mb(val,
+		soc_info->reg_map[1].mem_base + tpg_reg->top_mux_reg_offset);
+	CAM_DBG(CAM_ISP, "TPG:%d Reset Top Mux: 0x%x",
+		tpg_hw->hw_intf->hw_idx, val);
+
 	tpg_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
 
 	CAM_DBG(CAM_ISP, "TPG:%d stopped", tpg_hw->hw_intf->hw_idx);

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c

@@ -616,9 +616,9 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_GET_SECURE_MODE:
 	case CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ:
 	case CAM_ISP_HW_CMD_DUMP_BUS_INFO:
-	case CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT:
 	case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
 	case CAM_ISP_HW_CMD_DISABLE_UBWC_COMP:
+	case CAM_ISP_HW_CMD_QUERY_BUS_CAP:
 		rc = core_info->vfe_bus->hw_ops.process_cmd(
 			core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
 			arg_size);

+ 8 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE_CORE_H_
@@ -12,6 +12,13 @@
 #include "cam_vfe_bus.h"
 #include "cam_vfe_hw_intf.h"
 
+#define CAM_VFE_HW_IRQ_CAP_SOF             0x1
+#define CAM_VFE_HW_IRQ_CAP_EPOCH_0         0x2
+#define CAM_VFE_HW_IRQ_CAP_EPOCH_1         0x4
+#define CAM_VFE_HW_IRQ_CAP_RUP             0x8
+#define CAM_VFE_HW_IRQ_CAP_BUF_DONE        0x10
+#define CAM_VFE_HW_IRQ_CAP_EOF             0x20
+
 struct cam_vfe_hw_info {
 	struct cam_irq_controller_reg_info *irq_reg_info;
 

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h

@@ -861,6 +861,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe170_bus_hw_info = {
 	},
 	.top_irq_shift = 9,
 	.support_consumed_addr = false,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 19,
 };
 
 static struct cam_vfe_hw_info cam_vfe170_hw_info = {

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170_150.h

@@ -829,6 +829,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe170_150_bus_hw_info = {
 		},
 	},
 	.support_consumed_addr = false,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 19,
 };
 
 static struct cam_vfe_hw_info cam_vfe170_150_hw_info = {

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h

@@ -1022,6 +1022,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_bus_hw_info = {
 	},
 	.top_irq_shift = 9,
 	.support_consumed_addr = false,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 23,
 };
 
 static struct cam_vfe_hw_info cam_vfe175_hw_info = {

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h

@@ -1137,6 +1137,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_130_bus_hw_info = {
 	},
 	.top_irq_shift = 9,
 	.support_consumed_addr = false,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 23,
 };
 
 static struct cam_vfe_hw_info cam_vfe175_130_hw_info = {

+ 100 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h

@@ -412,7 +412,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.global_clear_bitmask     = 0x00000001,
 		},
 	},
-	.num_client = CAM_VFE_BUS_VER3_MAX_CLIENTS,
+	.num_client = CAM_VFE_BUS_VER3_480_MAX_CLIENTS,
 	.bus_client_reg = {
 		/* BUS Client 0 FULL Y */
 		{
@@ -1177,6 +1177,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_3,
 			.mid[0]        = 8,
+			.num_wm        = 1,
+			.wm_idx        = {
+				23,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI1,
@@ -1184,6 +1188,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_4,
 			.mid[0]        = 9,
+			.num_wm        = 1,
+			.wm_idx        = {
+				24,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI2,
@@ -1191,6 +1199,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_5,
 			.mid[0]        = 10,
+			.num_wm        = 1,
+			.wm_idx        = {
+				25,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FULL,
@@ -1201,6 +1213,11 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.mid[1]        = 33,
 			.mid[2]        = 34,
 			.mid[3]        = 35,
+			.num_wm        = 2,
+			.wm_idx        = {
+				0,
+				1,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS4,
@@ -1208,6 +1225,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 16,
+			.num_wm        = 1,
+			.wm_idx        = {
+				2,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS16,
@@ -1215,6 +1236,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 17,
+			.num_wm        = 1,
+			.wm_idx        = {
+				3,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP,
@@ -1223,6 +1248,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 11,
 			.mid[1]        = 12,
+			.num_wm        = 1,
+			.wm_idx        = {
+				10,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FD,
@@ -1232,6 +1261,11 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.mid[0]        = 20,
 			.mid[1]        = 21,
 			.mid[2]        = 22,
+			.num_wm        = 2,
+			.wm_idx        = {
+				8,
+				9,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_PDAF,
@@ -1240,6 +1274,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 25,
 			.mid[1]        = 26,
+			.num_wm        = 1,
+			.wm_idx        = {
+				11,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE,
@@ -1247,6 +1285,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 40,
+			.num_wm        = 1,
+			.wm_idx        = {
+				12,
+			}
 		},
 		{
 			.vfe_out_type  =
@@ -1255,6 +1297,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 41,
+			.num_wm        = 1,
+			.wm_idx        = {
+				13,
+			}
 		},
 		{
 			.vfe_out_type  =
@@ -1263,6 +1309,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 42,
+			.num_wm        = 1,
+			.wm_idx        = {
+				14,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF,
@@ -1270,6 +1320,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 43,
+			.num_wm        = 1,
+			.wm_idx        = {
+				20,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG,
@@ -1277,6 +1331,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]         = 44,
+			.num_wm        = 1,
+			.wm_idx        = {
+				15,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST,
@@ -1284,6 +1342,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 45,
+			.num_wm        = 1,
+			.wm_idx        = {
+				16,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS,
@@ -1291,6 +1353,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 46,
+			.num_wm        = 1,
+			.wm_idx        = {
+				17,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_CS,
@@ -1298,6 +1364,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 47,
+			.num_wm        = 1,
+			.wm_idx        = {
+				18,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST,
@@ -1305,6 +1375,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 48,
+			.num_wm        = 1,
+			.wm_idx        = {
+				19,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP,
@@ -1315,6 +1389,11 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.mid[1]        = 37,
 			.mid[2]        = 38,
 			.mid[3]        = 39,
+			.num_wm        = 2,
+			.wm_idx        = {
+				4,
+				5,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP,
@@ -1322,6 +1401,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 18,
+			.num_wm        = 1,
+			.wm_idx        = {
+				6,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP,
@@ -1329,6 +1412,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = 1080,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 19,
+			.num_wm        = 1,
+			.wm_idx        = {
+				7,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_2PD,
@@ -1337,6 +1424,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_1,
 			.mid[0]        = 23,
 			.mid[1]        = 24,
+			.num_wm        = 1,
+			.wm_idx        = {
+				21,
+			}
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_LCR,
@@ -1344,11 +1435,19 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_2,
 			.mid[0]        = 27,
+			.num_wm        = 1,
+			.wm_idx        = {
+				22,
+			}
 		},
 	},
+	.num_comp_grp    = 14,
 	.comp_done_shift = 6,
 	.top_irq_shift   = 7,
 	.support_consumed_addr = true,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 25,
+	.supported_irq =  CAM_VFE_HW_IRQ_CAP_BUF_DONE | CAM_VFE_HW_IRQ_CAP_RUP,
+	.comp_cfg_needed = true,
 };
 
 static struct cam_irq_register_set vfe480_bus_rd_irq_reg[1] = {

+ 1328 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h

@@ -0,0 +1,1328 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+
+#ifndef _CAM_VFE680_H_
+#define _CAM_VFE680_H_
+#include "cam_vfe_camif_ver3.h"
+#include "cam_vfe_top_ver3.h"
+#include "cam_vfe_core.h"
+#include "cam_vfe_bus_ver3.h"
+#include "cam_irq_controller.h"
+
+static struct cam_irq_register_set vfe680_top_irq_reg_set[3] = {
+	{
+		.mask_reg_offset   = 0x00000034,
+		.clear_reg_offset  = 0x0000003c,
+		.status_reg_offset = 0x00000044,
+	},
+	{
+		.mask_reg_offset   = 0x00000038,
+		.clear_reg_offset  = 0x00000040,
+		.status_reg_offset = 0x00000048,
+	},
+};
+
+static struct cam_irq_controller_reg_info vfe680_top_irq_reg_info = {
+	.num_registers = 2,
+	.irq_reg_set = vfe680_top_irq_reg_set,
+	.global_clear_offset  = 0x00000030,
+	.global_clear_bitmask = 0x00000001,
+};
+
+static struct cam_vfe_top_ver3_reg_offset_common vfe680_top_common_reg = {
+	.hw_version               = 0x00000000,
+	.hw_capability            = 0x00000004,
+	.lens_feature             = 0x00000008,
+	.stats_feature            = 0x0000000C,
+	.color_feature            = 0x00000010,
+	.zoom_feature             = 0x00000014,
+	.core_cfg_0               = 0x00000024,
+	.core_cfg_1               = 0x00000028,
+	.core_cfg_2               = 0x0000002C,
+	.global_reset_cmd         = 0x00000030,
+	.diag_config              = 0x00000050,
+	.diag_sensor_status_0     = 0x00000054,
+	.diag_sensor_status_1     = 0x00000058,
+	.diag_frm_cnt_status_0    = 0x0000005C,
+	.diag_frm_cnt_status_1    = 0x00000060,
+	.violation_status         = 0x00000064,
+	.core_cfg_3               = 0x00000068,
+	.core_cgc_ovd_0           = 0x00000018,
+	.core_cgc_ovd_1           = 0x0000001C,
+	.ahb_cgc_ovd              = 0x00000020,
+	.dsp_status               = 0x0000006C,
+	.stats_throttle_cfg_0     = 0x00000070,
+	.stats_throttle_cfg_1     = 0x00000074,
+	.stats_throttle_cfg_2     = 0x00000078,
+	.core_cfg_4               = 0x00000080,
+	.core_cfg_5               = 0x00000084,
+	.core_cfg_6               = 0x00000088,
+	.period_cfg               = 0x0000008C,
+	.irq_sub_pattern_cfg      = 0x00000090,
+	.epoch0_pattern_cfg       = 0x00000094,
+	.epoch1_pattern_cfg       = 0x00000098,
+	.epoch_height_cfg         = 0x0000009C,
+	.bus_overflow_status      = 0x0000AA68,
+	.top_debug_cfg            = 0x000000FC,
+	.top_debug_0              = 0x000000A0,
+	.top_debug_1              = 0x000000A4,
+	.top_debug_2              = 0x000000A8,
+	.top_debug_3              = 0x000000AC,
+	.top_debug_4              = 0x000000B0,
+	.top_debug_5              = 0x000000B4,
+	.top_debug_6              = 0x000000B8,
+	.top_debug_7              = 0x000000BC,
+	.top_debug_8              = 0x000000C0,
+	.top_debug_9              = 0x000000C4,
+	.top_debug_10             = 0x000000C8,
+	.top_debug_11             = 0x000000CC,
+	.top_debug_12             = 0x000000D0,
+	.top_debug_13             = 0x000000D4,
+	.top_debug_14             = 0x000000D8,
+	.top_debug_15             = 0x000000DC,
+	.top_debug_16             = 0x000000E0,
+};
+
+
+static struct cam_vfe_top_ver3_hw_info vfe680_top_hw_info = {
+	.common_reg = &vfe480_top_common_reg,
+	.camif_hw_info = {
+		.common_reg     = &vfe480_top_common_reg,
+		.camif_reg      = &vfe480_camif_reg,
+		.reg_data       = &vfe_480_camif_reg_data,
+		},
+	.pdlib_hw_info = {
+		.common_reg     = &vfe480_top_common_reg,
+		.camif_lite_reg = &vfe480_camif_pd,
+		.reg_data       = &vfe480_camif_pd_reg_data,
+		},
+	.rdi_hw_info[0] = &rdi_hw_info_arr[0],
+	.rdi_hw_info[1] = &rdi_hw_info_arr[1],
+	.rdi_hw_info[2] = &rdi_hw_info_arr[2],
+	.lcr_hw_info = {
+		.common_reg     = &vfe480_top_common_reg,
+		.camif_lite_reg = &vfe480_camif_lcr,
+		.reg_data       = &vfe480_camif_lcr_reg_data,
+		},
+	.num_mux = 6,
+	.mux_type = {
+		CAM_VFE_CAMIF_VER_3_0,
+		CAM_VFE_RDI_VER_1_0,
+		CAM_VFE_RDI_VER_1_0,
+		CAM_VFE_RDI_VER_1_0,
+		CAM_VFE_PDLIB_VER_1_0,
+		CAM_VFE_LCR_VER_1_0,
+	},
+};
+
+static struct cam_irq_register_set vfe680_bus_irq_reg[2] = {
+		{
+			.mask_reg_offset   = 0x00000C18,
+			.clear_reg_offset  = 0x00000C20,
+			.status_reg_offset = 0x00000C28,
+		},
+		{
+			.mask_reg_offset   = 0x00000C1C,
+			.clear_reg_offset  = 0x00000C24,
+			.status_reg_offset = 0x00000C2C,
+		},
+};
+
+static struct cam_vfe_bus_ver3_reg_offset_ubwc_client
+	vfe680_ubwc_regs_client_0 = {
+	.meta_addr        = 0x00000E40,
+	.meta_cfg         = 0x00000E44,
+	.mode_cfg         = 0x00000E48,
+	.stats_ctrl       = 0x00000E4C,
+	.ctrl_2           = 0x00000E50,
+	.lossy_thresh0    = 0x00000E54,
+	.lossy_thresh1    = 0x00000E58,
+	.off_lossy_var    = 0x00000E5C,
+	.bw_limit         = 0x00000E1C,
+};
+
+static struct cam_vfe_bus_ver3_reg_offset_ubwc_client
+	vfe680_ubwc_regs_client_1 = {
+	.meta_addr        = 0x00000F40,
+	.meta_cfg         = 0x00000F44,
+	.mode_cfg         = 0x00000F48,
+	.stats_ctrl       = 0x00000F4C,
+	.ctrl_2           = 0x00000F50,
+	.lossy_thresh0    = 0x00000F54,
+	.lossy_thresh1    = 0x00000F58,
+	.off_lossy_var    = 0x00000F5C,
+	.bw_limit         = 0x00000F1C,
+};
+
+static struct cam_vfe_bus_ver3_reg_offset_ubwc_client
+	vfe680_ubwc_regs_client_4 = {
+	.meta_addr        = 0x00001240,
+	.meta_cfg         = 0x00001244,
+	.mode_cfg         = 0x00001248,
+	.stats_ctrl       = 0x0000124C,
+	.ctrl_2           = 0x00001250,
+	.lossy_thresh0    = 0x00001254,
+	.lossy_thresh1    = 0x00001258,
+	.off_lossy_var    = 0x0000125C,
+	.bw_limit         = 0x0000121C,
+};
+
+static struct cam_vfe_bus_ver3_reg_offset_ubwc_client
+	vfe680_ubwc_regs_client_5 = {
+	.meta_addr        = 0x00001340,
+	.meta_cfg         = 0x00001344,
+	.mode_cfg         = 0x00001348,
+	.stats_ctrl       = 0x0000134C,
+	.ctrl_2           = 0x00001350,
+	.lossy_thresh0    = 0x00001354,
+	.lossy_thresh1    = 0x00001358,
+	.off_lossy_var    = 0x0000135C,
+	.bw_limit         = 0x0000131C,
+};
+
+static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = {
+	.common_reg = {
+		.hw_version                       = 0x00000C00,
+		.cgc_ovd                          = 0x00000C08,
+		.if_frameheader_cfg               = {
+			0x00000C34,
+			0x00000C38,
+			0x00000C3C,
+			0x00000C40,
+			0x00000C44,
+			0x00000C48,
+		},
+		.ubwc_static_ctrl                 = 0x00000C58,
+		.pwr_iso_cfg                      = 0x00000C5C,
+		.overflow_status_clear            = 0x00000C60,
+		.ccif_violation_status            = 0x00000C64,
+		.overflow_status                  = 0x00000C68,
+		.image_size_violation_status      = 0x00000C70,
+		.debug_status_top_cfg             = 0x00000CD4,
+		.debug_status_top                 = 0x00000CD8,
+		.test_bus_ctrl                    = 0x00000CDC,
+		.irq_reg_info = {
+			.num_registers            = 2,
+			.irq_reg_set              = vfe680_bus_irq_reg,
+			.global_clear_offset      = 0x00000C30,
+			.global_clear_bitmask     = 0x00000001,
+		},
+	},
+	.num_client = CAM_VFE_BUS_VER3_680_MAX_CLIENTS,
+	.bus_client_reg = {
+		/* BUS Client 0 FULL Y */
+		{
+			.cfg                      = 0x00000E00,
+			.image_addr               = 0x00000E04,
+			.frame_incr               = 0x00000E08,
+			.image_cfg_0              = 0x00000E0C,
+			.image_cfg_1              = 0x00000E10,
+			.image_cfg_2              = 0x00000E14,
+			.packer_cfg               = 0x00000E18,
+			.frame_header_addr        = 0x00000E20,
+			.frame_header_incr        = 0x00000E24,
+			.frame_header_cfg         = 0x00000E28,
+			.irq_subsample_period     = 0x00000E30,
+			.irq_subsample_pattern    = 0x00000E34,
+			.framedrop_period         = 0x00000E38,
+			.framedrop_pattern        = 0x00000E3C,
+			.mmu_prefetch_cfg         = 0x00000E60,
+			.mmu_prefetch_max_offset  = 0x00000E64,
+			.system_cache_cfg         = 0x00000E68,
+			.addr_status_0            = 0x00000E70,
+			.addr_status_1            = 0x00000E74,
+			.addr_status_2            = 0x00000E78,
+			.addr_status_3            = 0x00000E7C,
+			.debug_status_cfg         = 0x00000E80,
+			.debug_status_0           = 0x00000E84,
+			.debug_status_1           = 0x00000E88,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_0,
+			.ubwc_regs                = &vfe680_ubwc_regs_client_0,
+		},
+		/* BUS Client 1 FULL C */
+		{
+			.cfg                      = 0x00000F00,
+			.image_addr               = 0x00000F04,
+			.frame_incr               = 0x00000F08,
+			.image_cfg_0              = 0x00000F0C,
+			.image_cfg_1              = 0x00000F10,
+			.image_cfg_2              = 0x00000F14,
+			.packer_cfg               = 0x00000F18,
+			.frame_header_addr        = 0x00000F20,
+			.frame_header_incr        = 0x00000F24,
+			.frame_header_cfg         = 0x00000F28,
+			.irq_subsample_period     = 0x00000F30,
+			.irq_subsample_pattern    = 0x00000F34,
+			.framedrop_period         = 0x00000F38,
+			.framedrop_pattern        = 0x00000F3C,
+			.mmu_prefetch_cfg         = 0x00000F60,
+			.mmu_prefetch_max_offset  = 0x00000F64,
+			.system_cache_cfg         = 0x00000F68,
+			.addr_status_0            = 0x00000F70,
+			.addr_status_1            = 0x00000F74,
+			.addr_status_2            = 0x00000F78,
+			.addr_status_3            = 0x00000F7C,
+			.debug_status_cfg         = 0x00000F80,
+			.debug_status_0           = 0x00000F84,
+			.debug_status_1           = 0x00000F88,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_0,
+			.ubwc_regs                = &vfe680_ubwc_regs_client_1,
+		},
+		/* BUS Client 2 DS4 */
+		{
+			.cfg                      = 0x00001000,
+			.image_addr               = 0x00001004,
+			.frame_incr               = 0x00001008,
+			.image_cfg_0              = 0x0000100C,
+			.image_cfg_1              = 0x00001010,
+			.image_cfg_2              = 0x00001014,
+			.packer_cfg               = 0x00001018,
+			.frame_header_addr        = 0x00001020,
+			.frame_header_incr        = 0x00001024,
+			.frame_header_cfg         = 0x00001028,
+			.irq_subsample_period     = 0x00001030,
+			.irq_subsample_pattern    = 0x00001034,
+			.framedrop_period         = 0x00001038,
+			.framedrop_pattern        = 0x0000103C,
+			.mmu_prefetch_cfg         = 0x00001060,
+			.mmu_prefetch_max_offset  = 0x00001064,
+			.system_cache_cfg         = 0x00001068,
+			.addr_status_0            = 0x00001070,
+			.addr_status_1            = 0x00001074,
+			.addr_status_2            = 0x00001078,
+			.addr_status_3            = 0x0000107C,
+			.debug_status_cfg         = 0x00001080,
+			.debug_status_0           = 0x00001084,
+			.debug_status_1           = 0x00001088,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_0,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 3 DS16 */
+		{
+			.cfg                      = 0x00001100,
+			.image_addr               = 0x00001104,
+			.frame_incr               = 0x00001108,
+			.image_cfg_0              = 0x0000110C,
+			.image_cfg_1              = 0x00001110,
+			.image_cfg_2              = 0x00001114,
+			.packer_cfg               = 0x00001118,
+			.frame_header_addr        = 0x00001120,
+			.frame_header_incr        = 0x00001124,
+			.frame_header_cfg         = 0x00001128,
+			.irq_subsample_period     = 0x00001130,
+			.irq_subsample_pattern    = 0x00001134,
+			.framedrop_period         = 0x00001138,
+			.framedrop_pattern        = 0x0000113C,
+			.mmu_prefetch_cfg         = 0x00001160,
+			.mmu_prefetch_max_offset  = 0x00001164,
+			.system_cache_cfg         = 0x00001168,
+			.addr_status_0            = 0x00001170,
+			.addr_status_1            = 0x00001174,
+			.addr_status_2            = 0x00001178,
+			.addr_status_3            = 0x0000117C,
+			.debug_status_cfg         = 0x00001180,
+			.debug_status_0           = 0x00001184,
+			.debug_status_1           = 0x00001188,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_0,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 4 DISP Y */
+		{
+			.cfg                      = 0x00001200,
+			.image_addr               = 0x00001204,
+			.frame_incr               = 0x00001208,
+			.image_cfg_0              = 0x0000120C,
+			.image_cfg_1              = 0x00001210,
+			.image_cfg_2              = 0x00001214,
+			.packer_cfg               = 0x00001218,
+			.frame_header_addr        = 0x00001220,
+			.frame_header_incr        = 0x00001224,
+			.frame_header_cfg         = 0x00001228,
+			.irq_subsample_period     = 0x00001230,
+			.irq_subsample_pattern    = 0x00001234,
+			.framedrop_period         = 0x00001238,
+			.framedrop_pattern        = 0x0000123C,
+			.mmu_prefetch_cfg         = 0x00001260,
+			.mmu_prefetch_max_offset  = 0x00001264,
+			.system_cache_cfg         = 0x00001268,
+			.addr_status_0            = 0x00001270,
+			.addr_status_1            = 0x00001274,
+			.addr_status_2            = 0x00001278,
+			.addr_status_3            = 0x0000127C,
+			.debug_status_cfg         = 0x00001280,
+			.debug_status_0           = 0x00001284,
+			.debug_status_1           = 0x00001288,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_1,
+			.ubwc_regs                = &vfe680_ubwc_regs_client_4,
+		},
+		/* BUS Client 5 DISP C */
+		{
+			.cfg                      = 0x00001300,
+			.image_addr               = 0x00001304,
+			.frame_incr               = 0x00001308,
+			.image_cfg_0              = 0x0000130C,
+			.image_cfg_1              = 0x00001310,
+			.image_cfg_2              = 0x00001314,
+			.packer_cfg               = 0x00001318,
+			.frame_header_addr        = 0x00001320,
+			.frame_header_incr        = 0x00001324,
+			.frame_header_cfg         = 0x00001328,
+			.irq_subsample_period     = 0x00001330,
+			.irq_subsample_pattern    = 0x00001334,
+			.framedrop_period         = 0x00001338,
+			.framedrop_pattern        = 0x0000133C,
+			.mmu_prefetch_cfg         = 0x00001360,
+			.mmu_prefetch_max_offset  = 0x00001364,
+			.system_cache_cfg         = 0x00001368,
+			.addr_status_0            = 0x00001370,
+			.addr_status_1            = 0x00001374,
+			.addr_status_2            = 0x00001378,
+			.addr_status_3            = 0x0000137C,
+			.debug_status_cfg         = 0x00001380,
+			.debug_status_0           = 0x00001384,
+			.debug_status_1           = 0x00001388,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_1,
+			.ubwc_regs                = &vfe680_ubwc_regs_client_5,
+		},
+		/* BUS Client 6 DISP DS4 */
+		{
+			.cfg                      = 0x00001400,
+			.image_addr               = 0x00001404,
+			.frame_incr               = 0x00001408,
+			.image_cfg_0              = 0x0000140C,
+			.image_cfg_1              = 0x00001410,
+			.image_cfg_2              = 0x00001414,
+			.packer_cfg               = 0x00001418,
+			.frame_header_addr        = 0x00001420,
+			.frame_header_incr        = 0x00001424,
+			.frame_header_cfg         = 0x00001428,
+			.irq_subsample_period     = 0x00001430,
+			.irq_subsample_pattern    = 0x00001434,
+			.framedrop_period         = 0x00001438,
+			.framedrop_pattern        = 0x0000143C,
+			.mmu_prefetch_cfg         = 0x00001460,
+			.mmu_prefetch_max_offset  = 0x00001464,
+			.system_cache_cfg         = 0x00001468,
+			.addr_status_0            = 0x00001470,
+			.addr_status_1            = 0x00001474,
+			.addr_status_2            = 0x00001478,
+			.addr_status_3            = 0x0000147C,
+			.debug_status_cfg         = 0x00001480,
+			.debug_status_0           = 0x00001484,
+			.debug_status_1           = 0x00001488,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_1,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 7 DISP DS16 */
+		{
+			.cfg                      = 0x00001500,
+			.image_addr               = 0x00001504,
+			.frame_incr               = 0x00001508,
+			.image_cfg_0              = 0x0000150C,
+			.image_cfg_1              = 0x00001510,
+			.image_cfg_2              = 0x00001514,
+			.packer_cfg               = 0x00001518,
+			.frame_header_addr        = 0x00001520,
+			.frame_header_incr        = 0x00001524,
+			.frame_header_cfg         = 0x00001528,
+			.irq_subsample_period     = 0x00001530,
+			.irq_subsample_pattern    = 0x00001534,
+			.framedrop_period         = 0x00001538,
+			.framedrop_pattern        = 0x0000153C,
+			.mmu_prefetch_cfg         = 0x00001560,
+			.mmu_prefetch_max_offset  = 0x00001564,
+			.system_cache_cfg         = 0x00001568,
+			.addr_status_0            = 0x00001570,
+			.addr_status_1            = 0x00001574,
+			.addr_status_2            = 0x00001578,
+			.addr_status_3            = 0x0000157C,
+			.debug_status_cfg         = 0x00001580,
+			.debug_status_0           = 0x00001584,
+			.debug_status_1           = 0x00001588,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_1,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 8 FD Y */
+		{
+			.cfg                      = 0x00001600,
+			.image_addr               = 0x00001604,
+			.frame_incr               = 0x00001608,
+			.image_cfg_0              = 0x0000160C,
+			.image_cfg_1              = 0x00001610,
+			.image_cfg_2              = 0x00001614,
+			.packer_cfg               = 0x00001618,
+			.frame_header_addr        = 0x00001620,
+			.frame_header_incr        = 0x00001624,
+			.frame_header_cfg         = 0x00001628,
+			.irq_subsample_period     = 0x00001630,
+			.irq_subsample_pattern    = 0x00001634,
+			.framedrop_period         = 0x00001638,
+			.framedrop_pattern        = 0x0000163C,
+			.mmu_prefetch_cfg         = 0x00001660,
+			.mmu_prefetch_max_offset  = 0x00001664,
+			.system_cache_cfg         = 0x00001668,
+			.addr_status_0            = 0x00001670,
+			.addr_status_1            = 0x00001674,
+			.addr_status_2            = 0x00001678,
+			.addr_status_3            = 0x0000167C,
+			.debug_status_cfg         = 0x00001680,
+			.debug_status_0           = 0x00001684,
+			.debug_status_1           = 0x00001688,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_2,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 9 FD C */
+		{
+			.cfg                      = 0x00001700,
+			.image_addr               = 0x00001704,
+			.frame_incr               = 0x00001708,
+			.image_cfg_0              = 0x0000170C,
+			.image_cfg_1              = 0x00001710,
+			.image_cfg_2              = 0x00001714,
+			.packer_cfg               = 0x00001718,
+			.frame_header_addr        = 0x00001720,
+			.frame_header_incr        = 0x00001724,
+			.frame_header_cfg         = 0x00001728,
+			.irq_subsample_period     = 0x00001730,
+			.irq_subsample_pattern    = 0x00001734,
+			.framedrop_period         = 0x00001738,
+			.framedrop_pattern        = 0x0000173C,
+			.mmu_prefetch_cfg         = 0x00001760,
+			.mmu_prefetch_max_offset  = 0x00001764,
+			.system_cache_cfg         = 0x00001768,
+			.addr_status_0            = 0x00001770,
+			.addr_status_1            = 0x00001774,
+			.addr_status_2            = 0x00001778,
+			.addr_status_3            = 0x0000177C,
+			.debug_status_cfg         = 0x00001780,
+			.debug_status_0           = 0x00001784,
+			.debug_status_1           = 0x00001788,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_2,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 10 PIXEL RAW */
+		{
+			.cfg                      = 0x00001800,
+			.image_addr               = 0x00001804,
+			.frame_incr               = 0x00001808,
+			.image_cfg_0              = 0x0000180C,
+			.image_cfg_1              = 0x00001810,
+			.image_cfg_2              = 0x00001814,
+			.packer_cfg               = 0x00001818,
+			.frame_header_addr        = 0x00001820,
+			.frame_header_incr        = 0x00001824,
+			.frame_header_cfg         = 0x00001828,
+			.irq_subsample_period     = 0x00001830,
+			.irq_subsample_pattern    = 0x00001834,
+			.framedrop_period         = 0x00001838,
+			.framedrop_pattern        = 0x0000183C,
+			.mmu_prefetch_cfg         = 0x00001860,
+			.mmu_prefetch_max_offset  = 0x00001864,
+			.system_cache_cfg         = 0x00001868,
+			.addr_status_0            = 0x00001870,
+			.addr_status_1            = 0x00001874,
+			.addr_status_2            = 0x00001878,
+			.addr_status_3            = 0x0000187C,
+			.debug_status_cfg         = 0x00001880,
+			.debug_status_0           = 0x00001884,
+			.debug_status_1           = 0x00001888,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_3,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 11 STATS BE 0 */
+		{
+			.cfg                      = 0x00001900,
+			.image_addr               = 0x00001904,
+			.frame_incr               = 0x00001908,
+			.image_cfg_0              = 0x0000190C,
+			.image_cfg_1              = 0x00001910,
+			.image_cfg_2              = 0x00001914,
+			.packer_cfg               = 0x00001918,
+			.frame_header_addr        = 0x00001920,
+			.frame_header_incr        = 0x00001924,
+			.frame_header_cfg         = 0x00001928,
+			.irq_subsample_period     = 0x00001930,
+			.irq_subsample_pattern    = 0x00001934,
+			.framedrop_period         = 0x00001938,
+			.framedrop_pattern        = 0x0000193C,
+			.mmu_prefetch_cfg         = 0x00001960,
+			.mmu_prefetch_max_offset  = 0x00001964,
+			.system_cache_cfg         = 0x00001968,
+			.addr_status_0            = 0x00001970,
+			.addr_status_1            = 0x00001974,
+			.addr_status_2            = 0x00001978,
+			.addr_status_3            = 0x0000197C,
+			.debug_status_cfg         = 0x00001980,
+			.debug_status_0           = 0x00001984,
+			.debug_status_1           = 0x00001988,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_4,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 12 STATS BHIST 0 */
+		{
+			.cfg                      = 0x00001A00,
+			.image_addr               = 0x00001A04,
+			.frame_incr               = 0x00001A08,
+			.image_cfg_0              = 0x00001A0C,
+			.image_cfg_1              = 0x00001A10,
+			.image_cfg_2              = 0x00001A14,
+			.packer_cfg               = 0x00001A18,
+			.frame_header_addr        = 0x00001A20,
+			.frame_header_incr        = 0x00001A24,
+			.frame_header_cfg         = 0x00001A28,
+			.irq_subsample_period     = 0x00001A30,
+			.irq_subsample_pattern    = 0x00001A34,
+			.framedrop_period         = 0x00001A38,
+			.framedrop_pattern        = 0x00001A3C,
+			.mmu_prefetch_cfg         = 0x00001A60,
+			.mmu_prefetch_max_offset  = 0x00001A64,
+			.system_cache_cfg         = 0x00001A68,
+			.addr_status_0            = 0x00001A70,
+			.addr_status_1            = 0x00001A74,
+			.addr_status_2            = 0x00001A78,
+			.addr_status_3            = 0x00001A7C,
+			.debug_status_cfg         = 0x00001A80,
+			.debug_status_0           = 0x00001A84,
+			.debug_status_1           = 0x00001A88,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_4,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 13 STATS TINTLESS BG */
+		{
+			.cfg                      = 0x00001B00,
+			.image_addr               = 0x00001B04,
+			.frame_incr               = 0x00001B08,
+			.image_cfg_0              = 0x00001B0C,
+			.image_cfg_1              = 0x00001B10,
+			.image_cfg_2              = 0x00001B14,
+			.packer_cfg               = 0x00001B18,
+			.frame_header_addr        = 0x00001B20,
+			.frame_header_incr        = 0x00001B24,
+			.frame_header_cfg         = 0x00001B28,
+			.irq_subsample_period     = 0x00001B30,
+			.irq_subsample_pattern    = 0x00001B34,
+			.framedrop_period         = 0x00001B38,
+			.framedrop_pattern        = 0x00001B3C,
+			.mmu_prefetch_cfg         = 0x00001B60,
+			.mmu_prefetch_max_offset  = 0x00001B64,
+			.system_cache_cfg         = 0x00001B68,
+			.addr_status_0            = 0x00001B70,
+			.addr_status_1            = 0x00001B74,
+			.addr_status_2            = 0x00001B78,
+			.addr_status_3            = 0x00001B7C,
+			.debug_status_cfg         = 0x00001B80,
+			.debug_status_0           = 0x00001B84,
+			.debug_status_1           = 0x00001B88,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_5,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 14 STATS AWB BG */
+		{
+			.cfg                      = 0x00001C00,
+			.image_addr               = 0x00001C04,
+			.frame_incr               = 0x00001C08,
+			.image_cfg_0              = 0x00001C0C,
+			.image_cfg_1              = 0x00001C10,
+			.image_cfg_2              = 0x00001C14,
+			.packer_cfg               = 0x00001C18,
+			.frame_header_addr        = 0x00001C20,
+			.frame_header_incr        = 0x00001C24,
+			.frame_header_cfg         = 0x00001C28,
+			.irq_subsample_period     = 0x00001C30,
+			.irq_subsample_pattern    = 0x00001C34,
+			.framedrop_period         = 0x00001C38,
+			.framedrop_pattern        = 0x00001C3C,
+			.mmu_prefetch_cfg         = 0x00001C60,
+			.mmu_prefetch_max_offset  = 0x00001C64,
+			.system_cache_cfg         = 0x00001C68,
+			.addr_status_0            = 0x00001C70,
+			.addr_status_1            = 0x00001C74,
+			.addr_status_2            = 0x00001C78,
+			.addr_status_3            = 0x00001C7C,
+			.debug_status_cfg         = 0x00001C80,
+			.debug_status_0           = 0x00001C84,
+			.debug_status_1           = 0x00001C88,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_6,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 15 STATS AWB BFW */
+		{
+			.cfg                      = 0x00001D00,
+			.image_addr               = 0x00001D04,
+			.frame_incr               = 0x00001D08,
+			.image_cfg_0              = 0x00001D0C,
+			.image_cfg_1              = 0x00001D10,
+			.image_cfg_2              = 0x00001D14,
+			.packer_cfg               = 0x00001D18,
+			.frame_header_addr        = 0x00001D20,
+			.frame_header_incr        = 0x00001D24,
+			.frame_header_cfg         = 0x00001D28,
+			.irq_subsample_period     = 0x00001D30,
+			.irq_subsample_pattern    = 0x00001D34,
+			.framedrop_period         = 0x00001D38,
+			.framedrop_pattern        = 0x00001D3C,
+			.mmu_prefetch_cfg         = 0x00001D60,
+			.mmu_prefetch_max_offset  = 0x00001D64,
+			.system_cache_cfg         = 0x00001D68,
+			.addr_status_0            = 0x00001D70,
+			.addr_status_1            = 0x00001D74,
+			.addr_status_2            = 0x00001D78,
+			.addr_status_3            = 0x00001D7C,
+			.debug_status_cfg         = 0x00001D80,
+			.debug_status_0           = 0x00001D84,
+			.debug_status_1           = 0x00001D88,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_6,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 16 STATS BAF */
+		{
+			.cfg                      = 0x00001E00,
+			.image_addr               = 0x00001E04,
+			.frame_incr               = 0x00001E08,
+			.image_cfg_0              = 0x00001E0C,
+			.image_cfg_1              = 0x00001E10,
+			.image_cfg_2              = 0x00001E14,
+			.packer_cfg               = 0x00001E18,
+			.frame_header_addr        = 0x00001E20,
+			.frame_header_incr        = 0x00001E24,
+			.frame_header_cfg         = 0x00001E28,
+			.irq_subsample_period     = 0x00001E30,
+			.irq_subsample_pattern    = 0x00001E34,
+			.framedrop_period         = 0x00001E38,
+			.framedrop_pattern        = 0x00001E3C,
+			.mmu_prefetch_cfg         = 0x00001E60,
+			.mmu_prefetch_max_offset  = 0x00001E64,
+			.system_cache_cfg         = 0x00001E68,
+			.addr_status_0            = 0x00001E70,
+			.addr_status_1            = 0x00001E74,
+			.addr_status_2            = 0x00001E78,
+			.addr_status_3            = 0x00001E7C,
+			.debug_status_cfg         = 0x00001E80,
+			.debug_status_0           = 0x00001E84,
+			.debug_status_1           = 0x00001E88,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_7,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 17 STATS BHIST */
+		{
+			.cfg                      = 0x00001F00,
+			.image_addr               = 0x00001F04,
+			.frame_incr               = 0x00001F08,
+			.image_cfg_0              = 0x00001F0C,
+			.image_cfg_1              = 0x00001F10,
+			.image_cfg_2              = 0x00001F14,
+			.packer_cfg               = 0x00001F18,
+			.frame_header_addr        = 0x00001F20,
+			.frame_header_incr        = 0x00001F24,
+			.frame_header_cfg         = 0x00001F28,
+			.irq_subsample_period     = 0x00001F30,
+			.irq_subsample_pattern    = 0x00001F34,
+			.framedrop_period         = 0x00001F38,
+			.framedrop_pattern        = 0x00001F3C,
+			.mmu_prefetch_cfg         = 0x00001F60,
+			.mmu_prefetch_max_offset  = 0x00001F64,
+			.system_cache_cfg         = 0x00001F68,
+			.addr_status_0            = 0x00001F70,
+			.addr_status_1            = 0x00001F74,
+			.addr_status_2            = 0x00001F78,
+			.addr_status_3            = 0x00001F7C,
+			.debug_status_cfg         = 0x00001F80,
+			.debug_status_0           = 0x00001F84,
+			.debug_status_1           = 0x00001F88,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_8,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 18 STATS RS */
+		{
+			.cfg                      = 0x00002000,
+			.image_addr               = 0x00002004,
+			.frame_incr               = 0x00002008,
+			.image_cfg_0              = 0x0000200C,
+			.image_cfg_1              = 0x00002010,
+			.image_cfg_2              = 0x00002014,
+			.packer_cfg               = 0x00002018,
+			.frame_header_addr        = 0x00002020,
+			.frame_header_incr        = 0x00002024,
+			.frame_header_cfg         = 0x00002028,
+			.irq_subsample_period     = 0x00002030,
+			.irq_subsample_pattern    = 0x00002034,
+			.framedrop_period         = 0x00002038,
+			.framedrop_pattern        = 0x0000203C,
+			.mmu_prefetch_cfg         = 0x00002060,
+			.mmu_prefetch_max_offset  = 0x00002064,
+			.system_cache_cfg         = 0x00002068,
+			.addr_status_0            = 0x00002070,
+			.addr_status_1            = 0x00002074,
+			.addr_status_2            = 0x00002078,
+			.addr_status_3            = 0x0000207C,
+			.debug_status_cfg         = 0x00002080,
+			.debug_status_0           = 0x00002084,
+			.debug_status_1           = 0x00002088,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_9,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 19 STATS IHIST */
+		{
+			.cfg                      = 0x00002100,
+			.image_addr               = 0x00002104,
+			.frame_incr               = 0x00002108,
+			.image_cfg_0              = 0x0000210C,
+			.image_cfg_1              = 0x00002110,
+			.image_cfg_2              = 0x00002114,
+			.packer_cfg               = 0x00002118,
+			.frame_header_addr        = 0x00002120,
+			.frame_header_incr        = 0x00002124,
+			.frame_header_cfg         = 0x00002128,
+			.irq_subsample_period     = 0x00002130,
+			.irq_subsample_pattern    = 0x00002134,
+			.framedrop_period         = 0x00002138,
+			.framedrop_pattern        = 0x0000213C,
+			.mmu_prefetch_cfg         = 0x00002160,
+			.mmu_prefetch_max_offset  = 0x00002164,
+			.system_cache_cfg         = 0x00002168,
+			.addr_status_0            = 0x00002170,
+			.addr_status_1            = 0x00002174,
+			.addr_status_2            = 0x00002178,
+			.addr_status_3            = 0x0000217C,
+			.debug_status_cfg         = 0x00002180,
+			.debug_status_0           = 0x00002184,
+			.debug_status_1           = 0x00002188,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_10,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 20 CAMIF PD - PDAF */
+		{
+			.cfg                      = 0x00002200,
+			.image_addr               = 0x00002204,
+			.frame_incr               = 0x00002208,
+			.image_cfg_0              = 0x0000220C,
+			.image_cfg_1              = 0x00002210,
+			.image_cfg_2              = 0x00002214,
+			.packer_cfg               = 0x00002218,
+			.frame_header_addr        = 0x00002220,
+			.frame_header_incr        = 0x00002224,
+			.frame_header_cfg         = 0x00002228,
+			.irq_subsample_period     = 0x00002230,
+			.irq_subsample_pattern    = 0x00002234,
+			.framedrop_period         = 0x00002238,
+			.framedrop_pattern        = 0x0000223C,
+			.mmu_prefetch_cfg         = 0x00002260,
+			.mmu_prefetch_max_offset  = 0x00002264,
+			.system_cache_cfg         = 0x00002268,
+			.addr_status_0            = 0x00002270,
+			.addr_status_1            = 0x00002274,
+			.addr_status_2            = 0x00002278,
+			.addr_status_3            = 0x0000227C,
+			.debug_status_cfg         = 0x00002280,
+			.debug_status_0           = 0x00002284,
+			.debug_status_1           = 0x00002288,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_12,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 21 PDAF V2.0 PD DATA - 2PD */
+		{
+			.cfg                      = 0x00002300,
+			.image_addr               = 0x00002304,
+			.frame_incr               = 0x00002308,
+			.image_cfg_0              = 0x0000230C,
+			.image_cfg_1              = 0x00002310,
+			.image_cfg_2              = 0x00002314,
+			.packer_cfg               = 0x00002318,
+			.frame_header_addr        = 0x00002320,
+			.frame_header_incr        = 0x00002324,
+			.frame_header_cfg         = 0x00002328,
+			.irq_subsample_period     = 0x00002330,
+			.irq_subsample_pattern    = 0x00002334,
+			.framedrop_period         = 0x00002338,
+			.framedrop_pattern        = 0x0000233C,
+			.mmu_prefetch_cfg         = 0x00002360,
+			.mmu_prefetch_max_offset  = 0x00002364,
+			.system_cache_cfg         = 0x00002368,
+			.addr_status_0            = 0x00002370,
+			.addr_status_1            = 0x00002374,
+			.addr_status_2            = 0x00002378,
+			.addr_status_3            = 0x0000237C,
+			.debug_status_cfg         = 0x00002380,
+			.debug_status_0           = 0x00002384,
+			.debug_status_1           = 0x00002388,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_13,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 22 PDAF V2.0 SAD STATS */
+		{
+			.cfg                      = 0x00002400,
+			.image_addr               = 0x00002404,
+			.frame_incr               = 0x00002408,
+			.image_cfg_0              = 0x0000240C,
+			.image_cfg_1              = 0x00002410,
+			.image_cfg_2              = 0x00002414,
+			.packer_cfg               = 0x00002418,
+			.frame_header_addr        = 0x00002420,
+			.frame_header_incr        = 0x00002424,
+			.frame_header_cfg         = 0x00002428,
+			.irq_subsample_period     = 0x00002430,
+			.irq_subsample_pattern    = 0x00002434,
+			.framedrop_period         = 0x00002438,
+			.framedrop_pattern        = 0x0000243C,
+			.mmu_prefetch_cfg         = 0x00002460,
+			.mmu_prefetch_max_offset  = 0x00002464,
+			.system_cache_cfg         = 0x00002468,
+			.addr_status_0            = 0x00002470,
+			.addr_status_1            = 0x00002474,
+			.addr_status_2            = 0x00002478,
+			.addr_status_3            = 0x0000247C,
+			.debug_status_cfg         = 0x00002480,
+			.debug_status_0           = 0x00002484,
+			.debug_status_1           = 0x00002488,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_13,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 23 LCR */
+		{
+			.cfg                      = 0x00002500,
+			.image_addr               = 0x00002504,
+			.frame_incr               = 0x00002508,
+			.image_cfg_0              = 0x0000250C,
+			.image_cfg_1              = 0x00002510,
+			.image_cfg_2              = 0x00002514,
+			.packer_cfg               = 0x00002518,
+			.frame_header_addr        = 0x00002520,
+			.frame_header_incr        = 0x00002524,
+			.frame_header_cfg         = 0x00002528,
+			.irq_subsample_period     = 0x00002530,
+			.irq_subsample_pattern    = 0x00002534,
+			.framedrop_period         = 0x00002538,
+			.framedrop_pattern        = 0x0000253C,
+			.mmu_prefetch_cfg         = 0x00002560,
+			.mmu_prefetch_max_offset  = 0x00002564,
+			.system_cache_cfg         = 0x00002568,
+			.addr_status_0            = 0x00002570,
+			.addr_status_1            = 0x00002574,
+			.addr_status_2            = 0x00002578,
+			.addr_status_3            = 0x0000257C,
+			.debug_status_cfg         = 0x00002580,
+			.debug_status_0           = 0x00002584,
+			.debug_status_1           = 0x00002588,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_11,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 24 RDI0 */
+		{
+			.cfg                      = 0x00002600,
+			.image_addr               = 0x00002604,
+			.frame_incr               = 0x00002608,
+			.image_cfg_0              = 0x0000260C,
+			.image_cfg_1              = 0x00002610,
+			.image_cfg_2              = 0x00002614,
+			.packer_cfg               = 0x00002618,
+			.frame_header_addr        = 0x00002620,
+			.frame_header_incr        = 0x00002624,
+			.frame_header_cfg         = 0x00002628,
+			.irq_subsample_period     = 0x00002630,
+			.irq_subsample_pattern    = 0x00002634,
+			.framedrop_period         = 0x00002638,
+			.framedrop_pattern        = 0x0000263C,
+			.mmu_prefetch_cfg         = 0x00002660,
+			.mmu_prefetch_max_offset  = 0x00002664,
+			.system_cache_cfg         = 0x00002668,
+			.addr_status_0            = 0x00002670,
+			.addr_status_1            = 0x00002674,
+			.addr_status_2            = 0x00002678,
+			.addr_status_3            = 0x0000267C,
+			.debug_status_cfg         = 0x00002680,
+			.debug_status_0           = 0x00002684,
+			.debug_status_1           = 0x00002688,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_14,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 25 RDI1 */
+		{
+			.cfg                      = 0x00002700,
+			.image_addr               = 0x00002704,
+			.frame_incr               = 0x00002708,
+			.image_cfg_0              = 0x0000270C,
+			.image_cfg_1              = 0x00002710,
+			.image_cfg_2              = 0x00002714,
+			.packer_cfg               = 0x00002718,
+			.frame_header_addr        = 0x00002720,
+			.frame_header_incr        = 0x00002724,
+			.frame_header_cfg         = 0x00002728,
+			.irq_subsample_period     = 0x00002730,
+			.irq_subsample_pattern    = 0x00002734,
+			.framedrop_period         = 0x00002738,
+			.framedrop_pattern        = 0x0000273C,
+			.mmu_prefetch_cfg         = 0x00002760,
+			.mmu_prefetch_max_offset  = 0x00002764,
+			.system_cache_cfg         = 0x00002768,
+			.addr_status_0            = 0x00002770,
+			.addr_status_1            = 0x00002774,
+			.addr_status_2            = 0x00002778,
+			.addr_status_3            = 0x0000277C,
+			.debug_status_cfg         = 0x00002780,
+			.debug_status_0           = 0x00002784,
+			.debug_status_1           = 0x00002788,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_15,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 26 RDI2 */
+		{
+			.cfg                      = 0x00002800,
+			.image_addr               = 0x00002804,
+			.frame_incr               = 0x00002808,
+			.image_cfg_0              = 0x0000280C,
+			.image_cfg_1              = 0x00002810,
+			.image_cfg_2              = 0x00002814,
+			.packer_cfg               = 0x00002818,
+			.frame_header_addr        = 0x00002820,
+			.frame_header_incr        = 0x00002824,
+			.frame_header_cfg         = 0x00002828,
+			.irq_subsample_period     = 0x00002830,
+			.irq_subsample_pattern    = 0x00002834,
+			.framedrop_period         = 0x00002838,
+			.framedrop_pattern        = 0x0000283C,
+			.mmu_prefetch_cfg         = 0x00002860,
+			.mmu_prefetch_max_offset  = 0x00002864,
+			.system_cache_cfg         = 0x00002868,
+			.addr_status_0            = 0x00002870,
+			.addr_status_1            = 0x00002874,
+			.addr_status_2            = 0x00002878,
+			.addr_status_3            = 0x0000287C,
+			.debug_status_cfg         = 0x00002880,
+			.debug_status_0           = 0x00002884,
+			.debug_status_1           = 0x00002888,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_16,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 27 LTM STATS */
+		{
+			.cfg                      = 0x00002900,
+			.image_addr               = 0x00002904,
+			.frame_incr               = 0x00002908,
+			.image_cfg_0              = 0x0000290C,
+			.image_cfg_1              = 0x00002910,
+			.image_cfg_2              = 0x00002914,
+			.packer_cfg               = 0x00002918,
+			.frame_header_addr        = 0x00002920,
+			.frame_header_incr        = 0x00002924,
+			.frame_header_cfg         = 0x00002928,
+			.irq_subsample_period     = 0x00002930,
+			.irq_subsample_pattern    = 0x00002934,
+			.framedrop_period         = 0x00002938,
+			.framedrop_pattern        = 0x0000293C,
+			.mmu_prefetch_cfg         = 0x00002960,
+			.mmu_prefetch_max_offset  = 0x00002964,
+			.system_cache_cfg         = 0x00002968,
+			.addr_status_0            = 0x00002970,
+			.addr_status_1            = 0x00002974,
+			.addr_status_2            = 0x00002978,
+			.addr_status_3            = 0x0000297C,
+			.debug_status_cfg         = 0x00002980,
+			.debug_status_0           = 0x00002984,
+			.debug_status_1           = 0x00002988,
+			.comp_group              = CAM_VFE_BUS_VER3_COMP_GRP_3,
+			.ubwc_regs                = NULL,
+		},
+	},
+	.num_out = 27,
+	.vfe_out_hw_info = {
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI0,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_2,
+			.num_wm        = 1,
+			.wm_idx        = {
+				24,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI1,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_3,
+			.num_wm        = 1,
+			.wm_idx        = {
+				25,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI2,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_4,
+			.num_wm        = 1,
+			.wm_idx        = {
+				26,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FULL,
+			.max_width     = 4096,
+			.max_height    = 4096,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 2,
+			.wm_idx        = {
+				0,
+				1,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS4,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				2,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS16,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				3,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				10,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FD,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 2,
+			.wm_idx        = {
+				8,
+				9,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_PDAF,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				20,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				11,
+			},
+		},
+		{
+			.vfe_out_type  =
+				CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BHIST,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				12,
+			},
+		},
+		{
+			.vfe_out_type  =
+				CAM_VFE_BUS_VER3_VFE_OUT_STATS_TL_BG,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				13,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				16,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				14,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				12,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				18,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				19,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP,
+			.max_width     = 4096,
+			.max_height    = 4096,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 2,
+			.wm_idx        = {
+				4,
+				5,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				6,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				7,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_2PD,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_1,
+			.num_wm        = 1,
+			.wm_idx        = {
+				21,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_LCR,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				23,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_AWB_BFW,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				15,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_2PD_STATS,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_1,
+			.num_wm        = 1,
+			.wm_idx        = {
+				22,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_AEC_BE,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				11,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_LTM_STATS,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				27,
+			},
+		},
+		{
+			.vfe_out_type  =
+				CAM_VFE_BUS_VER3_VFE_OUT_STATS_GTM_BHIST,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				17,
+			},
+		},
+	},
+	.num_comp_grp    = 17,
+	.comp_done_shift = 0,
+	.top_irq_shift   = 1,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 33,
+};
+
+
+static struct cam_vfe_hw_info cam_vfe680_hw_info = {
+	.irq_reg_info                  = &vfe680_top_irq_reg_info,
+
+	.bus_version                   = CAM_VFE_BUS_VER_3_0,
+	.bus_hw_info                   = &vfe680_bus_hw_info,
+
+	.bus_rd_version                = NULL,
+	.bus_rd_hw_info                = NULL,
+
+	.top_version                   = CAM_VFE_TOP_VER_4_0,
+	.top_hw_info                   = &vfe680_top_hw_info,
+};
+
+#endif /* _CAM_VFE680_H_ */

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h

@@ -334,6 +334,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe17x_bus_hw_info = {
 	},
 	.top_irq_shift = 9,
 	.support_consumed_addr = false,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 23,
 };
 
 static struct cam_vfe_hw_info cam_vfe_lite17x_hw_info = {

+ 20 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h

@@ -374,6 +374,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
 			.mid[0]        = 16,
+			.num_wm        = 1,
+			.wm_idx        = {
+				0,
+			},
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI1,
@@ -381,6 +385,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_1,
 			.mid[0]        = 17,
+			.num_wm        = 1,
+			.wm_idx        = {
+				1,
+			},
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI2,
@@ -388,6 +396,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_2,
 			.mid[0]        = 18,
+			.num_wm        = 1,
+			.wm_idx        = {
+				2,
+			},
 		},
 		{
 			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI3,
@@ -395,11 +407,19 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = {
 			.max_height    = -1,
 			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_3,
 			.mid[0]        = 19,
+			.num_wm        = 1,
+			.wm_idx        = {
+				3,
+			},
 		},
 	},
+	.num_comp_grp    = 4,
 	.comp_done_shift = 4,
 	.top_irq_shift   = 4,
 	.support_consumed_addr = true,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 25,
+	.supported_irq =  CAM_VFE_HW_IRQ_CAP_BUF_DONE | CAM_VFE_HW_IRQ_CAP_RUP,
+	.comp_cfg_needed = true,
 };
 
 static struct cam_vfe_hw_info cam_vfe_lite48x_hw_info = {

+ 314 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h

@@ -0,0 +1,314 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+
+#ifndef _CAM_VFE_LITE680X_H_
+#define _CAM_VFE_LITE680X_H_
+#include "cam_vfe_camif_ver3.h"
+#include "cam_vfe_top_ver3.h"
+#include "cam_vfe_core.h"
+#include "cam_vfe_bus_ver3.h"
+#include "cam_irq_controller.h"
+
+static struct cam_irq_register_set vfe680x_bus_irq_reg[2] = {
+		{
+			.mask_reg_offset   = 0x00000218,
+			.clear_reg_offset  = 0x00000220,
+			.status_reg_offset = 0x00000228,
+		},
+		{
+			.mask_reg_offset   = 0x0000021C,
+			.clear_reg_offset  = 0x00000224,
+			.status_reg_offset = 0x0000022C,
+		},
+};
+
+static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = {
+	.common_reg = {
+		.hw_version                       = 0x00000200,
+		.cgc_ovd                          = 0x00000208,
+		.if_frameheader_cfg               = {
+			0x00000234,
+			0x00000238,
+			0x0000023C,
+			0x00000240,
+			0x00000244,
+		},
+		.pwr_iso_cfg                      = 0x0000025C,
+		.overflow_status_clear            = 0x00000260,
+		.ccif_violation_status            = 0x00000264,
+		.overflow_status                  = 0x00000268,
+		.image_size_violation_status      = 0x00000270,
+		.debug_status_top_cfg             = 0x000002D4,
+		.debug_status_top                 = 0x000002D8,
+		.test_bus_ctrl                    = 0x000002DC,
+		.irq_reg_info = {
+			.num_registers            = 2,
+			.irq_reg_set              = vfe680x_bus_irq_reg,
+			.global_clear_offset      = 0x00000230,
+			.global_clear_bitmask     = 0x00000001,
+		},
+	},
+	.num_client = 6,
+	.bus_client_reg = {
+		/* BUS Client 0 RDI0 */
+		{
+			.cfg                      = 0x00000400,
+			.image_addr               = 0x00000404,
+			.frame_incr               = 0x00000408,
+			.image_cfg_0              = 0x0000040C,
+			.image_cfg_1              = 0x00000410,
+			.image_cfg_2              = 0x00000414,
+			.packer_cfg               = 0x00000418,
+			.frame_header_addr        = 0x00000420,
+			.frame_header_incr        = 0x00000424,
+			.frame_header_cfg         = 0x00000428,
+			.irq_subsample_period     = 0x00000430,
+			.irq_subsample_pattern    = 0x00000434,
+			.framedrop_period         = 0x00000438,
+			.framedrop_pattern        = 0x0000043C,
+			.mmu_prefetch_cfg         = 0x00000460,
+			.mmu_prefetch_max_offset  = 0x00000464,
+			.system_cache_cfg         = 0x00000468,
+			.addr_status_0            = 0x00000470,
+			.addr_status_1            = 0x00000474,
+			.addr_status_2            = 0x00000478,
+			.addr_status_3            = 0x0000047C,
+			.debug_status_cfg         = 0x00000480,
+			.debug_status_0           = 0x00000484,
+			.debug_status_1           = 0x00000488,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_1,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 1 RDI1 */
+		{
+			.cfg                      = 0x00000500,
+			.image_addr               = 0x00000504,
+			.frame_incr               = 0x00000508,
+			.image_cfg_0              = 0x0000050C,
+			.image_cfg_1              = 0x00000510,
+			.image_cfg_2              = 0x00000514,
+			.packer_cfg               = 0x00000518,
+			.frame_header_addr        = 0x00000520,
+			.frame_header_incr        = 0x00000524,
+			.frame_header_cfg         = 0x00000528,
+			.irq_subsample_period     = 0x00000530,
+			.irq_subsample_pattern    = 0x00000534,
+			.framedrop_period         = 0x00000538,
+			.framedrop_pattern        = 0x0000053C,
+			.mmu_prefetch_cfg         = 0x00000560,
+			.mmu_prefetch_max_offset  = 0x00000564,
+			.system_cache_cfg         = 0x00000568,
+			.addr_status_0            = 0x00000570,
+			.addr_status_1            = 0x00000574,
+			.addr_status_2            = 0x00000578,
+			.addr_status_3            = 0x0000057C,
+			.debug_status_cfg         = 0x00000580,
+			.debug_status_0           = 0x00000584,
+			.debug_status_1           = 0x00000588,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_2,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 2 RDI2 */
+		{
+			.cfg                      = 0x00000600,
+			.image_addr               = 0x00000604,
+			.frame_incr               = 0x00000608,
+			.image_cfg_0              = 0x0000060C,
+			.image_cfg_1              = 0x00000610,
+			.image_cfg_2              = 0x00000614,
+			.packer_cfg               = 0x00000618,
+			.frame_header_addr        = 0x00000620,
+			.frame_header_incr        = 0x00000624,
+			.frame_header_cfg         = 0x00000628,
+			.irq_subsample_period     = 0x00000630,
+			.irq_subsample_pattern    = 0x00000634,
+			.framedrop_period         = 0x00000638,
+			.framedrop_pattern        = 0x0000063C,
+			.mmu_prefetch_cfg         = 0x00000660,
+			.mmu_prefetch_max_offset  = 0x00000664,
+			.system_cache_cfg         = 0x00000668,
+			.addr_status_0            = 0x00000670,
+			.addr_status_1            = 0x00000674,
+			.addr_status_2            = 0x00000678,
+			.addr_status_3            = 0x0000067C,
+			.debug_status_cfg         = 0x00000680,
+			.debug_status_0           = 0x00000684,
+			.debug_status_1           = 0x00000688,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_3,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 3 RDI3 */
+		{
+			.cfg                      = 0x00000700,
+			.image_addr               = 0x00000704,
+			.frame_incr               = 0x00000708,
+			.image_cfg_0              = 0x0000070C,
+			.image_cfg_1              = 0x00000710,
+			.image_cfg_2              = 0x00000714,
+			.packer_cfg               = 0x00000718,
+			.frame_header_addr        = 0x00000720,
+			.frame_header_incr        = 0x00000724,
+			.frame_header_cfg         = 0x00000728,
+			.irq_subsample_period     = 0x00000730,
+			.irq_subsample_pattern    = 0x00000734,
+			.framedrop_period         = 0x00000738,
+			.framedrop_pattern        = 0x0000073C,
+			.mmu_prefetch_cfg         = 0x00000760,
+			.mmu_prefetch_max_offset  = 0x00000764,
+			.system_cache_cfg         = 0x00000768,
+			.addr_status_0            = 0x00000770,
+			.addr_status_1            = 0x00000774,
+			.addr_status_2            = 0x00000778,
+			.addr_status_3            = 0x0000077C,
+			.debug_status_cfg         = 0x00000780,
+			.debug_status_0           = 0x00000784,
+			.debug_status_1           = 0x00000788,
+			.comp_group               = CAM_VFE_BUS_VER3_COMP_GRP_4,
+			.ubwc_regs                = NULL,
+		},
+		/* BUS Client 4 Gamma */
+		{
+			.cfg			  = 0x00000800,
+			.image_addr		  = 0x00000804,
+			.frame_incr		  = 0x00000808,
+			.image_cfg_0		  = 0x0000080C,
+			.image_cfg_1		  = 0x00000810,
+			.image_cfg_2		  = 0x00000814,
+			.packer_cfg		  = 0x00000818,
+			.frame_header_addr	  = 0x00000820,
+			.frame_header_incr	  = 0x00000824,
+			.frame_header_cfg	  = 0x00000828,
+			.irq_subsample_period	  = 0x00000830,
+			.irq_subsample_pattern	  = 0x00000834,
+			.framedrop_period	  = 0x00000838,
+			.framedrop_pattern	  = 0x0000083C,
+			.mmu_prefetch_cfg	  = 0x00000860,
+			.mmu_prefetch_max_offset  = 0x00000864,
+			.system_cache_cfg	  = 0x00000868,
+			.addr_status_0		  = 0x00000870,
+			.addr_status_1		  = 0x00000874,
+			.addr_status_2		  = 0x00000878,
+			.addr_status_3		  = 0x0000087C,
+			.debug_status_cfg	  = 0x00000880,
+			.debug_status_0		  = 0x00000884,
+			.debug_status_1		  = 0x00000888,
+			.comp_group		  = CAM_VFE_BUS_VER3_COMP_GRP_0,
+			.ubwc_regs		  = NULL,
+		},
+		/* BUS Client 5 Stats BE */
+		{
+			.cfg			  = 0x00000900,
+			.image_addr		  = 0x00000904,
+			.frame_incr		  = 0x00000908,
+			.image_cfg_0		  = 0x0000090C,
+			.image_cfg_1		  = 0x00000910,
+			.image_cfg_2		  = 0x00000914,
+			.packer_cfg		  = 0x00000918,
+			.frame_header_addr	  = 0x00000920,
+			.frame_header_incr	  = 0x00000924,
+			.frame_header_cfg	  = 0x00000928,
+			.irq_subsample_period	  = 0x00000930,
+			.irq_subsample_pattern	  = 0x00000934,
+			.framedrop_period	  = 0x00000938,
+			.framedrop_pattern	  = 0x0000093C,
+			.mmu_prefetch_cfg	  = 0x00000960,
+			.mmu_prefetch_max_offset  = 0x00000964,
+			.system_cache_cfg	  = 0x00000968,
+			.addr_status_0		  = 0x00000970,
+			.addr_status_1		  = 0x00000974,
+			.addr_status_2		  = 0x00000978,
+			.addr_status_3		  = 0x0000097C,
+			.debug_status_cfg	  = 0x00000980,
+			.debug_status_0		  = 0x00000984,
+			.debug_status_1		  = 0x00000988,
+			.comp_group		  = CAM_VFE_BUS_VER3_COMP_GRP_0,
+			.ubwc_regs		  = NULL,
+		},
+	},
+	.num_out = 6,
+	.vfe_out_hw_info = {
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI0,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_1,
+			.num_wm        = 1,
+			.wm_idx        = {
+				0,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI1,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_2,
+			.num_wm        = 1,
+			.wm_idx        = {
+				1,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI2,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_3,
+			.num_wm        = 1,
+			.wm_idx        = {
+				2,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_RDI3,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_4,
+			.num_wm        = 1,
+			.wm_idx        = {
+				3,
+			},
+		},
+		{
+			.vfe_out_type  =
+				CAM_VFE_BUS_VER3_VFE_OUT_GAMMA,
+			.max_width     = 1920,
+			.max_height    = 1080,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				4,
+			},
+		},
+		{
+			.vfe_out_type  = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BE,
+			.max_width     = -1,
+			.max_height    = -1,
+			.source_group  = CAM_VFE_BUS_VER3_SRC_GRP_0,
+			.num_wm        = 1,
+			.wm_idx        = {
+				5,
+			},
+		},
+	},
+	.num_comp_grp    = 4,
+	.comp_done_shift = 0,
+	.top_irq_shift   = 1,
+	.max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 33,
+};
+
+static struct cam_vfe_hw_info cam_vfe_lite68x_hw_info = {
+	.irq_reg_info                  =,
+
+	.bus_version                   = CAM_VFE_BUS_VER_3_0,
+	.bus_hw_info                   = &vfe680x_bus_hw_info,
+
+	.bus_rd_version                = NULL,
+	.bus_rd_hw_info                = NULL,
+
+	.top_version                   =,
+	.top_hw_info                   =,
+};
+
+#endif /* _CAM_VFE_LITE680X_H_ */

+ 13 - 8
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c

@@ -201,6 +201,7 @@ struct cam_vfe_bus_ver2_priv {
 	int                                 irq_handle;
 	int                                 error_irq_handle;
 	void                               *tasklet_info;
+	uint32_t                            max_out_res;
 };
 
 static int cam_vfe_bus_process_cmd(
@@ -3394,7 +3395,7 @@ static int cam_vfe_bus_update_stripe_cfg(void *priv, void *cmd_args,
 
 	outport_id = stripe_args->res->res_id & 0xFF;
 	if (stripe_args->res->res_id < CAM_ISP_IFE_OUT_RES_BASE ||
-		stripe_args->res->res_id >= CAM_ISP_IFE_OUT_RES_MAX)
+		stripe_args->res->res_id >= bus_priv->max_out_res)
 		return 0;
 
 	ports_plane_idx = (stripe_args->split_id *
@@ -3637,7 +3638,8 @@ static int cam_vfe_bus_process_cmd(
 	int rc = -EINVAL;
 	struct cam_vfe_bus_ver2_priv		 *bus_priv;
 	uint32_t top_mask_0 = 0;
-	bool *support_consumed_addr;
+	struct cam_isp_hw_bus_cap *vfe_bus_cap;
+
 
 	if (!priv || !cmd_args) {
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments");
@@ -3684,12 +3686,6 @@ static int cam_vfe_bus_process_cmd(
 		cam_io_w_mb(top_mask_0, bus_priv->common_data.mem_base +
 			bus_priv->common_data.common_reg->top_irq_mask_0);
 		break;
-	case CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT:
-		bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
-		support_consumed_addr = (bool *)cmd_args;
-		*support_consumed_addr =
-			bus_priv->common_data.support_consumed_addr;
-		break;
 	case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
 		bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
 		rc = cam_vfe_bus_get_res_for_mid(bus_priv, cmd_args, arg_size);
@@ -3697,6 +3693,14 @@ static int cam_vfe_bus_process_cmd(
 	case CAM_ISP_HW_CMD_DISABLE_UBWC_COMP:
 		bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
 		bus_priv->common_data.disable_ubwc_comp = true;
+		break;
+	case CAM_ISP_HW_CMD_QUERY_BUS_CAP:
+		bus_priv = (struct cam_vfe_bus_ver2_priv  *) priv;
+		vfe_bus_cap = (struct cam_isp_hw_bus_cap *) cmd_args;
+		vfe_bus_cap->max_vfe_out_res_type = bus_priv->max_out_res;
+		vfe_bus_cap->support_consumed_addr =
+			bus_priv->common_data.support_consumed_addr;
+
 		break;
 	default:
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
@@ -3749,6 +3753,7 @@ int cam_vfe_bus_ver2_init(
 	bus_priv->num_client                     = ver2_hw_info->num_client;
 	bus_priv->num_out                        = ver2_hw_info->num_out;
 	bus_priv->top_irq_shift                  = ver2_hw_info->top_irq_shift;
+	bus_priv->max_out_res                    = ver2_hw_info->max_out_res;
 	bus_priv->common_data.num_sec_out        = 0;
 	bus_priv->common_data.secure_mode        = CAM_SECURE_MODE_NON_SECURE;
 	bus_priv->common_data.core_index         = soc_info->index;

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h

@@ -182,6 +182,7 @@ struct cam_vfe_bus_ver2_vfe_out_hw_info {
  * @vfe_out_hw_info:       VFE output capability
  * @top_irq_shift:         Mask shift for top level BUS WR irq
  * @support_consumed_addr: Indicate if bus support consumed address
+ * @max_out_res:           Max vfe out resource value supported for hw
  */
 struct cam_vfe_bus_ver2_hw_info {
 	struct cam_vfe_bus_ver2_reg_offset_common common_reg;
@@ -195,6 +196,7 @@ struct cam_vfe_bus_ver2_hw_info {
 		vfe_out_hw_info[CAM_VFE_BUS_VER2_VFE_OUT_MAX];
 	uint32_t top_irq_shift;
 	bool support_consumed_addr;
+	uint32_t max_out_res;
 };
 
 /*

File diff suppressed because it is too large
+ 237 - 510
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c


+ 26 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h

@@ -10,9 +10,10 @@
 #include "cam_irq_controller.h"
 #include "cam_vfe_bus.h"
 
-#define CAM_VFE_BUS_VER3_MAX_CLIENTS     26
-#define CAM_VFE_BUS_VER3_MAX_SUB_GRPS     6
+#define CAM_VFE_BUS_VER3_MAX_SUB_GRPS        6
 #define CAM_VFE_BUS_VER3_MAX_MID_PER_PORT 4
+#define CAM_VFE_BUS_VER3_480_MAX_CLIENTS     26
+#define CAM_VFE_BUS_VER3_680_MAX_CLIENTS     28
 
 enum cam_vfe_bus_ver3_vfe_core_id {
 	CAM_VFE_BUS_VER3_VFE_CORE_0,
@@ -45,6 +46,9 @@ enum cam_vfe_bus_ver3_comp_grp_type {
 	CAM_VFE_BUS_VER3_COMP_GRP_11,
 	CAM_VFE_BUS_VER3_COMP_GRP_12,
 	CAM_VFE_BUS_VER3_COMP_GRP_13,
+	CAM_VFE_BUS_VER3_COMP_GRP_14,
+	CAM_VFE_BUS_VER3_COMP_GRP_15,
+	CAM_VFE_BUS_VER3_COMP_GRP_16,
 	CAM_VFE_BUS_VER3_COMP_GRP_MAX,
 };
 
@@ -73,6 +77,13 @@ enum cam_vfe_bus_ver3_vfe_out_type {
 	CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP,
 	CAM_VFE_BUS_VER3_VFE_OUT_2PD,
 	CAM_VFE_BUS_VER3_VFE_OUT_LCR,
+	CAM_VFE_BUS_VER3_VFE_OUT_AWB_BFW,
+	CAM_VFE_BUS_VER3_VFE_OUT_2PD_STATS,
+	CAM_VFE_BUS_VER3_VFE_OUT_STATS_AEC_BE,
+	CAM_VFE_BUS_VER3_VFE_OUT_LTM_STATS,
+	CAM_VFE_BUS_VER3_VFE_OUT_STATS_GTM_BHIST,
+	CAM_VFE_BUS_VER3_VFE_OUT_STATS_BE,
+	CAM_VFE_BUS_VER3_VFE_OUT_GAMMA,
 	CAM_VFE_BUS_VER3_VFE_OUT_MAX,
 };
 
@@ -138,6 +149,8 @@ struct cam_vfe_bus_ver3_reg_offset_bus_client {
 	uint32_t irq_subsample_pattern;
 	uint32_t framedrop_period;
 	uint32_t framedrop_pattern;
+	uint32_t mmu_prefetch_cfg;
+	uint32_t mmu_prefetch_max_offset;
 	uint32_t burst_limit;
 	uint32_t system_cache_cfg;
 	void    *ubwc_regs;
@@ -162,6 +175,8 @@ struct cam_vfe_bus_ver3_vfe_out_hw_info {
 	uint32_t                            max_height;
 	uint32_t                            source_group;
 	uint32_t                         mid[CAM_VFE_BUS_VER3_MAX_MID_PER_PORT];
+	uint32_t                            num_wm;
+	uint32_t                            wm_idx[PLANE_MAX];
 };
 
 /*
@@ -173,21 +188,29 @@ struct cam_vfe_bus_ver3_vfe_out_hw_info {
  * @num_client:            Total number of write clients
  * @bus_client_reg:        Bus client register info
  * @vfe_out_hw_info:       VFE output capability
+ * @num_comp_grp:          Number of composite groups
  * @comp_done_shift:       Mask shift for comp done mask
  * @top_irq_shift:         Mask shift for top level BUS WR irq
  * @support_consumed_addr: Indicate if bus support consumed address
+ * @max_out_res:           Max vfe out resource value supported for hw
+ * @supported_irq:         Mask to indicate the IRQ supported
+ * @comp_cfg_needed:       Composite group config is needed for hw
  */
 struct cam_vfe_bus_ver3_hw_info {
 	struct cam_vfe_bus_ver3_reg_offset_common common_reg;
 	uint32_t num_client;
 	struct cam_vfe_bus_ver3_reg_offset_bus_client
-		bus_client_reg[CAM_VFE_BUS_VER3_MAX_CLIENTS];
+		bus_client_reg[CAM_VFE_BUS_VER3_680_MAX_CLIENTS];
 	uint32_t num_out;
 	struct cam_vfe_bus_ver3_vfe_out_hw_info
 		vfe_out_hw_info[CAM_VFE_BUS_VER3_VFE_OUT_MAX];
+	uint32_t num_comp_grp;
 	uint32_t comp_done_shift;
 	uint32_t top_irq_shift;
 	bool support_consumed_addr;
+	uint32_t max_out_res;
+	uint32_t supported_irq;
+	bool comp_cfg_needed;
 };
 
 /*

+ 4 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c

@@ -426,10 +426,11 @@ static int cam_vfe_camif_resource_start(
 	default:
 		epoch0_irq_mask = (((rsrc_data->last_line +
 				rsrc_data->vbi_value) -
-				rsrc_data->first_line) / 2) +
+				rsrc_data->first_line) / 2);
+		if ((epoch0_irq_mask) >
+			(rsrc_data->last_line - rsrc_data->first_line))
+			epoch0_irq_mask = rsrc_data->last_line -
 				rsrc_data->first_line;
-		if (epoch0_irq_mask > rsrc_data->last_line)
-			epoch0_irq_mask = rsrc_data->last_line;
 
 		epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg &
 				0xFFFF;

+ 4 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c

@@ -471,8 +471,10 @@ static int cam_vfe_camif_ver3_resource_start(
 		epoch0_line_cfg = ((rsrc_data->last_line +
 			rsrc_data->vbi_value) -
 			rsrc_data->first_line) / 4;
-		if (epoch0_line_cfg > rsrc_data->last_line)
-			epoch0_line_cfg = rsrc_data->last_line;
+		if ((epoch0_line_cfg * 2) >
+			(rsrc_data->last_line - rsrc_data->first_line))
+			epoch0_line_cfg = (rsrc_data->last_line -
+				rsrc_data->first_line)/2;
 	/* epoch line cfg will still be configured at midpoint of the
 	 * frame width. We use '/ 4' instead of '/ 2'
 	 * cause it is multipixel path

+ 3 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.c

@@ -307,9 +307,9 @@ static int cam_vfe_fe_resource_start(
 
 	/* epoch config */
 	epoch0_irq_mask = (((rsrc_data->last_line + rsrc_data->vbi_value) -
-		rsrc_data->first_line) / 2) + rsrc_data->first_line;
-	if (epoch0_irq_mask > rsrc_data->last_line)
-		epoch0_irq_mask = rsrc_data->last_line;
+		rsrc_data->first_line) / 2);
+	if (epoch0_irq_mask > (rsrc_data->last_line - rsrc_data->first_line))
+		epoch0_irq_mask = rsrc_data->last_line - rsrc_data->first_line;
 
 	epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg & 0xFFFF;
 	computed_epoch_line_cfg = (epoch0_irq_mask << 16) | epoch1_irq_mask;

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include/cam_vfe_top.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE_TOP_H_
@@ -12,6 +12,7 @@
 #define CAM_VFE_TOP_VER_1_0 0x100000
 #define CAM_VFE_TOP_VER_2_0 0x200000
 #define CAM_VFE_TOP_VER_3_0 0x300000
+#define CAM_VFE_TOP_VER_4_0 0x400000
 
 #define CAM_VFE_CAMIF_VER_1_0 0x10
 #define CAM_VFE_CAMIF_VER_2_0 0x20

+ 3 - 0
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c

@@ -139,6 +139,9 @@ static int cam_jpeg_process_next_hw_update(void *priv, void *data,
 		rc = -EINVAL;
 		goto end_error;
 	}
+
+	CAM_TRACE(CAM_JPEG, "Start JPEG ENC Req %llu", config_args->request_id);
+
 	rc = hw_mgr->devices[dev_type][0]->hw_ops.start(
 		hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0);
 	if (rc) {

+ 1 - 0
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c

@@ -202,6 +202,7 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
 	if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) {
 		spin_lock(&jpeg_enc_dev->hw_lock);
 		if (core_info->core_state == CAM_JPEG_ENC_CORE_READY) {
+			CAM_TRACE(CAM_JPEG, "FrameDone IRQ");
 			encoded_size = cam_io_r_mb(mem_base +
 			core_info->jpeg_enc_hw_info->reg_offset.encode_size);
 			if (core_info->irq_cb.jpeg_hw_mgr_cb) {

+ 4 - 4
drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c

@@ -1647,11 +1647,11 @@ static void cam_ope_ctx_cdm_callback(uint32_t handle, void *userdata,
 		if (!rc)
 			goto end;
 	} else {
-		CAM_ERR(CAM_OPE,
+		CAM_INFO(CAM_OPE,
 			"CDM hdl=%x, udata=%pK, status=%d, cookie=%d req_id = %llu ctx_id=%d",
 			 handle, userdata, status, cookie,
 			 ope_req->request_id, ctx->ctx_id);
-		CAM_ERR(CAM_OPE, "Rst of CDM and OPE for error reqid = %lld",
+		CAM_INFO(CAM_OPE, "Rst of CDM and OPE for error reqid = %lld",
 			ope_req->request_id);
 		if (status != CAM_CDM_CB_STATUS_HW_FLUSH) {
 			cam_ope_dump_req_data(ope_req);
@@ -2657,8 +2657,6 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
 
 		hw_mgr->clk_info.base_clk =
 			soc_info->clk_rate[CAM_TURBO_VOTE][idx];
-		hw_mgr->clk_info.curr_clk =
-			soc_info->clk_rate[CAM_TURBO_VOTE][idx];
 		hw_mgr->clk_info.threshold = 5;
 		hw_mgr->clk_info.over_clked = 0;
 
@@ -2689,6 +2687,8 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
 		soc_info = &dev->soc_info;
 		idx = soc_info->src_clk_idx;
 		clk_update.clk_rate = soc_info->clk_rate[CAM_TURBO_VOTE][idx];
+		hw_mgr->clk_info.curr_clk =
+			soc_info->clk_rate[CAM_TURBO_VOTE][idx];
 
 		rc = hw_mgr->ope_dev_intf[i]->hw_ops.process_cmd(
 			hw_mgr->ope_dev_intf[i]->hw_priv, OPE_HW_CLK_UPDATE,

+ 95 - 31
drivers/cam_req_mgr/cam_req_mgr_core.c

@@ -15,6 +15,7 @@
 #include "cam_trace.h"
 #include "cam_debug_util.h"
 #include "cam_req_mgr_dev.h"
+#include "cam_req_mgr_debug.h"
 
 static struct cam_req_mgr_core_device *g_crm_core_dev;
 static struct cam_req_mgr_core_link g_links[MAXIMUM_LINKS_PER_SESSION];
@@ -313,6 +314,10 @@ static int __cam_req_mgr_notify_error_on_link(
 	int rc = 0, pd;
 
 	session = (struct cam_req_mgr_core_session *)link->parent;
+	if (!session) {
+		CAM_WARN(CAM_CRM, "session ptr NULL %x", link->link_hdl);
+		return -EINVAL;
+	}
 
 	pd = dev->dev_info.p_delay;
 	if (pd >= CAM_PIPELINE_DELAY_MAX) {
@@ -557,6 +562,8 @@ static void __cam_req_mgr_flush_req_slot(
 	in_q->rd_idx = 0;
 	link->trigger_cnt[0] = 0;
 	link->trigger_cnt[1] = 0;
+	link->trigger_mask = 0;
+	link->subscribe_event &= ~CAM_TRIGGER_POINT_EOF;
 }
 
 /**
@@ -810,12 +817,6 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
 			continue;
 		}
 
-		if (slot->ops.apply_at_eof && slot->ops.skip_next_frame) {
-			CAM_ERR(CAM_CRM,
-				"Both EOF and SOF trigger is not supported");
-			return -EINVAL;
-		}
-
 		if (dev->dev_hdl != slot->ops.dev_hdl) {
 			CAM_DBG(CAM_CRM,
 				"Dev_hdl : %d Not matched:: Expected dev_hdl: %d",
@@ -1115,12 +1116,19 @@ static int __cam_req_mgr_check_sync_for_mslave(
 	int64_t req_id = 0, sync_req_id = 0;
 	int32_t sync_num_slots = 0;
 
-	if (!sync_link) {
-		CAM_ERR(CAM_CRM, "Sync link null");
+	if (!sync_link  || !link) {
+		CAM_ERR(CAM_CRM, "Sync link or link is null");
 		return -EINVAL;
 	}
 
 	req_id = slot->req_id;
+
+	if (!sync_link->req.in_q) {
+		CAM_ERR(CAM_CRM, "Link hdl %x in_q is NULL",
+			sync_link->link_hdl);
+		return -EINVAL;
+	}
+
 	sync_num_slots = sync_link->req.in_q->num_slots;
 	sync_rd_idx = sync_link->req.in_q->rd_idx;
 
@@ -1188,7 +1196,6 @@ static int __cam_req_mgr_check_sync_for_mslave(
 			(sync_link->initial_sync_req <= sync_req_id)) {
 			sync_slot_idx = __cam_req_mgr_find_slot_for_req(
 				sync_link->req.in_q, sync_req_id);
-
 			if (sync_slot_idx == -1) {
 				CAM_DBG(CAM_CRM,
 					"Prev Req: %lld [master] not found on link: %x [slave]",
@@ -1322,20 +1329,27 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 	uint64_t master_slave_diff = 0;
 	bool ready = true, sync_ready = true;
 
-	if (!sync_link) {
+	if (!sync_link || !link) {
 		CAM_ERR(CAM_CRM, "Sync link null");
 		return -EINVAL;
 	}
 
 	req_id = slot->req_id;
+
+	if (!sync_link->req.in_q) {
+		CAM_ERR(CAM_CRM, "Link hdl %x in_q is NULL",
+			sync_link->link_hdl);
+		return -EINVAL;
+	}
+
 	sync_num_slots = sync_link->req.in_q->num_slots;
-	sync_rd_idx = sync_link->req.in_q->rd_idx;
-	sync_rd_slot = &sync_link->req.in_q->slot[sync_rd_idx];
-	sync_req_id = sync_rd_slot->req_id;
+	sync_rd_idx    = sync_link->req.in_q->rd_idx;
+	sync_rd_slot   = &sync_link->req.in_q->slot[sync_rd_idx];
+	sync_req_id    = sync_rd_slot->req_id;
 
 	CAM_DBG(CAM_REQ,
-		"link_hdl %x req %lld frame_skip_flag %d ",
-		link->link_hdl, req_id, link->sync_link_sof_skip);
+		"link_hdl %x sync link_hdl %x req %lld",
+		link->link_hdl, sync_link->link_hdl, req_id);
 
 	if (sync_link->initial_skip) {
 		link->initial_skip = false;
@@ -1439,13 +1453,20 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 		ready = false;
 	}
 
-	rc = __cam_req_mgr_check_link_is_ready(sync_link, sync_slot_idx, true);
-	if (rc && (sync_link->req.in_q->slot[sync_slot_idx].status !=
-		CRM_SLOT_STATUS_REQ_APPLIED)) {
-		CAM_DBG(CAM_CRM,
-			"Req: %lld not ready on [other link] link: %x, rc=%d",
-			req_id, sync_link->link_hdl, rc);
-		sync_ready = false;
+	if (sync_link->req.in_q) {
+		rc = __cam_req_mgr_check_link_is_ready(sync_link,
+			sync_slot_idx, true);
+		if (rc && (sync_link->req.in_q->slot[sync_slot_idx].status !=
+				CRM_SLOT_STATUS_REQ_APPLIED)) {
+			CAM_DBG(CAM_CRM,
+				"Req: %lld not ready on link: %x, rc=%d",
+				req_id, sync_link->link_hdl, rc);
+			sync_ready = false;
+		}
+	} else {
+		CAM_ERR(CAM_CRM, "Link hdl %x in_q is NULL",
+			sync_link->link_hdl);
+		return -EINVAL;
 	}
 
 	/*
@@ -1511,7 +1532,6 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 			return -EAGAIN;
 		}
 	}
-
 	CAM_DBG(CAM_REQ,
 		"Req: %lld ready to apply on link: %x [validation successful]",
 		req_id, link->link_hdl);
@@ -1525,8 +1545,20 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
 {
 	int i, rc = 0;
 
+	if (link->state == CAM_CRM_LINK_STATE_IDLE) {
+		CAM_ERR(CAM_CRM, "link hdl %x is in idle state",
+				link->link_hdl);
+		return -EINVAL;
+	}
+
 	for (i = 0; i < link->num_sync_links; i++) {
 		if (link->sync_link[i]) {
+			if (link->sync_link[i]->state ==
+				CAM_CRM_LINK_STATE_IDLE) {
+				CAM_ERR(CAM_CRM, "sync link hdl %x is idle",
+					link->sync_link[i]->link_hdl);
+				return -EINVAL;
+			}
 			if (link->max_delay == link->sync_link[i]->max_delay) {
 				rc = __cam_req_mgr_check_sync_req_is_ready(
 						link, link->sync_link[i], slot);
@@ -1557,6 +1589,9 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
 					return rc;
 				}
 			}
+		} else {
+			CAM_ERR(CAM_REQ, "Sync link is null");
+			return -EINVAL;
 		}
 	}
 
@@ -1596,9 +1631,14 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
 	struct cam_req_mgr_core_link        *tmp_link = NULL;
 	uint32_t                             max_retry = 0;
 
-	in_q = link->req.in_q;
 	session = (struct cam_req_mgr_core_session *)link->parent;
+	if (!session) {
+		CAM_WARN(CAM_CRM, "session ptr NULL %x", link->link_hdl);
+		return -EINVAL;
+	}
+
 	mutex_lock(&session->lock);
+	in_q = link->req.in_q;
 	/*
 	 * Check if new read index,
 	 * - if in pending  state, traverse again to complete
@@ -1716,6 +1756,15 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
 					"Max retry attempts (count %d) reached on link[0x%x] for req [%lld]",
 					max_retry, link->link_hdl,
 					in_q->slot[in_q->rd_idx].req_id);
+
+				cam_req_mgr_debug_delay_detect();
+				trace_cam_delay_detect("CRM",
+					"Max retry attempts reached",
+					in_q->slot[in_q->rd_idx].req_id,
+					CAM_DEFAULT_VALUE,
+					link->link_hdl,
+					CAM_DEFAULT_VALUE, rc);
+
 				__cam_req_mgr_notify_error_on_link(link, dev);
 				link->retry_cnt = 0;
 			}
@@ -2006,6 +2055,10 @@ static int __cam_req_mgr_process_sof_freeze(void *priv, void *data)
 
 	link = (struct cam_req_mgr_core_link *)priv;
 	session = (struct cam_req_mgr_core_session *)link->parent;
+	if (!session) {
+		CAM_WARN(CAM_CRM, "session ptr NULL %x", link->link_hdl);
+		return -EINVAL;
+	}
 
 	spin_lock_bh(&link->link_state_spin_lock);
 	if ((link->watchdog) && (link->watchdog->pause_timer)) {
@@ -2268,6 +2321,7 @@ static void __cam_req_mgr_free_link(struct cam_req_mgr_core_link *link)
 	ptrdiff_t i;
 	kfree(link->req.in_q);
 	link->req.in_q = NULL;
+	link->parent = NULL;
 	i = link - g_links;
 	CAM_DBG(CAM_CRM, "free link index %d", i);
 	cam_req_mgr_core_link_reset(link);
@@ -2350,6 +2404,7 @@ int cam_req_mgr_process_flush_req(void *priv, void *data)
 		rc = -EINVAL;
 		goto end;
 	}
+
 	link = (struct cam_req_mgr_core_link *)priv;
 	task_data = (struct crm_task_payload *)data;
 	flush_info  = (struct cam_req_mgr_flush_info *)&task_data->u;
@@ -2575,8 +2630,7 @@ int cam_req_mgr_process_add_req(void *priv, void *data)
 			(add_req->skip_before_applying & 0xFF));
 	}
 
-	/* Used when Precise Flash is enabled */
-	if ((add_req->trigger_eof) && (!add_req->skip_before_applying)) {
+	if (add_req->trigger_eof) {
 		slot->ops.apply_at_eof = true;
 		slot->ops.dev_hdl = add_req->dev_hdl;
 		CAM_DBG(CAM_REQ,
@@ -2667,6 +2721,7 @@ int cam_req_mgr_process_error(void *priv, void *data)
 		rc = -EINVAL;
 		goto end;
 	}
+
 	link = (struct cam_req_mgr_core_link *)priv;
 	task_data = (struct crm_task_payload *)data;
 	err_info  = (struct cam_req_mgr_error_notify *)&task_data->u;
@@ -2760,6 +2815,7 @@ int cam_req_mgr_process_stop(void *priv, void *data)
 		rc = -EINVAL;
 		goto end;
 	}
+
 	link = (struct cam_req_mgr_core_link *)priv;
 	__cam_req_mgr_flush_req_slot(link);
 end:
@@ -2790,6 +2846,7 @@ static int cam_req_mgr_process_trigger(void *priv, void *data)
 		rc = -EINVAL;
 		goto end;
 	}
+
 	link = (struct cam_req_mgr_core_link *)priv;
 	task_data = (struct crm_task_payload *)data;
 	trigger_data = (struct cam_req_mgr_trigger_notify *)&task_data->u;
@@ -2825,7 +2882,8 @@ static int cam_req_mgr_process_trigger(void *priv, void *data)
 	spin_lock_bh(&link->link_state_spin_lock);
 
 	if (link->state < CAM_CRM_LINK_STATE_READY) {
-		CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
+		CAM_WARN(CAM_CRM, "invalid link state:%d for link 0x%x",
+			link->state, link->link_hdl);
 		spin_unlock_bh(&link->link_state_spin_lock);
 		rc = -EPERM;
 		goto release_lock;
@@ -3260,7 +3318,7 @@ static int cam_req_mgr_cb_notify_trigger(
 
 	task = cam_req_mgr_workq_get_task(link->workq);
 	if (!task) {
-		CAM_ERR(CAM_CRM, "no empty task frame %lld",
+		CAM_ERR_RATE_LIMIT(CAM_CRM, "no empty task frame %lld",
 			trigger_data->frame_id);
 		rc = -EBUSY;
 		goto end;
@@ -3520,7 +3578,8 @@ int cam_req_mgr_create_session(
 	ses_info->session_hdl = session_hdl;
 
 	mutex_init(&cam_session->lock);
-	CAM_DBG(CAM_CRM, "LOCK_DBG session lock %pK", &cam_session->lock);
+	CAM_DBG(CAM_CRM, "LOCK_DBG session lock %pK hdl 0x%x",
+		&cam_session->lock, session_hdl);
 
 	mutex_lock(&cam_session->lock);
 	cam_session->session_hdl = session_hdl;
@@ -3607,6 +3666,7 @@ int cam_req_mgr_destroy_session(
 		goto end;
 
 	}
+	mutex_lock(&cam_session->lock);
 	if (cam_session->num_links) {
 		CAM_DBG(CAM_CRM, "destroy session %x num_active_links %d",
 			ses_info->session_hdl,
@@ -3614,10 +3674,11 @@ int cam_req_mgr_destroy_session(
 
 		for (i = 0; i < MAXIMUM_LINKS_PER_SESSION; i++) {
 			link = cam_session->links[i];
-
 			if (!link)
 				continue;
 
+			CAM_DBG(CAM_CRM, "Unlink link hdl 0x%x",
+				link->link_hdl);
 			/* Ignore return value since session is going away */
 			link->is_shutdown = is_shutdown;
 			__cam_req_mgr_unlink(link);
@@ -3625,7 +3686,9 @@ int cam_req_mgr_destroy_session(
 		}
 	}
 	list_del(&cam_session->entry);
+	mutex_unlock(&cam_session->lock);
 	mutex_destroy(&cam_session->lock);
+
 	kfree(cam_session);
 
 	rc = cam_destroy_session_hdl(ses_info->session_hdl);
@@ -3685,7 +3748,7 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
 	memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
 	root_dev.session_hdl = link_info->u.link_info_v1.session_hdl;
 	root_dev.priv = (void *)link;
-
+	root_dev.dev_id = CAM_CRM;
 	mutex_lock(&link->lock);
 	/* Create unique dev handle for link */
 	link->link_hdl = cam_create_device_hdl(&root_dev);
@@ -3795,6 +3858,7 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
 	memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
 	root_dev.session_hdl = link_info->u.link_info_v2.session_hdl;
 	root_dev.priv = (void *)link;
+	root_dev.dev_id = CAM_CRM;
 
 	mutex_lock(&link->lock);
 	/* Create unique dev handle for link */

+ 10 - 1
drivers/cam_req_mgr/cam_req_mgr_debug.c

@@ -8,6 +8,7 @@
 #define MAX_SESS_INFO_LINE_BUFF_LEN 256
 
 static char sess_info_buffer[MAX_SESS_INFO_LINE_BUFF_LEN];
+static int cam_debug_mgr_delay_detect;
 
 static int cam_req_mgr_debug_set_bubble_recovery(void *data, u64 val)
 {
@@ -131,6 +132,8 @@ int cam_req_mgr_debug_register(struct cam_req_mgr_core_device *core_dev)
 		debugfs_root, core_dev, &bubble_recovery);
 	dbgfileptr = debugfs_create_bool("recovery_on_apply_fail", 0644,
 		debugfs_root, &core_dev->recovery_on_apply_fail);
+	dbgfileptr = debugfs_create_u32("delay_detect_count", 0644,
+		debugfs_root, &cam_debug_mgr_delay_detect);
 	if (IS_ERR(dbgfileptr)) {
 		if (PTR_ERR(dbgfileptr) == -ENODEV)
 			CAM_WARN(CAM_MEM, "DebugFS not enabled in kernel!");
@@ -141,7 +144,13 @@ end:
 	return rc;
 }
 
-void cam_req_mgr_debug_unregister(void)
+int cam_req_mgr_debug_unregister(void)
 {
 	debugfs_remove_recursive(debugfs_root);
+	return 0;
+}
+
+void cam_req_mgr_debug_delay_detect(void)
+{
+	cam_debug_mgr_delay_detect += 1;
 }

+ 5 - 1
drivers/cam_req_mgr/cam_req_mgr_debug.h

@@ -11,6 +11,10 @@
 #include "cam_debug_util.h"
 
 int cam_req_mgr_debug_register(struct cam_req_mgr_core_device *core_dev);
-void cam_req_mgr_debug_unregister(void);
+int cam_req_mgr_debug_unregister(void);
 
+/* cam_req_mgr_debug_delay_detect()
+ * @brief    : increment debug_fs varaible by 1 whenever delay occurred.
+ */
+void cam_req_mgr_debug_delay_detect(void);
 #endif

+ 2 - 1
drivers/cam_req_mgr/cam_req_mgr_dev.c

@@ -162,7 +162,8 @@ static int cam_req_mgr_close(struct file *filep)
 	struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
 
 	CAM_WARN(CAM_CRM,
-		"release invoked associated userspace process has died");
+		"release invoked associated userspace process has died, open_cnt: %d",
+		g_dev.open_cnt);
 	mutex_lock(&g_dev.cam_lock);
 
 	if (g_dev.open_cnt <= 0) {

+ 25 - 4
drivers/cam_req_mgr/cam_req_mgr_util.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #define pr_fmt(fmt) "CAM-REQ-MGR_UTIL %s:%d " fmt, __func__, __LINE__
@@ -113,14 +113,30 @@ static int32_t cam_get_free_handle_index(void)
 
 	idx = find_first_zero_bit(hdl_tbl->bitmap, hdl_tbl->bits);
 
-	if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2 || idx < 0)
+	if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2 || idx < 0) {
+		CAM_DBG(CAM_CRM, "idx: %d", idx);
 		return -ENOSR;
+	}
 
 	set_bit(idx, hdl_tbl->bitmap);
 
 	return idx;
 }
 
+void cam_dump_tbl_info(void)
+{
+	int i;
+
+	for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++)
+		CAM_INFO(CAM_CRM,
+			"i: %d session_hdl=0x%x hdl_value=0x%x type=%d state=%d dev_id=0x%llx",
+			i, hdl_tbl->hdl[i].session_hdl,
+			hdl_tbl->hdl[i].hdl_value,
+			hdl_tbl->hdl[i].type,
+			hdl_tbl->hdl[i].state,
+			hdl_tbl->hdl[i].dev_id);
+}
+
 int32_t cam_create_session_hdl(void *priv)
 {
 	int idx;
@@ -137,6 +153,7 @@ int32_t cam_create_session_hdl(void *priv)
 	idx = cam_get_free_handle_index();
 	if (idx < 0) {
 		CAM_ERR(CAM_CRM, "Unable to create session handle");
+		cam_dump_tbl_info();
 		spin_unlock_bh(&hdl_tbl_lock);
 		return idx;
 	}
@@ -149,6 +166,7 @@ int32_t cam_create_session_hdl(void *priv)
 	hdl_tbl->hdl[idx].state = HDL_ACTIVE;
 	hdl_tbl->hdl[idx].priv = priv;
 	hdl_tbl->hdl[idx].ops = NULL;
+	hdl_tbl->hdl[idx].dev_id = CAM_CRM;
 	spin_unlock_bh(&hdl_tbl_lock);
 
 	return handle;
@@ -169,7 +187,9 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
 
 	idx = cam_get_free_handle_index();
 	if (idx < 0) {
-		CAM_ERR(CAM_CRM, "Unable to create device handle");
+		CAM_ERR(CAM_CRM,
+			"Unable to create device handle(idx= %d)", idx);
+		cam_dump_tbl_info();
 		spin_unlock_bh(&hdl_tbl_lock);
 		return idx;
 	}
@@ -182,9 +202,10 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
 	hdl_tbl->hdl[idx].state = HDL_ACTIVE;
 	hdl_tbl->hdl[idx].priv = hdl_data->priv;
 	hdl_tbl->hdl[idx].ops = hdl_data->ops;
+	hdl_tbl->hdl[idx].dev_id = hdl_data->dev_id;
 	spin_unlock_bh(&hdl_tbl_lock);
 
-	pr_debug("%s: handle = %x", __func__, handle);
+	pr_debug("%s: handle = 0x%x idx = %d\n", __func__, handle, idx);
 	return handle;
 }
 

+ 5 - 1
drivers/cam_req_mgr/cam_req_mgr_util.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_REQ_MGR_UTIL_API_H_
@@ -35,6 +35,7 @@ enum hdl_type {
  * @hdl_value: Allocated handle
  * @type: session/device handle
  * @state: free/used
+ * @dev_id: device id for handle
  * @ops: ops structure
  * @priv: private data of a handle
  */
@@ -43,6 +44,7 @@ struct handle {
 	uint32_t hdl_value;
 	enum hdl_type type;
 	enum hdl_state state;
+	uint64_t dev_id;
 	void *ops;
 	void *priv;
 };
@@ -65,6 +67,7 @@ struct cam_req_mgr_util_hdl_tbl {
  * @v4l2_sub_dev_flag: flag to create v4l2 sub device
  * @media_entity_flag: flag for media entity
  * @reserved: reserved field
+ * @dev_id: device id for handle
  * @ops: ops pointer for a device handle
  * @priv: private data for a device handle
  */
@@ -73,6 +76,7 @@ struct cam_create_dev_hdl {
 	int32_t v4l2_sub_dev_flag;
 	int32_t media_entity_flag;
 	int32_t reserved;
+	uint64_t dev_id;
 	void *ops;
 	void *priv;
 };

+ 24 - 0
drivers/cam_req_mgr/cam_req_mgr_workq.c

@@ -102,6 +102,7 @@ void cam_req_mgr_process_workq(struct work_struct *w)
 	workq = (struct cam_req_mgr_core_workq *)
 		container_of(w, struct cam_req_mgr_core_workq, work);
 
+	cam_req_mgr_thread_switch_delay_detect(workq->workq_scheduled_ts);
 	while (i < CRM_TASK_PRIORITY_MAX) {
 		WORKQ_ACQUIRE_LOCK(workq, flags);
 		while (!list_empty(&workq->task.process_head[i])) {
@@ -164,6 +165,7 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
 	CAM_DBG(CAM_CRM, "enq task %pK pending_cnt %d",
 		task, atomic_read(&workq->task.pending_cnt));
 
+	workq->workq_scheduled_ts = ktime_get();
 	queue_work(workq->job, &workq->work);
 	WORKQ_RELEASE_LOCK(workq, flags);
 end:
@@ -265,3 +267,25 @@ void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **crm_workq)
 		*crm_workq = NULL;
 	}
 }
+
+void cam_req_mgr_thread_switch_delay_detect(ktime_t workq_scheduled)
+{
+	uint64_t                         diff;
+	ktime_t                          cur_time;
+	struct timespec64                cur_ts;
+	struct timespec64                workq_scheduled_ts;
+
+	cur_time = ktime_get();
+	diff = ktime_ms_delta(cur_time, workq_scheduled);
+	workq_scheduled_ts  = ktime_to_timespec64(workq_scheduled);
+	cur_ts = ktime_to_timespec64(cur_time);
+
+	if (diff > CAM_WORKQ_RESPONSE_TIME_THRESHOLD) {
+		CAM_WARN(CAM_CRM,
+			"Workq delay detected %ld:%06ld %ld:%06ld %ld:",
+			workq_scheduled_ts.tv_sec,
+			workq_scheduled_ts.tv_nsec/NSEC_PER_USEC,
+			cur_ts.tv_sec, cur_ts.tv_nsec/NSEC_PER_USEC,
+			diff);
+	}
+}

+ 24 - 8
drivers/cam_req_mgr/cam_req_mgr_workq.h

@@ -26,6 +26,13 @@
  */
 #define CAM_WORKQ_FLAG_SERIAL                    (1 << 1)
 
+/*
+ * Response time threshold in ms beyond which it is considered
+ * as workq scheduling/processing delay.
+ */
+#define CAM_WORKQ_RESPONSE_TIME_THRESHOLD   5
+
+
 /* Task priorities, lower the number higher the priority*/
 enum crm_task_priority {
 	CRM_TASK_PRIORITY_0,
@@ -54,14 +61,14 @@ enum crm_workq_context {
  * @ret        : return value in future to use for blocking calls
  */
 struct crm_workq_task {
-	int32_t                  priority;
-	void                    *payload;
-	int32_t                (*process_cb)(void *priv, void *data);
-	void                    *parent;
-	struct list_head         entry;
-	uint8_t                  cancel;
-	void                    *priv;
-	int32_t                  ret;
+	int32_t                    priority;
+	void                      *payload;
+	int32_t                  (*process_cb)(void *priv, void *data);
+	void                      *parent;
+	struct list_head           entry;
+	uint8_t                    cancel;
+	void                      *priv;
+	int32_t                    ret;
 };
 
 /** struct cam_req_mgr_core_workq
@@ -84,6 +91,7 @@ struct cam_req_mgr_core_workq {
 	struct workqueue_struct   *job;
 	spinlock_t                 lock_bh;
 	uint32_t                   in_irq;
+	ktime_t                    workq_scheduled_ts;
 
 	/* tasks */
 	struct {
@@ -142,6 +150,14 @@ void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **workq);
 int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
 	void *priv, int32_t prio);
 
+/**
+ * cam_req_mgr_thread_switch_delay_detect()
+ * @brief: Detects if workq delay has occurred or not
+ * @timestamp: workq scheduled timestamp
+ */
+void cam_req_mgr_thread_switch_delay_detect(
+	ktime_t timestamp);
+
 /**
  * cam_req_mgr_workq_get_task()
  * @brief: Returns empty task pointer for use

+ 9 - 1
drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c

@@ -106,8 +106,15 @@ static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
 	}
 
 	rc = camera_io_init(&a_ctrl->io_master_info);
-	if (rc < 0)
+	if (rc < 0) {
 		CAM_ERR(CAM_ACTUATOR, "cci init failed: rc: %d", rc);
+		goto cci_failure;
+	}
+
+	return rc;
+cci_failure:
+	if (cam_sensor_util_power_down(power_info, soc_info))
+		CAM_ERR(CAM_ACTUATOR, "Power down failure");
 
 	return rc;
 }
@@ -848,6 +855,7 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
 		bridge_params.v4l2_sub_dev_flag = 0;
 		bridge_params.media_entity_flag = 0;
 		bridge_params.priv = a_ctrl;
+		bridge_params.dev_id = CAM_ACTUATOR;
 
 		actuator_acq_dev.device_handle =
 			cam_create_device_hdl(&bridge_params);

+ 6 - 0
drivers/cam_sensor_module/cam_cci/cam_cci_core.c

@@ -6,6 +6,7 @@
 #include <linux/module.h>
 #include "cam_cci_core.h"
 #include "cam_cci_dev.h"
+#include "cam_req_mgr_workq.h"
 
 static int32_t cam_cci_convert_type_to_num_bytes(
 	enum camera_sensor_i2c_type type)
@@ -1533,6 +1534,8 @@ static void cam_cci_write_async_helper(struct work_struct *work)
 	enum cci_i2c_master_t master;
 	struct cam_cci_master_info *cci_master_info;
 
+	cam_req_mgr_thread_switch_delay_detect(
+		write_async->workq_scheduled_ts);
 	cci_dev = write_async->cci_dev;
 	i2c_msg = &write_async->c_ctrl.cfg.cci_i2c_write_cfg;
 	master = write_async->c_ctrl.cci_info->cci_i2c_master;
@@ -1601,6 +1604,7 @@ static int32_t cam_cci_i2c_write_async(struct v4l2_subdev *sd,
 	cci_i2c_write_cfg_w->size = cci_i2c_write_cfg->size;
 	cci_i2c_write_cfg_w->delay = cci_i2c_write_cfg->delay;
 
+	write_async->workq_scheduled_ts = ktime_get();
 	queue_work(cci_dev->write_wq[write_async->queue], &write_async->work);
 
 	return rc;
@@ -1725,8 +1729,10 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd,
 	 * THRESHOLD irq's, we reinit the threshold wait before
 	 * we load the burst read cmd.
 	 */
+	mutex_lock(&cci_dev->cci_master_info[master].mutex_q[QUEUE_1]);
 	reinit_completion(&cci_dev->cci_master_info[master].rd_done);
 	reinit_completion(&cci_dev->cci_master_info[master].th_complete);
+	mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[QUEUE_1]);
 
 	CAM_DBG(CAM_CCI, "Bytes to read %u", read_bytes);
 	do {

+ 2 - 0
drivers/cam_sensor_module/cam_cci/cam_cci_dev.h

@@ -31,6 +31,7 @@
 #include "cam_cci_hwreg.h"
 #include "cam_soc_util.h"
 #include "cam_debug_util.h"
+#include "cam_req_mgr_workq.h"
 
 #define CCI_I2C_QUEUE_0_SIZE 128
 #define CCI_I2C_QUEUE_1_SIZE 32
@@ -292,6 +293,7 @@ struct cci_write_async {
 	struct cam_cci_ctrl c_ctrl;
 	enum cci_i2c_queue_t queue;
 	struct work_struct work;
+	ktime_t workq_scheduled_ts;
 	enum cci_i2c_sync sync_en;
 };
 

+ 2 - 1
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c

@@ -1110,6 +1110,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 		bridge_params.v4l2_sub_dev_flag = 0;
 		bridge_params.media_entity_flag = 0;
 		bridge_params.priv = csiphy_dev;
+		bridge_params.dev_id = CAM_CSIPHY;
 		index = csiphy_dev->acquire_count;
 		csiphy_acq_dev.device_handle =
 			cam_create_device_hdl(&bridge_params);
@@ -1338,7 +1339,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 				csiphy_dev->ctrl_reg->getclockvoting(
 					csiphy_dev, offset);
 			rc = cam_soc_util_set_clk_rate_level(
-				&csiphy_dev->soc_info, clk_vote_level);
+				&csiphy_dev->soc_info, clk_vote_level, false);
 			if (rc) {
 				CAM_WARN(CAM_CSIPHY,
 					"Failed to set the clk_rate level: %d",

+ 7 - 1
drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c

@@ -185,10 +185,15 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
 		rc = camera_io_init(&(e_ctrl->io_master_info));
 		if (rc) {
 			CAM_ERR(CAM_EEPROM, "cci_init failed");
-			return -EINVAL;
+			goto cci_failure;
 		}
 	}
 	return rc;
+cci_failure:
+	if (cam_sensor_util_power_down(power_info, soc_info))
+		CAM_ERR(CAM_EEPROM, "Power down failure");
+
+	return rc;
 }
 
 /**
@@ -351,6 +356,7 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl,
 	bridge_params.v4l2_sub_dev_flag = 0;
 	bridge_params.media_entity_flag = 0;
 	bridge_params.priv = e_ctrl;
+	bridge_params.dev_id = CAM_EEPROM;
 
 	eeprom_acq_dev.device_handle =
 		cam_create_device_hdl(&bridge_params);

+ 3 - 6
drivers/cam_sensor_module/cam_flash/cam_flash_core.c

@@ -1546,12 +1546,9 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
 
 			CAM_DBG(CAM_FLASH,
 				"FLASH_CMD_TYPE op:%d", flash_data->opcode);
-			if (flash_data->opcode == CAMERA_SENSOR_FLASH_OP_OFF)
-				add_req.skip_before_applying |= SKIP_NEXT_FRAME;
 
 			if (flash_data->opcode ==
 				CAMERA_SENSOR_FLASH_OP_FIREDURATION) {
-				add_req.trigger_eof = true;
 				/* Active time for the preflash */
 				flash_data->flash_active_time_ms =
 				(flash_operation_info->time_on_duration_ns)
@@ -1748,12 +1745,12 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
 
 		if ((csl_packet->header.op_code & 0xFFFFF) ==
 			CAM_FLASH_PACKET_OPCODE_SET_OPS) {
+			add_req.skip_before_applying |= SKIP_NEXT_FRAME;
+			add_req.trigger_eof = true;
+
 			if ((flash_data->opcode !=
 				CAMERA_SENSOR_FLASH_OP_FIREDURATION))
 				add_req.skip_before_applying |= 1;
-			else if (flash_data->opcode ==
-				CAMERA_SENSOR_FLASH_OP_FIREDURATION)
-				add_req.trigger_eof = true;
 			else
 				add_req.skip_before_applying = 0;
 		} else {

+ 1 - 0
drivers/cam_sensor_module/cam_flash/cam_flash_dev.c

@@ -64,6 +64,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
 		bridge_params.v4l2_sub_dev_flag = 0;
 		bridge_params.media_entity_flag = 0;
 		bridge_params.priv = fctrl;
+		bridge_params.dev_id = CAM_FLASH;
 
 		flash_acq_dev.device_handle =
 			cam_create_device_hdl(&bridge_params);

+ 9 - 1
drivers/cam_sensor_module/cam_ois/cam_ois_core.c

@@ -82,6 +82,7 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl,
 	bridge_params.v4l2_sub_dev_flag = 0;
 	bridge_params.media_entity_flag = 0;
 	bridge_params.priv = o_ctrl;
+	bridge_params.dev_id = CAM_OIS;
 
 	ois_acq_dev.device_handle =
 		cam_create_device_hdl(&bridge_params);
@@ -152,8 +153,15 @@ static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl)
 	}
 
 	rc = camera_io_init(&o_ctrl->io_master_info);
-	if (rc)
+	if (rc) {
 		CAM_ERR(CAM_OIS, "cci_init failed: rc: %d", rc);
+		goto cci_failure;
+	}
+
+	return rc;
+cci_failure:
+	if (cam_sensor_util_power_down(power_info, soc_info))
+		CAM_ERR(CAM_OIS, "Power Down failed");
 
 	return rc;
 }

+ 6 - 6
drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c

@@ -462,8 +462,8 @@ int cam_res_mgr_gpio_request(struct device *dev, uint gpio,
 		CAM_DBG(CAM_RES, "gpio: %u not found in gpio_res list", gpio);
 		rc = gpio_request_one(gpio, flags, label);
 		if (rc) {
-			CAM_ERR(CAM_RES, "gpio %d:%s request fails",
-				gpio, label);
+			CAM_ERR(CAM_RES, "gpio %d:%s request fails rc = %d",
+				gpio, label, rc);
 			goto end;
 		}
 	}
@@ -760,7 +760,7 @@ static int cam_res_mgr_parse_dt_shared_gpio(
 
 	of_node = dev->of_node;
 	dt->num_shared_gpio = of_property_count_u32_elems(of_node,
-		"shared-gpios");
+		"gpios-shared");
 
 	if (dt->num_shared_gpio <= 0) {
 		CAM_DBG(CAM_RES,
@@ -776,7 +776,7 @@ static int cam_res_mgr_parse_dt_shared_gpio(
 		return -EINVAL;
 	}
 
-	rc = of_property_read_u32_array(of_node, "shared-gpios",
+	rc = of_property_read_u32_array(of_node, "gpios-shared",
 		dt->shared_gpio, dt->num_shared_gpio);
 	if (rc) {
 		CAM_ERR(CAM_RES, "Get shared gpio array failed.");
@@ -796,7 +796,7 @@ static int cam_res_mgr_parse_dt_shared_pinctrl_gpio(
 
 	of_node = dev->of_node;
 	dt->num_shared_pctrl_gpio = of_property_count_u32_elems(of_node,
-		"shared-pinctrl-gpios");
+		"gpios-shared-pinctrl");
 
 	if (dt->num_shared_pctrl_gpio <= 0) {
 		CAM_DBG(CAM_RES,
@@ -825,7 +825,7 @@ static int cam_res_mgr_parse_dt_shared_pinctrl_gpio(
 	CAM_INFO(CAM_RES,
 		"number of pctrl_gpio: %d", dt->num_shared_pctrl_gpio);
 
-	rc = of_property_read_u32_array(of_node, "shared-pinctrl-gpios",
+	rc = of_property_read_u32_array(of_node, "gpios-shared-pinctrl",
 		dt->shared_pctrl_gpio, dt->num_shared_pctrl_gpio);
 	if (rc) {
 		CAM_ERR(CAM_RES, "Get shared pinctrl gpio array failed.");

+ 10 - 1
drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c

@@ -835,6 +835,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 		bridge_params.v4l2_sub_dev_flag = 0;
 		bridge_params.media_entity_flag = 0;
 		bridge_params.priv = s_ctrl;
+		bridge_params.dev_id = CAM_SENSOR;
 
 		sensor_acq_dev.device_handle =
 			cam_create_device_hdl(&bridge_params);
@@ -1196,10 +1197,18 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
 	}
 
 	rc = camera_io_init(&(s_ctrl->io_master_info));
-	if (rc < 0)
+	if (rc < 0) {
 		CAM_ERR(CAM_SENSOR, "cci_init failed: rc: %d", rc);
+		goto cci_failure;
+	}
 
 	return rc;
+cci_failure:
+	if (cam_sensor_util_power_down(power_info, soc_info))
+		CAM_ERR(CAM_SENSOR, "power down failure");
+
+	return rc;
+
 }
 
 int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl)

+ 7 - 7
drivers/cam_smmu/cam_smmu_api.c

@@ -218,7 +218,7 @@ static struct cam_iommu_cb_set iommu_cb_set;
 static enum dma_data_direction cam_smmu_translate_dir(
 	enum cam_smmu_map_dir dir);
 
-static int cam_smmu_check_handle_unique(int hdl);
+static bool cam_smmu_is_hdl_nonunique_or_null(int hdl);
 
 static int cam_smmu_create_iommu_handle(int idx);
 
@@ -810,13 +810,12 @@ void cam_smmu_reset_iommu_table(enum cam_smmu_init_dir ops)
 	}
 }
 
-static int cam_smmu_check_handle_unique(int hdl)
+static bool cam_smmu_is_hdl_nonunique_or_null(int hdl)
 {
 	int i;
 
-	if (hdl == HANDLE_INIT) {
-		CAM_DBG(CAM_SMMU,
-			"iommu handle is init number. Need to try again");
+	if ((hdl == HANDLE_INIT) || (!hdl)) {
+		CAM_DBG(CAM_SMMU, "iommu handle: %d is not valid", hdl);
 		return 1;
 	}
 
@@ -876,11 +875,12 @@ static int cam_smmu_create_add_handle_in_table(char *name,
 
 			if (iommu_cb_set.cb_info[i].handle == HANDLE_INIT) {
 				mutex_lock(&iommu_cb_set.cb_info[i].lock);
-				/* make sure handle is unique */
+				/* make sure handle is unique and non-zero*/
 				do {
 					handle =
 						cam_smmu_create_iommu_handle(i);
-				} while (cam_smmu_check_handle_unique(handle));
+				} while (cam_smmu_is_hdl_nonunique_or_null(
+						handle));
 
 				/* put handle in the table */
 				iommu_cb_set.cb_info[i].handle = handle;

+ 2 - 0
drivers/cam_sync/cam_sync.c

@@ -17,6 +17,7 @@
 #include "cam_debug_util.h"
 #include "cam_common_util.h"
 #include "camera_main.h"
+#include "cam_req_mgr_workq.h"
 
 struct sync_device *sync_dev;
 
@@ -130,6 +131,7 @@ int cam_sync_register_callback(sync_callback cb_func,
 			sync_cb->status = row->state;
 			CAM_DBG(CAM_SYNC, "Enqueue callback for sync object:%d",
 				sync_cb->sync_obj);
+			sync_cb->workq_scheduled_ts = ktime_get();
 			queue_work(sync_dev->work_queue,
 				&sync_cb->cb_dispatch_work);
 			spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);

+ 9 - 7
drivers/cam_sync/cam_sync_private.h

@@ -30,7 +30,7 @@
 
 #define CAM_SYNC_OBJ_NAME_LEN           64
 #define CAM_SYNC_MAX_OBJS               2048
-#define CAM_SYNC_MAX_V4L2_EVENTS        100
+#define CAM_SYNC_MAX_V4L2_EVENTS        250
 #define CAM_SYNC_DEBUG_FILENAME         "cam_debug"
 #define CAM_SYNC_DEBUG_BASEDIR          "cam"
 #define CAM_SYNC_DEBUG_BUF_SIZE         32
@@ -94,18 +94,20 @@ struct sync_child_info {
  * struct sync_callback_info - Single node of information about a kernel
  * callback registered on a sync object
  *
- * @callback_func    : Callback function, registered by client driver
- * @cb_data          : Callback data, registered by client driver
- * @status........   : Status with which callback will be invoked in client
- * @sync_obj         : Sync id of the object for which callback is registered
- * @cb_dispatch_work : Work representing the call dispatch
- * @list             : List member used to append this node to a linked list
+ * @callback_func      : Callback function, registered by client driver
+ * @cb_data            : Callback data, registered by client driver
+ * @status             : Status with which callback will be invoked in client
+ * @sync_obj           : Sync id of the object for which callback is registered
+ * @workq_scheduled_ts : workqueue scheduled timestamp
+ * @cb_dispatch_work   : Work representing the call dispatch
+ * @list               : List member used to append this node to a linked list
  */
 struct sync_callback_info {
 	sync_callback callback_func;
 	void *cb_data;
 	int status;
 	int32_t sync_obj;
+	ktime_t workq_scheduled_ts;
 	struct work_struct cb_dispatch_work;
 	struct list_head list;
 };

+ 3 - 0
drivers/cam_sync/cam_sync_util.c

@@ -4,6 +4,7 @@
  */
 
 #include "cam_sync_util.h"
+#include "cam_req_mgr_workq.h"
 
 int cam_sync_util_find_and_set_empty_row(struct sync_device *sync_dev,
 	long *idx)
@@ -293,6 +294,8 @@ void cam_sync_util_cb_dispatch(struct work_struct *cb_dispatch_work)
 		cb_dispatch_work);
 	sync_callback sync_data = cb_info->callback_func;
 
+	cam_req_mgr_thread_switch_delay_detect(
+			cb_info->workq_scheduled_ts);
 	sync_data(cb_info->sync_obj, cb_info->status, cb_info->cb_data);
 
 	kfree(cb_info);

+ 3 - 0
drivers/cam_utils/cam_packet_util.c

@@ -179,6 +179,9 @@ void cam_packet_dump_patch_info(struct cam_packet *packet,
 			((uint32_t *) &packet->payload +
 			packet->patch_offset/4);
 
+	CAM_INFO(CAM_UTIL, "Total num of patches : %d",
+		packet->num_patches);
+
 	for (i = 0; i < packet->num_patches; i++) {
 		hdl = cam_mem_is_secure_buf(patch_desc[i].src_buf_hdl) ?
 			sec_mmu_hdl : iommu_hdl;

+ 11 - 1
drivers/cam_utils/cam_soc_util.c

@@ -907,7 +907,7 @@ end:
 }
 
 int cam_soc_util_set_clk_rate_level(struct cam_hw_soc_info *soc_info,
-	enum cam_vote_level clk_level)
+	enum cam_vote_level clk_level, bool do_not_set_src_clk)
 {
 	int i, rc = 0;
 	enum cam_vote_level apply_level;
@@ -928,6 +928,16 @@ int cam_soc_util_set_clk_rate_level(struct cam_hw_soc_info *soc_info,
 		cam_cx_ipeak_update_vote_cx_ipeak(soc_info, apply_level);
 
 	for (i = 0; i < soc_info->num_clk; i++) {
+		if (do_not_set_src_clk && (i == soc_info->src_clk_idx)) {
+			CAM_DBG(CAM_UTIL, "Skipping set rate for src clk %s",
+				soc_info->clk_name[i]);
+			continue;
+		}
+
+		CAM_DBG(CAM_UTIL, "Set rate for clk %s rate %d",
+			soc_info->clk_name[i],
+			soc_info->clk_rate[apply_level][i]);
+
 		rc = cam_soc_util_set_clk_rate(soc_info->clk[i],
 			soc_info->clk_name[i],
 			soc_info->clk_rate[apply_level][i]);

+ 2 - 1
drivers/cam_utils/cam_soc_util.h

@@ -470,11 +470,12 @@ int cam_soc_util_clk_enable(struct clk *clk, const char *clk_name,
  *
  * @soc_info:           Device soc information
  * @clk_level:          Clock level number to set
+ * @do_not_set_src_clk: If true, set clock rates except the src clk
  *
  * @return:             Success or failure
  */
 int cam_soc_util_set_clk_rate_level(struct cam_hw_soc_info *soc_info,
-	enum cam_vote_level clk_level);
+	enum cam_vote_level clk_level, bool do_not_set_src_clk);
 
 /**
  * cam_soc_util_clk_disable()

+ 35 - 0
drivers/cam_utils/cam_trace.h

@@ -19,6 +19,8 @@
 #include "cam_req_mgr_interface.h"
 #include "cam_context.h"
 
+#define CAM_DEFAULT_VALUE 0xFF
+
 TRACE_EVENT(cam_context_state,
 	TP_PROTO(const char *name, struct cam_context *ctx),
 	TP_ARGS(name, ctx),
@@ -282,6 +284,39 @@ TRACE_EVENT(cam_req_mgr_add_req,
 	)
 );
 
+TRACE_EVENT(cam_delay_detect,
+	TP_PROTO(const char *entity,
+		const char *text, uint64_t req_id,
+		uint32_t ctx_id, int32_t link_hdl,
+		int32_t session_hdl, int rc),
+	TP_ARGS(entity, text, req_id, ctx_id,
+		link_hdl, session_hdl, rc),
+	TP_STRUCT__entry(
+		__string(entity, entity)
+		__string(text, text)
+		__field(uint64_t, req_id)
+		__field(uint64_t, ctx_id)
+		__field(int32_t, link_hdl)
+		__field(int32_t, session_hdl)
+		__field(int32_t, rc)
+	),
+	TP_fast_assign(
+		__assign_str(entity, entity);
+		__assign_str(text, text);
+		__entry->req_id      = req_id;
+		__entry->ctx_id      = ctx_id;
+		__entry->link_hdl    = link_hdl;
+		__entry->session_hdl = session_hdl;
+		__entry->rc          = rc;
+	),
+	TP_printk(
+		"%s: %s request=%lld ctx_id=%d link_hdl=0x%x session_hdl=0x%x rc=%d",
+			__get_str(entity), __get_str(text), __entry->req_id,
+			__entry->ctx_id, __entry->link_hdl,
+			__entry->session_hdl, __entry->rc
+	)
+);
+
 TRACE_EVENT(cam_submit_to_hw,
 	TP_PROTO(const char *entity, uint64_t req_id),
 	TP_ARGS(entity, req_id),

+ 8 - 3
include/uapi/camera/media/cam_isp_ife.h

@@ -34,9 +34,14 @@
 #define CAM_ISP_IFE_OUT_RES_2PD                (CAM_ISP_IFE_OUT_RES_BASE + 22)
 #define CAM_ISP_IFE_OUT_RES_RDI_RD             (CAM_ISP_IFE_OUT_RES_BASE + 23)
 #define CAM_ISP_IFE_OUT_RES_LCR                (CAM_ISP_IFE_OUT_RES_BASE + 24)
-
-#define CAM_ISP_IFE_OUT_RES_MAX                (CAM_ISP_IFE_OUT_RES_BASE + 25)
-
+#define CAM_ISP_IFE_OUT_RES_SPARSE_PD          (CAM_ISP_IFE_OUT_RES_BASE + 25)
+#define CAM_ISP_IFE_OUT_RES_2PD_STATS          (CAM_ISP_IFE_OUT_RES_BASE + 26)
+#define CAM_ISP_IFE_OUT_RES_AWB_BFW            (CAM_ISP_IFE_OUT_RES_BASE + 27)
+#define CAM_ISP_IFE_OUT_RES_STATS_AEC_BE       (CAM_ISP_IFE_OUT_RES_BASE + 28)
+#define CAM_ISP_IFE_OUT_RES_LTM_STATS          (CAM_ISP_IFE_OUT_RES_BASE + 29)
+#define CAM_ISP_IFE_OUT_RES_STATS_GTM_BHIST    (CAM_ISP_IFE_OUT_RES_BASE + 30)
+#define CAM_ISP_IFE_LITE_OUT_RES_STATS_BE      (CAM_ISP_IFE_OUT_RES_BASE + 31)
+#define CAM_ISP_IFE_LITE_OUT_RES_GAMMA         (CAM_ISP_IFE_OUT_RES_BASE + 32)
 
 /* IFE input port resource type (global unique) */
 #define CAM_ISP_IFE_IN_RES_BASE                 0x4000

+ 1 - 0
include/uapi/camera/media/cam_req_mgr.h

@@ -426,6 +426,7 @@ struct cam_mem_cache_ops_cmd {
  * @CAM_REQ_MGR_ERROR_TYPE_BUFFER: Buffer was not filled, not fatal
  * @CAM_REQ_MGR_ERROR_TYPE_RECOVERY: Fatal error, can be recovered
  * @CAM_REQ_MGR_ERROR_TYPE_SOF_FREEZE: SOF freeze, can be recovered
+ * @CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY: Full recovery, can be recovered
  * @CAM_REQ_MGR_ERROR_TYPE_PAGE_FAULT: page fault, can be recovered
  */
 #define CAM_REQ_MGR_ERROR_TYPE_DEVICE           0

Some files were not shown because too many files changed in this diff